Exemple #1
0
class Network(object):
    '''Initialize and run a dipde simulation.
    
    The Network class handles the initialization of population and connection
    objects, and provides a convenience time stepping loop to drive a network
    simulation.  Typical usage involves the create of populations and
    connections, construction of a simulation object, and then call to
    simulation.run()
    
    Parameters
    ----------
    population_list : list of ExternalPopulation, InternalPopulation objects
        List of populations to include in simulation.
    connection_list : list of Connection objects
        List of connections to include in simulation.
    verbose : bool (default=True)
        Setting True prints current time-step at each update evaluation.
    '''
    def __init__(self,
                 population_list=[],
                 connection_list=[],
                 metadata={},
                 run_callback=lambda s: None,
                 update_callback=lambda s: None,
                 progress=None,
                 **kwargs):

        self.update_callback = update_callback
        self.run_callback = run_callback

        self.progress = progress

        self.population_list = []
        for p in population_list:
            if isinstance(p, dict):
                curr_module, curr_class = p['module'], p['class']
                curr_instance = getattr(importlib.import_module(curr_module),
                                        curr_class)(**p)
                self.population_list.append(curr_instance)
            else:
                self.population_list.append(p)

        self.connection_list = []
        for c in connection_list:
            if isinstance(c, dict):
                curr_module, curr_class = c['class']
                curr_instance = getattr(importlib.import_module(curr_module),
                                        curr_class)(**c)
                if curr_instance.nsyn_input != 0:
                    self.connection_list.append(curr_instance)
            else:
                if c.nsyn_input != 0:
                    self.connection_list.append(c)

        self.gid_dict = dict(
            (population, ii)
            for ii, population in enumerate(self.population_list))
        for key, val in self.gid_dict.items():
            self.gid_dict[val] = key

        # Initialize:
        self.connection_distribution_collection = ConnectionDistributionCollection(
        )

        # Each population needs access to dt:
        for p in self.population_list:
            p.simulation = self

        # Each connection needs access to t:
        for c in self.connection_list:
            c.simulation = self

        self.kill_signal = False

    @property
    def rank(self):
        return self.synchronization_harness.rank

    def run(self, *args, **kwargs):
        try:
            self._run(*args, **kwargs)
        except Exception as e:
            self.shutdown()
            print 'Safely Shutting down after exception...'
            print traceback.format_exc()
            raise e

    def _run(self, dt, tf, t0=0., synchronization_harness=None):
        '''Main iteration control loop for simulation
        
        The time step selection must be approximately of the same order as dv
        for the internal populations, if the 'approx' time stepping method is
        selected.
        
        Parameters
        ----------
        t0 : float (default=0.)
            Network start time (unit=seconds), passed to initialize call.
        tf : float (default=.1)
            Network end time (unit=seconds).
        dt : float (default=0.001)
            Time step (unit=seconds).
        '''

        if synchronization_harness is None:
            self.synchronization_harness = utilities.DefaultSynchronizationHarness(
            )
        else:
            self.synchronization_harness = synchronization_harness
        self.firing_rate_organizer = FiringRateOrganizer(
            self.synchronization_harness)

        self.dt = dt
        self.t0 = t0

        if not self.progress is None: self.progress.set_network(self)

        # Initialize:
        start_time = time.time()
        self.tf = tf
        self.ti = 0

        if not self.progress is None: self.progress.initialize()
        self.synchronization_harness.initialize(self.ti)

        # Initialize populations:
        for gid, p in enumerate(self.population_list):
            p.initialize()

            if self.synchronization_harness.gid_to_rank(gid) == self.rank:
                self.firing_rate_organizer.push(self.ti, gid,
                                                p.curr_firing_rate)

        self.synchronization_harness.update(
            self.ti,
            self.firing_rate_organizer.firing_rate_dict_internal.setdefault(
                self.ti, {}))

        # Initialize connections:
        for c in self.connection_list:
            c.initialize()

        for p in self.population_list:
            try:
                p.initialize_total_input_dict()
            except AttributeError:
                pass

        self.initialization_time = time.time() - start_time

        # Run
        start_time = time.time()
        while self.t < self.tf:
            self.update()

        self.run_time = time.time() - start_time

        self.synchronization_harness.finalize()
        self.shutdown()

        self.run_callback(self)

    def shutdown(self):

        for c in self.connection_list:
            c.shutdown()

        for p in self.population_list:
            p.shutdown()

    @property
    def t(self):
        return self.t0 + self.ti * self.dt

    def update(self):

        if not self.progress is None: self.progress.update()
        self.firing_rate_organizer.drop(self.ti)
        self.ti += 1
        logger.info('time: %s' % self.t)

        for gid, p in enumerate(self.population_list):

            if self.synchronization_harness.gid_to_rank(gid) == self.rank:
                p.update()
                self.firing_rate_organizer.push(self.ti, gid,
                                                p.curr_firing_rate)

        self.synchronization_harness.update(
            self.ti,
            self.firing_rate_organizer.firing_rate_dict_internal.setdefault(
                self.ti, {}))

        for c in self.connection_list:
            c.update()

        self.update_callback(self)

        if self.kill_signal:
            raise StopSimulation()

    def to_dict(self, organization='sparse_adjacency_matrix'):

        population_list = [p.to_dict() for p in self.population_list]
        connection_list = [c.to_dict() for c in self.connection_list]

        if organization == 'sparse_adjacency_matrix':

            data_dict = {
                'population_list': population_list,
                'connection_list': connection_list,
                'class': self.__class__.__name__,
                'module': __name__
            }

            return data_dict

        else:

            raise NotImplementedError

    def to_json(self, fh=None, **kwargs):
        '''Save the contents of the InternalPopultion to json'''

        data_dict = self.to_dict()

        indent = kwargs.pop('indent', 2)

        if fh is None:
            return json.dumps(data_dict, indent=indent, **kwargs)
        else:
            return json.dump(data_dict, fh, indent=indent, **kwargs)

    def copy(self):
        return Network(**self.to_dict())

    def get_curr_firing_rate(self, gid):
        return self.firing_rate_organizer.pull(self.ti, gid)

    def get_firing_rate(self, gid, t):
        return self.population_list[gid].firing_rate(t)

    def to_df(self):
        pd.options.display.max_columns = 999
        df_list = [p.to_df() for p in self.population_list]
        return reorder_df_columns(pd.concat(df_list), ['class', 'module'])

    def get_total_flux_matrix(self, internal_population, dt):

        # Protect memory state of population and network:
        population_ind = self.population_list.index(internal_population)
        new_network = self.copy()
        new_network.dt = dt
        new_network.t0 = 0
        new_network.ti = 0

        new_internal_population = new_network.population_list[population_ind]
        new_internal_population.initialize()
        new_internal_population.initialize_total_input_dict()
        return new_internal_population.get_total_flux_matrix()

    @property
    def external_population_list(self):
        return [
            p for p in self.population_list
            if isinstance(p, ExternalPopulation)
        ]

    @property
    def internal_population_list(self):
        return [
            p for p in self.population_list
            if isinstance(p, InternalPopulation)
        ]
Exemple #2
0
class Network(object):
    '''Initialize and run a dipde simulation.
    
    The Network class handles the initialization of population and connection
    objects, and provides a convenience time stepping loop to drive a network
    simulation.  Typical usage involves the create of populations and
    connections, construction of a simulation object, and then call to
    simulation.run()
    
    Parameters
    ----------
    population_list : list of ExternalPopulation, InternalPopulation objects
        List of populations to include in simulation.
    connection_list : list of Connection objects
        List of connections to include in simulation.
    verbose : bool (default=True)
        Setting True prints current time-step at each update evaluation.
    '''
    def __init__(self,
                 population_list=[],
                 connection_list=[],
                 metadata={},
                 run_callback=lambda s: None,
                 update_callback=lambda s: None,
                 **kwargs):

        self.update_callback = update_callback
        self.run_callback = run_callback

        self.population_list = []
        for p in population_list:
            if isinstance(p, dict):
                curr_module, curr_class = p['module'], p['class']
                curr_instance = getattr(importlib.import_module(curr_module),
                                        curr_class)(**p)
                self.population_list.append(curr_instance)
            else:
                self.population_list.append(p)

        self.connection_list = []
        for c in connection_list:
            if isinstance(c, dict):
                curr_module, curr_class = c['class']
                curr_instance = getattr(importlib.import_module(curr_module),
                                        curr_class)(**c)
                if curr_instance.nsyn != 0:
                    self.connection_list.append(curr_instance)
            else:
                if c.nsyn != 0:
                    self.connection_list.append(c)

        self.gid_dict = dict(
            (population, ii)
            for ii, population in enumerate(self.population_list))
        for key, val in self.gid_dict.items():
            self.gid_dict[val] = key

        # Initialize:
        self.connection_distribution_collection = ConnectionDistributionCollection(
        )

        # Each population needs access to dt:
        for p in self.population_list:
            p.simulation = self

        # Each connection needs access to t:
        for c in self.connection_list:
            c.simulation = self

    @property
    def rank(self):
        return self.distributed_configuration.rank()

    def run(self,
            dt,
            tf,
            t0=0.,
            distributed_configuration=utilities.NullObject()):
        '''Main iteration control loop for simulation
        
        The time step selection must be approximately of the same order as dv
        for the internal populations, if the 'approx' time stepping method is
        selected.
        
        Parameters
        ----------
        t0 : float (default=0.)
            Network start time (unit=seconds), passed to initialize call.
        tf : float (default=.1)
            Network end time (unit=seconds).
        dt : float (default=0.001)
            Time step (unit=seconds).
        '''

        self.distributed_configuration = distributed_configuration
        self.firing_rate_organizer = FiringRateOrganizer(
            self.distributed_configuration)

        self.dt = dt
        self.t0 = t0

        # Initialize:
        start_time = time.time()
        self.tf = tf
        self.ti = 0

        self.distributed_configuration.initialize(self.ti)

        # Initialize populations:
        for gid, p in enumerate(self.population_list):
            p.initialize()
            self.firing_rate_organizer.push(self.ti, gid, p.curr_firing_rate)

        self.distributed_configuration.update(
            self.ti,
            self.firing_rate_organizer.firing_rate_dict_internal[self.ti])

        for p in self.population_list:
            if isinstance(p, InternalPopulation):
                p.initialize_total_input_dict()

        # Initialize connections:
        for c in self.connection_list:
            c.initialize()
        self.initialization_time = time.time() - start_time

        # Run
        start_time = time.time()
        while self.t < self.tf:
            self.update()

        self.run_time = time.time() - start_time

        self.distributed_configuration.finalize()

        self.run_callback(self)

    @property
    def t(self):
        return self.t0 + self.ti * self.dt

    def update(self):

        self.firing_rate_organizer.drop(self.ti)
        self.ti += 1
        logger.info('time: %s' % self.t)

        for gid, p in enumerate(self.population_list):
            if self.distributed_configuration.gid_to_rank(gid) == self.rank:
                p.update()
                self.firing_rate_organizer.push(self.ti, gid,
                                                p.curr_firing_rate)

        self.distributed_configuration.update(
            self.ti,
            self.firing_rate_organizer.firing_rate_dict_internal[self.ti])

        for c in self.connection_list:
            c.update()

        self.update_callback(self)

    def to_dict(self):

        data_dict = {
            'population_list': [p.to_dict() for p in self.population_list],
            'connection_list': [c.to_dict() for c in self.connection_list],
            'class': self.__class__.__name__,
            'module': __name__
        }

        return data_dict

    def to_json(self, fh=None, **kwargs):
        '''Save the contents of the InternalPopultion to json'''

        data_dict = self.to_dict()

        indent = kwargs.pop('indent', 2)

        if fh is None:
            return json.dumps(data_dict, indent=indent, **kwargs)
        else:
            return json.dump(data_dict, fh, indent=indent, **kwargs)

    def copy(self):
        return Network(**self.to_dict())

    def get_curr_firing_rate(self, gid):
        return self.firing_rate_organizer.pull(self.ti, gid)

    def get_firing_rate(self, gid, t):
        return self.population_list[gid].firing_rate(t)

    def to_df(self):
        pd.options.display.max_columns = 999
        df_list = [p.to_df() for p in self.population_list]
        return reorder_df_columns(pd.concat(df_list), ['class', 'module'])
Exemple #3
0
class Network(object):
    '''Initialize and run a dipde simulation.
    
    The Network class handles the initialization of population and connection
    objects, and provides a convenience time stepping loop to drive a network
    simulation.  Typical usage involves the create of populations and
    connections, construction of a simulation object, and then call to
    simulation.run()
    
    Parameters
    ----------
    population_list : list of ExternalPopulation, InternalPopulation objects
        List of populations to include in simulation.
    connection_list : list of Connection objects
        List of connections to include in simulation.
    verbose : bool (default=True)
        Setting True prints current time-step at each update evaluation.
    '''
    
    def __init__(self, 
                 population_list=[], 
                 connection_list=[],
                 metadata={},
                 run_callback=lambda s: None,
                 update_callback=lambda s: None,
                 progress=None,
                 **kwargs):
        
        self.update_callback = update_callback
        self.run_callback = run_callback

        self.progress = progress

        self.population_list = []
        for p in population_list:
            if isinstance(p, dict):
                curr_module, curr_class = p['module'], p['class']
                curr_instance = getattr(importlib.import_module(curr_module), curr_class)(**p)
                self.population_list.append(curr_instance)
            else: 
                self.population_list.append(p)

        self.connection_list = []
        for c in connection_list:
            if isinstance(c, dict):
                curr_module, curr_class = c['class']
                curr_instance = getattr(importlib.import_module(curr_module), curr_class)(**c)
                if curr_instance.nsyn_input != 0:
                    self.connection_list.append(curr_instance)
            else:
                if c.nsyn_input != 0:
                    self.connection_list.append(c)



        self.gid_dict = dict((population, ii) for ii, population in enumerate(self.population_list))
        for key, val in self.gid_dict.items():
            self.gid_dict[val] = key
        
        # Initialize:
        self.connection_distribution_collection = ConnectionDistributionCollection()
        
        # Each population needs access to dt:
        for p in self.population_list:
            p.simulation = self
            
        # Each connection needs access to t:
        for c in self.connection_list:
            c.simulation = self


        self.kill_signal = False
    
    @property
    def rank(self):
        return self.synchronization_harness.rank

    def run(self, *args, **kwargs):
        try:
            self._run(*args, **kwargs)
        except Exception as e:
            self.shutdown()
            print 'Safely Shutting down after exception...'
            print traceback.format_exc()
            raise e
        
    def _run(self, dt, tf, t0=0., synchronization_harness=None):

        '''Main iteration control loop for simulation
        
        The time step selection must be approximately of the same order as dv
        for the internal populations, if the 'approx' time stepping method is
        selected.
        
        Parameters
        ----------
        t0 : float (default=0.)
            Network start time (unit=seconds), passed to initialize call.
        tf : float (default=.1)
            Network end time (unit=seconds).
        dt : float (default=0.001)
            Time step (unit=seconds).
        '''

        if synchronization_harness is None:
            self.synchronization_harness = utilities.DefaultSynchronizationHarness()
        else:
            self.synchronization_harness = synchronization_harness
        self.firing_rate_organizer = FiringRateOrganizer(self.synchronization_harness)
        
        self.dt = dt
        self.t0 = t0

        if not self.progress is None: self.progress.set_network(self)

        # Initialize:
        start_time = time.time()
        self.tf = tf
        self.ti = 0



        if not self.progress is None: self.progress.initialize()
        self.synchronization_harness.initialize(self.ti)
        
        # Initialize populations:
        for gid, p in enumerate(self.population_list):
            p.initialize()

            if self.synchronization_harness.gid_to_rank(gid) == self.rank:
                self.firing_rate_organizer.push(self.ti, gid, p.curr_firing_rate)
        
        self.synchronization_harness.update(self.ti, self.firing_rate_organizer.firing_rate_dict_internal.setdefault(self.ti, {}))



        # Initialize connections:
        for c in self.connection_list:
            c.initialize()



        for p in self.population_list:
            try:
                p.initialize_total_input_dict()
            except AttributeError:
                pass

        self.initialization_time = time.time() - start_time
        

        
        # Run
        start_time = time.time()
        while self.t < self.tf:
            self.update()

        self.run_time = time.time() - start_time

        self.synchronization_harness.finalize()
        self.shutdown()

        
        self.run_callback(self)

    def shutdown(self):

        for c in self.connection_list:
            c.shutdown()

        for p in self.population_list:
            p.shutdown()


        
    @property
    def t(self): return self.t0+self.ti*self.dt

    def update(self):

        if not self.progress is None: self.progress.update()
        self.firing_rate_organizer.drop(self.ti)
        self.ti += 1
        logger.info( 'time: %s' % self.t)
        
        for gid, p in enumerate(self.population_list):

            if self.synchronization_harness.gid_to_rank(gid) == self.rank:
                p.update()
                self.firing_rate_organizer.push(self.ti, gid, p.curr_firing_rate)
        
        self.synchronization_harness.update(self.ti, self.firing_rate_organizer.firing_rate_dict_internal.setdefault(self.ti, {}))

        
        for c in self.connection_list:
            c.update()
            
        self.update_callback(self)

        if self.kill_signal:
            raise StopSimulation()
        
    def to_dict(self, organization='sparse_adjacency_matrix'):

        population_list = [p.to_dict() for p in self.population_list]
        connection_list = [c.to_dict() for c in self.connection_list]

        if organization == 'sparse_adjacency_matrix':

            data_dict = {'population_list':population_list,
                         'connection_list':connection_list,
                         'class':self.__class__.__name__,
                         'module':__name__}
            
            return data_dict
        
        else:
            
            raise NotImplementedError
            
            
        
    def to_json(self, fh=None, **kwargs):
        '''Save the contents of the InternalPopultion to json'''
        
        data_dict = self.to_dict()

        indent = kwargs.pop('indent',2)

        if fh is None:
            return json.dumps(data_dict, indent=indent, **kwargs)
        else:
            return json.dump(data_dict, fh, indent=indent, **kwargs)

    def copy(self):
        return Network(**self.to_dict())
    
    def get_curr_firing_rate(self, gid):
        return self.firing_rate_organizer.pull(self.ti,gid)
        
    def get_firing_rate(self, gid, t):
        return self.population_list[gid].firing_rate(t)
    
    def to_df(self):
        pd.options.display.max_columns = 999
        df_list = [p.to_df() for p in self.population_list]
        return reorder_df_columns(pd.concat(df_list), ['class', 'module'])

    def get_total_flux_matrix(self, internal_population, dt):
        
        # Protect memory state of population and network:
        population_ind = self.population_list.index(internal_population)
        new_network = self.copy()
        new_network.dt = dt
        new_network.t0 = 0
        new_network.ti = 0
        
        new_internal_population = new_network.population_list[population_ind] 
        new_internal_population.initialize()
        new_internal_population.initialize_total_input_dict()
        return new_internal_population.get_total_flux_matrix()
    
    @property
    def external_population_list(self):
        return [p for p in self.population_list if isinstance(p, ExternalPopulation)]
    
    @property
    def internal_population_list(self):
        return [p for p in self.population_list if isinstance(p, InternalPopulation)]