Exemple #1
0
class SimulatorAdapterTest(TransactionalTestCase):
    """
    Basic testing that Simulator is still working from UI.
    """
    CONNECTIVITY_NODES = 74

    def setUp(self):
        """
        Reset the database before each test.
        """
        initialize_storage()
        self.datatypes_factory = DatatypesFactory()
        self.test_user = self.datatypes_factory.get_user()
        self.test_project = self.datatypes_factory.get_project()
        self.connectivity = self.datatypes_factory.create_connectivity(
            self.CONNECTIVITY_NODES)[1]

        algo_group = dao.find_group(SIMULATOR_MODULE, SIMULATOR_CLASS)
        algorithm = dao.get_algorithm_by_group(algo_group.id)
        self.simulator_adapter = FlowService().build_adapter_instance(
            algo_group)
        self.operation = TestFactory.create_operation(
            algorithm, self.test_user, self.test_project, model.STATUS_STARTED,
            json.dumps(SIMULATOR_PARAMETERS))

        SIMULATOR_PARAMETERS['connectivity'] = self.connectivity.gid

    def test_happy_flow_launch(self):
        """
        Test that launching a simulation from UI works.
        """
        OperationService().initiate_prelaunch(self.operation,
                                              self.simulator_adapter, {},
                                              **SIMULATOR_PARAMETERS)
        sim_result = dao.get_generic_entity(TimeSeriesRegion,
                                            'TimeSeriesRegion', 'type')[0]
        self.assertEquals(sim_result.read_data_shape(),
                          (32, 1, self.CONNECTIVITY_NODES, 1))

    def _estimate_hdd(self, new_parameters_dict):
        """ Private method, to return HDD estimation for a given set of input parameters"""
        filtered_params = self.simulator_adapter.prepare_ui_inputs(
            new_parameters_dict)
        self.simulator_adapter.configure(**filtered_params)
        return self.simulator_adapter.get_required_disk_size(**filtered_params)

    def test_estimate_hdd(self):
        """
        Test that occupied HDD estimation for simulation results considers simulation length.
        """
        factor = 5
        simulation_parameters = copy(SIMULATOR_PARAMETERS)
        ## Estimate HDD with default simulation parameters
        estimate1 = self._estimate_hdd(simulation_parameters)
        self.assertTrue(estimate1 > 1)

        ## Change simulation length and monitor period, we expect a direct proportial increase in estimated HDD
        simulation_parameters['simulation_length'] = float(
            simulation_parameters['simulation_length']) * factor
        period = float(simulation_parameters[
            'monitors_parameters_option_TemporalAverage_period'])
        simulation_parameters[
            'monitors_parameters_option_TemporalAverage_period'] = period / factor
        estimate2 = self._estimate_hdd(simulation_parameters)
        self.assertEqual(estimate1, estimate2 / factor / factor)

        ## Change number of nodes in connectivity. Expect HDD estimation increase.
        large_conn_gid = self.datatypes_factory.create_connectivity(
            self.CONNECTIVITY_NODES * factor)[1].gid
        simulation_parameters['connectivity'] = large_conn_gid
        estimate3 = self._estimate_hdd(simulation_parameters)
        self.assertEqual(estimate2, estimate3 / factor)

    def test_estimate_execution_time(self):
        """
        Test that get_execution_time_approximation considers the correct params
        """
        ## Compute reference estimation
        params = self.simulator_adapter.prepare_ui_inputs(SIMULATOR_PARAMETERS)
        estimation1 = self.simulator_adapter.get_execution_time_approximation(
            **params)

        ## Estimation when the surface input parameter is set
        params['surface'] = "GID_surface"
        estimation2 = self.simulator_adapter.get_execution_time_approximation(
            **params)

        self.assertEqual(estimation1, estimation2 / 500)
        params['surface'] = ""

        ## Modify integration step and simulation length:
        initial_simulation_length = float(params['simulation_length'])
        initial_integration_step = float(params['integrator_parameters']['dt'])

        for factor in (2, 4, 10):
            params['simulation_length'] = initial_simulation_length * factor
            params['integrator_parameters'][
                'dt'] = initial_integration_step / factor

            estimation3 = self.simulator_adapter.get_execution_time_approximation(
                **params)

            self.assertEqual(estimation1, estimation3 / factor / factor)

        ## Check that no division by zero happens
        params['integrator_parameters']['dt'] = 0
        estimation4 = self.simulator_adapter.get_execution_time_approximation(
            **params)
        self.assertTrue(estimation4 > 0)

        ## even with length zero, still a positive estimation should be returned
        params['simulation_length'] = 0
        estimation5 = self.simulator_adapter.get_execution_time_approximation(
            **params)
        self.assertTrue(estimation5 > 0)

    def test_noise_2d_bad_shape(self):
        """
        Test a simulation with noise. Pass a wrong shape and expect exception to be raised.
        """
        params = copy(SIMULATOR_PARAMETERS)
        params['integrator'] = u'HeunStochastic'
        noise_4d_config = [[1 for _ in xrange(self.CONNECTIVITY_NODES)]
                           for _ in xrange(4)]
        params[
            'integrator_parameters_option_HeunStochastic_dt'] = u'0.01220703125'
        params[
            'integrator_parameters_option_HeunStochastic_noise'] = u'Additive'
        params[
            'integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_nsig'] = str(
                noise_4d_config)
        params[
            'integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_ntau'] = u'0.0'
        params[
            'integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_random_stream'] = u'RandomStream'
        params[
            'integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_random_stream_parameters_option_RandomStream_init_seed'] = u'42'
        filtered_params = self.simulator_adapter.prepare_ui_inputs(params)
        self.simulator_adapter.configure(**filtered_params)
        if hasattr(self.simulator_adapter, 'algorithm'):
            self.assertEqual(
                (4, 74),
                self.simulator_adapter.algorithm.integrator.noise.nsig.shape)
        else:
            self.fail("Simulator adapter was not initialized properly")
        self.assertRaises(Exception,
                          OperationService().initiate_prelaunch,
                          self.operation, self.simulator_adapter, {}, **params)

    def test_noise_2d_happy_flow(self):
        """
        Test a simulation with noise.
        """
        params = copy(SIMULATOR_PARAMETERS)
        params['integrator'] = u'HeunStochastic'
        noise_2d_config = [[1 for _ in xrange(self.CONNECTIVITY_NODES)]
                           for _ in xrange(2)]
        params[
            'integrator_parameters_option_HeunStochastic_dt'] = u'0.01220703125'
        params[
            'integrator_parameters_option_HeunStochastic_noise'] = u'Additive'
        params[
            'integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_nsig'] = str(
                noise_2d_config)
        params[
            'integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_ntau'] = u'0.0'
        params[
            'integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_random_stream'] = u'RandomStream'
        params[
            'integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_random_stream_parameters_option_RandomStream_init_seed'] = u'42'

        self._launch_and_check_noise(params, (2, 74))

        sim_result = dao.get_generic_entity(TimeSeriesRegion,
                                            'TimeSeriesRegion', 'type')[0]
        self.assertEquals(sim_result.read_data_shape(),
                          (32, 1, self.CONNECTIVITY_NODES, 1))

        params[
            'integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_nsig'] = '[1]'
        self._launch_and_check_noise(params, (1, ))

    def _launch_and_check_noise(self, params, expected_noise_shape):

        filtered_params = self.simulator_adapter.prepare_ui_inputs(params)
        self.simulator_adapter.configure(**filtered_params)

        if hasattr(self.simulator_adapter, 'algorithm'):
            self.assertEqual(
                expected_noise_shape,
                self.simulator_adapter.algorithm.integrator.noise.nsig.shape)
        else:
            self.fail("Simulator adapter was not initialized properly")

        OperationService().initiate_prelaunch(self.operation,
                                              self.simulator_adapter, {},
                                              **params)

    def test_simulation_with_stimulus(self):
        """
        Test a simulation with noise.
        """
        params = copy(SIMULATOR_PARAMETERS)
        params["stimulus"] = self.datatypes_factory.create_stimulus(
            self.connectivity).gid

        filtered_params = self.simulator_adapter.prepare_ui_inputs(params)
        self.simulator_adapter.configure(**filtered_params)
        OperationService().initiate_prelaunch(self.operation,
                                              self.simulator_adapter, {},
                                              **params)
class SimulatorAdapterTest(TransactionalTestCase):
    """
    Basic testing that Simulator is still working from UI.
    """
    CONNECTIVITY_NODES = 74

    def setUp(self):
        """
        Reset the database before each test.
        """
        initialize_storage()
        user = model.User("test_user", "test_pass", "*****@*****.**", True,
                          "user")
        self.test_user = dao.store_entity(user)
        data = dict(name='test_proj', description='desc', users=[])
        self.test_project = ProjectService().store_project(
            self.test_user, True, None, **data)
        meta = {
            DataTypeMetaData.KEY_SUBJECT: "John Doe",
            DataTypeMetaData.KEY_STATE: "INTERMEDIATE"
        }
        algo_group = dao.find_group(SIMULATOR_MODULE, SIMULATOR_CLASS)
        self.simulator_adapter = FlowService().build_adapter_instance(
            algo_group)

        self.operation = model.Operation(self.test_user.id,
                                         self.test_project.id,
                                         algo_group.id,
                                         json.dumps(SIMULATOR_PARAMETERS),
                                         meta=json.dumps(meta),
                                         status=model.STATUS_STARTED,
                                         method_name=ABCAdapter.LAUNCH_METHOD)
        self.operation = dao.store_entity(self.operation)

        SIMULATOR_PARAMETERS['connectivity'] = self._create_connectivity(
            self.CONNECTIVITY_NODES)

    def _create_connectivity(self, nodes_number):
        """
        Create a connectivity entity and return its GID
        """
        storage_path = FilesHelper().get_project_folder(
            self.test_project, str(self.operation.id))
        connectivity = Connectivity(storage_path=storage_path)
        connectivity.weights = numpy.ones((nodes_number, nodes_number))
        connectivity.centres = numpy.ones((nodes_number, 3))
        adapter_instance = StoreAdapter([connectivity])
        OperationService().initiate_prelaunch(self.operation, adapter_instance,
                                              {})

        return dao.get_datatype_by_id(connectivity.id).gid

    def test_happy_flow_launch(self):
        """
        Test that launching a simulation from UI works.
        """
        OperationService().initiate_prelaunch(self.operation,
                                              self.simulator_adapter, {},
                                              **SIMULATOR_PARAMETERS)
        sim_result = dao.get_generic_entity(TimeSeriesRegion,
                                            'TimeSeriesRegion', 'type')[0]
        self.assertEquals(sim_result.read_data_shape(),
                          (32, 1, self.CONNECTIVITY_NODES, 1))

    def _estimate_hdd(self, new_parameters_dict):
        """ Private method, to return HDD estimation for a given set of input parameters"""
        filtered_params = self.simulator_adapter.prepare_ui_inputs(
            new_parameters_dict)
        self.simulator_adapter.configure(**filtered_params)
        return self.simulator_adapter.get_required_disk_size(**filtered_params)

    def test_estimate_hdd(self):
        """
        Test that occupied HDD estimation for simulation results considers simulation length.
        """
        factor = 5
        simulation_parameters = copy(SIMULATOR_PARAMETERS)
        ## Estimate HDD with default simulation parameters
        estimate1 = self._estimate_hdd(simulation_parameters)
        self.assertTrue(estimate1 > 1)

        ## Change simulation length and monitor period, we expect a direct proportial increase in estimated HDD
        simulation_parameters['simulation_length'] = float(
            simulation_parameters['simulation_length']) * factor
        period = float(simulation_parameters[
            'monitors_parameters_option_TemporalAverage_period'])
        simulation_parameters[
            'monitors_parameters_option_TemporalAverage_period'] = period / factor
        estimate2 = self._estimate_hdd(simulation_parameters)
        self.assertEqual(estimate1, estimate2 / factor / factor)

        ## Change number of nodes in connectivity. Expect HDD estimation increase.
        simulation_parameters['connectivity'] = self._create_connectivity(
            self.CONNECTIVITY_NODES * factor)
        estimate3 = self._estimate_hdd(simulation_parameters)
        self.assertEqual(estimate2, estimate3 / factor)

    def test_estimate_execution_time(self):
        """
        Test that get_execution_time_approximation considers the correct params
        """
        ## Compute reference estimation
        simulation_parameters = self.simulator_adapter.prepare_ui_inputs(
            SIMULATOR_PARAMETERS)
        estimation1 = self.simulator_adapter.get_execution_time_approximation(
            **simulation_parameters)

        ## Estimation when the surface input parameter is set
        simulation_parameters['surface'] = "GID_surface"
        estimation2 = self.simulator_adapter.get_execution_time_approximation(
            **simulation_parameters)

        self.assertEqual(estimation1, estimation2 / 500)
        simulation_parameters['surface'] = ""

        ## Modify integration step and simulation length:
        initial_simulation_length = float(
            simulation_parameters['simulation_length'])
        initial_integration_step = float(
            simulation_parameters['integrator_parameters']['dt'])

        for factor in (2, 4, 10):
            simulation_parameters[
                'simulation_length'] = initial_simulation_length * factor
            simulation_parameters['integrator_parameters'][
                'dt'] = initial_integration_step / factor

            estimation3 = self.simulator_adapter.get_execution_time_approximation(
                **simulation_parameters)

            self.assertEqual(estimation1, estimation3 / factor / factor)

        ## Check that no division by zero happens
        simulation_parameters['integrator_parameters']['dt'] = 0
        estimation4 = self.simulator_adapter.get_execution_time_approximation(
            **simulation_parameters)
        self.assertTrue(estimation4 > 0)

        ## even with length zero, still a positive estimation should be returned
        simulation_parameters['simulation_length'] = 0
        estimation5 = self.simulator_adapter.get_execution_time_approximation(
            **simulation_parameters)
        self.assertTrue(estimation5 > 0)

    def test_noise_2d_bad_shape(self):
        """
        Test a simulation with noise. Pass a wrong shape and expect exception to be raised.
        """
        SIMULATOR_PARAMETERS['integrator'] = u'HeunStochastic'
        noise_4d_config = [[1 for _ in xrange(self.CONNECTIVITY_NODES)]
                           for _ in xrange(4)]
        SIMULATOR_PARAMETERS[
            'integrator_parameters_option_HeunStochastic_dt'] = u'0.01220703125'
        SIMULATOR_PARAMETERS[
            'integrator_parameters_option_HeunStochastic_noise'] = u'Additive'
        SIMULATOR_PARAMETERS[
            'integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_nsig'] = str(
                noise_4d_config)
        SIMULATOR_PARAMETERS[
            'integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_ntau'] = u'0.0'
        SIMULATOR_PARAMETERS[
            'integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_random_stream'] = u'RandomStream'
        SIMULATOR_PARAMETERS[
            'integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_random_stream_parameters_option_RandomStream_init_seed'] = u'42'
        filtered_params = self.simulator_adapter.prepare_ui_inputs(
            SIMULATOR_PARAMETERS)
        self.simulator_adapter.configure(**filtered_params)
        if hasattr(self.simulator_adapter, 'algorithm'):
            self.assertEqual(
                (4, 74),
                self.simulator_adapter.algorithm.integrator.noise.nsig.shape)
        else:
            self.fail("Simulator adapter was not initialized properly")
        self.assertRaises(Exception,
                          OperationService().initiate_prelaunch,
                          self.operation, self.simulator_adapter, {},
                          **SIMULATOR_PARAMETERS)

    def test_noise_2d_happy_flow(self):
        """
        Test a simulation with noise.
        """
        SIMULATOR_PARAMETERS['integrator'] = u'HeunStochastic'
        noise_2d_config = [[1 for _ in xrange(self.CONNECTIVITY_NODES)]
                           for _ in xrange(2)]
        SIMULATOR_PARAMETERS[
            'integrator_parameters_option_HeunStochastic_dt'] = u'0.01220703125'
        SIMULATOR_PARAMETERS[
            'integrator_parameters_option_HeunStochastic_noise'] = u'Additive'
        SIMULATOR_PARAMETERS[
            'integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_nsig'] = str(
                noise_2d_config)
        SIMULATOR_PARAMETERS[
            'integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_ntau'] = u'0.0'
        SIMULATOR_PARAMETERS[
            'integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_random_stream'] = u'RandomStream'
        SIMULATOR_PARAMETERS[
            'integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_random_stream_parameters_option_RandomStream_init_seed'] = u'42'
        filtered_params = self.simulator_adapter.prepare_ui_inputs(
            SIMULATOR_PARAMETERS)
        self.simulator_adapter.configure(**filtered_params)
        if hasattr(self.simulator_adapter, 'algorithm'):
            self.assertEqual(
                (2, 74, 1),
                self.simulator_adapter.algorithm.integrator.noise.nsig.shape)
        else:
            self.fail("Simulator adapter was not initialized properly")
        OperationService().initiate_prelaunch(self.operation,
                                              self.simulator_adapter, {},
                                              **SIMULATOR_PARAMETERS)
        sim_result = dao.get_generic_entity(TimeSeriesRegion,
                                            'TimeSeriesRegion', 'type')[0]
        self.assertEquals(sim_result.read_data_shape(),
                          (32, 1, self.CONNECTIVITY_NODES, 1))
        SIMULATOR_PARAMETERS[
            'integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_nsig'] = '[1]'

        filtered_params = self.simulator_adapter.prepare_ui_inputs(
            SIMULATOR_PARAMETERS)
        self.simulator_adapter.configure(**filtered_params)
        if hasattr(self.simulator_adapter, 'algorithm'):
            self.assertEqual(
                (1, ),
                self.simulator_adapter.algorithm.integrator.noise.nsig.shape)
        else:
            self.fail("Simulator adapter was not initialized properly")
        OperationService().initiate_prelaunch(self.operation,
                                              self.simulator_adapter, {},
                                              **SIMULATOR_PARAMETERS)
class SimulatorAdapterTest(TransactionalTestCase):
    """
    Basic testing that Simulator is still working from UI.
    """
    CONNECTIVITY_NODES = 74

    def setUp(self):
        """
        Reset the database before each test.
        """
        initialize_storage()
        user = model.User("test_user", "test_pass", "*****@*****.**", True, "user")
        self.test_user = dao.store_entity(user)
        data = dict(name='test_proj', description='desc', users=[])
        self.test_project = ProjectService().store_project(self.test_user, True, None, **data)
        meta = {DataTypeMetaData.KEY_SUBJECT: "John Doe",
                DataTypeMetaData.KEY_STATE: "INTERMEDIATE"}
        algo_group = dao.find_group(SIMULATOR_MODULE, SIMULATOR_CLASS)
        self.simulator_adapter = FlowService().build_adapter_instance(algo_group)

        self.operation = model.Operation(self.test_user.id, self.test_project.id, algo_group.id,
                                         json.dumps(SIMULATOR_PARAMETERS),
                                         meta=json.dumps(meta), status=model.STATUS_STARTED,
                                         method_name=ABCAdapter.LAUNCH_METHOD)
        self.operation = dao.store_entity(self.operation)

        SIMULATOR_PARAMETERS['connectivity'] = self._create_connectivity(self.CONNECTIVITY_NODES)


    def _create_connectivity(self, nodes_number):
        """
        Create a connectivity entity and return its GID
        """
        storage_path = FilesHelper().get_project_folder(self.test_project, str(self.operation.id))
        connectivity = Connectivity(storage_path=storage_path)
        connectivity.weights = numpy.ones((nodes_number, nodes_number))
        connectivity.centres = numpy.ones((nodes_number, 3))
        adapter_instance = StoreAdapter([connectivity])
        OperationService().initiate_prelaunch(self.operation, adapter_instance, {})

        return dao.get_datatype_by_id(connectivity.id).gid


    def test_happy_flow_launch(self):
        """
        Test that launching a simulation from UI works.
        """
        OperationService().initiate_prelaunch(self.operation, self.simulator_adapter, {}, **SIMULATOR_PARAMETERS)
        sim_result = dao.get_generic_entity(TimeSeriesRegion, 'TimeSeriesRegion', 'type')[0]
        self.assertEquals(sim_result.read_data_shape(), (32, 1, self.CONNECTIVITY_NODES, 1))


    def _estimate_hdd(self, new_parameters_dict):
        """ Private method, to return HDD estimation for a given set of input parameters"""
        filtered_params = self.simulator_adapter.prepare_ui_inputs(new_parameters_dict)
        self.simulator_adapter.configure(**filtered_params)
        return self.simulator_adapter.get_required_disk_size(**filtered_params)


    def test_estimate_hdd(self):
        """
        Test that occupied HDD estimation for simulation results considers simulation length.
        """
        factor = 5
        simulation_parameters = copy(SIMULATOR_PARAMETERS)
        ## Estimate HDD with default simulation parameters
        estimate1 = self._estimate_hdd(simulation_parameters)
        self.assertTrue(estimate1 > 1)

        ## Change simulation length and monitor period, we expect a direct proportial increase in estimated HDD
        simulation_parameters['simulation_length'] = float(simulation_parameters['simulation_length']) * factor
        period = float(simulation_parameters['monitors_parameters_option_TemporalAverage_period'])
        simulation_parameters['monitors_parameters_option_TemporalAverage_period'] = period / factor
        estimate2 = self._estimate_hdd(simulation_parameters)
        self.assertEqual(estimate1, estimate2 / factor / factor)

        ## Change number of nodes in connectivity. Expect HDD estimation increase.
        simulation_parameters['connectivity'] = self._create_connectivity(self.CONNECTIVITY_NODES * factor)
        estimate3 = self._estimate_hdd(simulation_parameters)
        self.assertEqual(estimate2, estimate3 / factor)


    def test_estimate_execution_time(self):
        """
        Test that get_execution_time_approximation considers the correct params
        """
        ## Compute reference estimation
        simulation_parameters = self.simulator_adapter.prepare_ui_inputs(SIMULATOR_PARAMETERS)
        estimation1 = self.simulator_adapter.get_execution_time_approximation(**simulation_parameters)

        ## Estimation when the surface input parameter is set
        simulation_parameters['surface'] = "GID_surface"
        estimation2 = self.simulator_adapter.get_execution_time_approximation(**simulation_parameters)

        self.assertEqual(estimation1, estimation2 / 500)
        simulation_parameters['surface'] = ""

        ## Modify integration step and simulation length:
        initial_simulation_length = float(simulation_parameters['simulation_length'])
        initial_integration_step = float(simulation_parameters['integrator_parameters']['dt'])

        for factor in (2, 4, 10):
            simulation_parameters['simulation_length'] = initial_simulation_length * factor
            simulation_parameters['integrator_parameters']['dt'] = initial_integration_step / factor

            estimation3 = self.simulator_adapter.get_execution_time_approximation(**simulation_parameters)

            self.assertEqual(estimation1, estimation3 / factor / factor)

        ## Check that no division by zero happens
        simulation_parameters['integrator_parameters']['dt'] = 0
        estimation4 = self.simulator_adapter.get_execution_time_approximation(**simulation_parameters)
        self.assertTrue(estimation4 > 0)

        ## even with length zero, still a positive estimation should be returned
        simulation_parameters['simulation_length'] = 0
        estimation5 = self.simulator_adapter.get_execution_time_approximation(**simulation_parameters)
        self.assertTrue(estimation5 > 0)


    def test_noise_2d_bad_shape(self):
        """
        Test a simulation with noise. Pass a wrong shape and expect exception to be raised.
        """
        SIMULATOR_PARAMETERS['integrator'] = u'HeunStochastic'
        noise_4d_config = [[1 for _ in xrange(self.CONNECTIVITY_NODES)] for _ in xrange(4)]
        SIMULATOR_PARAMETERS['integrator_parameters_option_HeunStochastic_dt'] = u'0.01220703125'
        SIMULATOR_PARAMETERS['integrator_parameters_option_HeunStochastic_noise'] = u'Additive'
        SIMULATOR_PARAMETERS['integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_nsig'] = str(noise_4d_config)
        SIMULATOR_PARAMETERS['integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_ntau'] = u'0.0'
        SIMULATOR_PARAMETERS['integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_random_stream'] = u'RandomStream'
        SIMULATOR_PARAMETERS['integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_random_stream_parameters_option_RandomStream_init_seed'] = u'42'
        filtered_params = self.simulator_adapter.prepare_ui_inputs(SIMULATOR_PARAMETERS)
        self.simulator_adapter.configure(**filtered_params)
        if hasattr(self.simulator_adapter, 'algorithm'):
            self.assertEqual((4, 74), self.simulator_adapter.algorithm.integrator.noise.nsig.shape)
        else:
            self.fail("Simulator adapter was not initialized properly")
        self.assertRaises(Exception, OperationService().initiate_prelaunch, self.operation, self.simulator_adapter, {}, **SIMULATOR_PARAMETERS)


    def test_noise_2d_happy_flow(self):
        """
        Test a simulation with noise.
        """
        SIMULATOR_PARAMETERS['integrator'] = u'HeunStochastic'
        noise_2d_config = [[1 for _ in xrange(self.CONNECTIVITY_NODES)] for _ in xrange(2)]
        SIMULATOR_PARAMETERS['integrator_parameters_option_HeunStochastic_dt'] = u'0.01220703125'
        SIMULATOR_PARAMETERS['integrator_parameters_option_HeunStochastic_noise'] = u'Additive'
        SIMULATOR_PARAMETERS['integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_nsig'] = str(noise_2d_config)
        SIMULATOR_PARAMETERS['integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_ntau'] = u'0.0'
        SIMULATOR_PARAMETERS['integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_random_stream'] = u'RandomStream'
        SIMULATOR_PARAMETERS['integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_random_stream_parameters_option_RandomStream_init_seed'] = u'42'
        filtered_params = self.simulator_adapter.prepare_ui_inputs(SIMULATOR_PARAMETERS)
        self.simulator_adapter.configure(**filtered_params)
        if hasattr(self.simulator_adapter, 'algorithm'):
            self.assertEqual((2, 74, 1), self.simulator_adapter.algorithm.integrator.noise.nsig.shape)
        else:
            self.fail("Simulator adapter was not initialized properly")
        OperationService().initiate_prelaunch(self.operation, self.simulator_adapter, {}, **SIMULATOR_PARAMETERS)
        sim_result = dao.get_generic_entity(TimeSeriesRegion, 'TimeSeriesRegion', 'type')[0]
        self.assertEquals(sim_result.read_data_shape(), (32, 1, self.CONNECTIVITY_NODES, 1))
        SIMULATOR_PARAMETERS['integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_nsig'] = '[1]'

        filtered_params = self.simulator_adapter.prepare_ui_inputs(SIMULATOR_PARAMETERS)
        self.simulator_adapter.configure(**filtered_params)
        if hasattr(self.simulator_adapter, 'algorithm'):
            self.assertEqual((1,), self.simulator_adapter.algorithm.integrator.noise.nsig.shape)
        else:
            self.fail("Simulator adapter was not initialized properly")
        OperationService().initiate_prelaunch(self.operation, self.simulator_adapter, {}, **SIMULATOR_PARAMETERS)
class SimulatorAdapterTest(TransactionalTestCase):
    """
    Basic testing that Simulator is still working from UI.
    """
    CONNECTIVITY_NODES = 74

    def setUp(self):
        """
        Reset the database before each test.
        """
        initialize_storage()
        self.datatypes_factory = DatatypesFactory()
        self.test_user = self.datatypes_factory.get_user()
        self.test_project = self.datatypes_factory.get_project()
        self.connectivity = self.datatypes_factory.create_connectivity(self.CONNECTIVITY_NODES)[1]

        algo_group = dao.find_group(SIMULATOR_MODULE, SIMULATOR_CLASS)
        algorithm = dao.get_algorithm_by_group(algo_group.id)
        self.simulator_adapter = FlowService().build_adapter_instance(algo_group)
        self.operation = TestFactory.create_operation(algorithm, self.test_user, self.test_project,
                                                      model.STATUS_STARTED, json.dumps(SIMULATOR_PARAMETERS))

        SIMULATOR_PARAMETERS['connectivity'] = self.connectivity.gid


    def test_happy_flow_launch(self):
        """
        Test that launching a simulation from UI works.
        """
        OperationService().initiate_prelaunch(self.operation, self.simulator_adapter, {}, **SIMULATOR_PARAMETERS)
        sim_result = dao.get_generic_entity(TimeSeriesRegion, 'TimeSeriesRegion', 'type')[0]
        self.assertEquals(sim_result.read_data_shape(), (32, 1, self.CONNECTIVITY_NODES, 1))


    def _estimate_hdd(self, new_parameters_dict):
        """ Private method, to return HDD estimation for a given set of input parameters"""
        filtered_params = self.simulator_adapter.prepare_ui_inputs(new_parameters_dict)
        self.simulator_adapter.configure(**filtered_params)
        return self.simulator_adapter.get_required_disk_size(**filtered_params)


    def test_estimate_hdd(self):
        """
        Test that occupied HDD estimation for simulation results considers simulation length.
        """
        factor = 5
        simulation_parameters = copy(SIMULATOR_PARAMETERS)
        ## Estimate HDD with default simulation parameters
        estimate1 = self._estimate_hdd(simulation_parameters)
        self.assertTrue(estimate1 > 1)

        ## Change simulation length and monitor period, we expect a direct proportial increase in estimated HDD
        simulation_parameters['simulation_length'] = float(simulation_parameters['simulation_length']) * factor
        period = float(simulation_parameters['monitors_parameters_option_TemporalAverage_period'])
        simulation_parameters['monitors_parameters_option_TemporalAverage_period'] = period / factor
        estimate2 = self._estimate_hdd(simulation_parameters)
        self.assertEqual(estimate1, estimate2 / factor / factor)

        ## Change number of nodes in connectivity. Expect HDD estimation increase.
        large_conn_gid = self.datatypes_factory.create_connectivity(self.CONNECTIVITY_NODES * factor)[1].gid
        simulation_parameters['connectivity'] = large_conn_gid
        estimate3 = self._estimate_hdd(simulation_parameters)
        self.assertEqual(estimate2, estimate3 / factor)


    def test_estimate_execution_time(self):
        """
        Test that get_execution_time_approximation considers the correct params
        """
        ## Compute reference estimation
        params = self.simulator_adapter.prepare_ui_inputs(SIMULATOR_PARAMETERS)
        estimation1 = self.simulator_adapter.get_execution_time_approximation(**params)

        ## Estimation when the surface input parameter is set
        params['surface'] = "GID_surface"
        estimation2 = self.simulator_adapter.get_execution_time_approximation(**params)

        self.assertEqual(estimation1, estimation2 / 500)
        params['surface'] = ""

        ## Modify integration step and simulation length:
        initial_simulation_length = float(params['simulation_length'])
        initial_integration_step = float(params['integrator_parameters']['dt'])

        for factor in (2, 4, 10):
            params['simulation_length'] = initial_simulation_length * factor
            params['integrator_parameters']['dt'] = initial_integration_step / factor

            estimation3 = self.simulator_adapter.get_execution_time_approximation(**params)

            self.assertEqual(estimation1, estimation3 / factor / factor)

        ## Check that no division by zero happens
        params['integrator_parameters']['dt'] = 0
        estimation4 = self.simulator_adapter.get_execution_time_approximation(**params)
        self.assertTrue(estimation4 > 0)

        ## even with length zero, still a positive estimation should be returned
        params['simulation_length'] = 0
        estimation5 = self.simulator_adapter.get_execution_time_approximation(**params)
        self.assertTrue(estimation5 > 0)


    def test_noise_2d_bad_shape(self):
        """
        Test a simulation with noise. Pass a wrong shape and expect exception to be raised.
        """
        params = copy(SIMULATOR_PARAMETERS)
        params['integrator'] = u'HeunStochastic'
        noise_4d_config = [[1 for _ in xrange(self.CONNECTIVITY_NODES)] for _ in xrange(4)]
        params['integrator_parameters_option_HeunStochastic_dt'] = u'0.01220703125'
        params['integrator_parameters_option_HeunStochastic_noise'] = u'Additive'
        params['integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_nsig'] = str(noise_4d_config)
        params['integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_ntau'] = u'0.0'
        params['integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_random_stream'] = u'RandomStream'
        params['integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_random_stream_parameters_option_RandomStream_init_seed'] = u'42'
        filtered_params = self.simulator_adapter.prepare_ui_inputs(params)
        self.simulator_adapter.configure(**filtered_params)
        if hasattr(self.simulator_adapter, 'algorithm'):
            self.assertEqual((4, 74), self.simulator_adapter.algorithm.integrator.noise.nsig.shape)
        else:
            self.fail("Simulator adapter was not initialized properly")
        self.assertRaises(Exception, OperationService().initiate_prelaunch, self.operation,
                          self.simulator_adapter, {}, **params)


    def test_noise_2d_happy_flow(self):
        """
        Test a simulation with noise.
        """
        params = copy(SIMULATOR_PARAMETERS)
        params['integrator'] = u'HeunStochastic'
        noise_2d_config = [[1 for _ in xrange(self.CONNECTIVITY_NODES)] for _ in xrange(2)]
        params['integrator_parameters_option_HeunStochastic_dt'] = u'0.01220703125'
        params['integrator_parameters_option_HeunStochastic_noise'] = u'Additive'
        params['integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_nsig'] = str(noise_2d_config)
        params['integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_ntau'] = u'0.0'
        params['integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_random_stream'] = u'RandomStream'
        params['integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_random_stream_parameters_option_RandomStream_init_seed'] = u'42'

        self._launch_and_check_noise(params, (2, 74))

        sim_result = dao.get_generic_entity(TimeSeriesRegion, 'TimeSeriesRegion', 'type')[0]
        self.assertEquals(sim_result.read_data_shape(), (32, 1, self.CONNECTIVITY_NODES, 1))

        params['integrator_parameters_option_HeunStochastic_noise_parameters_option_Additive_nsig'] = '[1]'
        self._launch_and_check_noise(params, (1,))


    def _launch_and_check_noise(self, params, expected_noise_shape):

        filtered_params = self.simulator_adapter.prepare_ui_inputs(params)
        self.simulator_adapter.configure(**filtered_params)

        if hasattr(self.simulator_adapter, 'algorithm'):
            self.assertEqual(expected_noise_shape, self.simulator_adapter.algorithm.integrator.noise.nsig.shape)
        else:
            self.fail("Simulator adapter was not initialized properly")

        OperationService().initiate_prelaunch(self.operation, self.simulator_adapter, {}, **params)


    def test_simulation_with_stimulus(self):
        """
        Test a simulation with noise.
        """
        params = copy(SIMULATOR_PARAMETERS)
        params["stimulus"] = self.datatypes_factory.create_stimulus(self.connectivity).gid

        filtered_params = self.simulator_adapter.prepare_ui_inputs(params)
        self.simulator_adapter.configure(**filtered_params)
        OperationService().initiate_prelaunch(self.operation, self.simulator_adapter, {}, **params)