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: "RAW"}
        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 _estimate_execution_time(self, new_parameters_dict):
        """ Private method, to return execution time 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_execution_time_approximation(**filtered_params)
        
        
    def test_execution_time_approximation(self):
        simulation_parameters = copy(SIMULATOR_PARAMETERS)
        base_time_length = 400
        factors = (2, 4, 13)
        simulation_parameters['simulation_length'] = float(base_time_length)
        base_estimate = self._estimate_execution_time(simulation_parameters)
        self.assertTrue(base_estimate > 0)
        for scale_factor in factors:
            # Test that time estimation scales linear with simulation length
            simulation_parameters['simulation_length'] = float(base_time_length * scale_factor)
            scaled_estimate = self._estimate_execution_time(simulation_parameters)
            self.assertEqual(scaled_estimate / (base_estimate * scale_factor), 1)
        # Even in absurd case where simulation length is 0 or negative operation should still
        # be estimate as a larger than 0s value
        simulation_parameters['simulation_length'] = 0.0
        estimate = self._estimate_execution_time(simulation_parameters)
        self.assertTrue(estimate >= 0, "Actually got %s" % estimate)
        
        
    
    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)
Esempio n. 2
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()
        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 : "RAW"}
        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="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)