def __init__(self, sedml_experiment): """ :rtype: None :raises: RuntimeError """ self.name = '' self.network = None self.reportingInterval = 0.0 self.timeHorizon = 0.0 self.log = daeLogs.daePythonStdOutLog() self.datareporter = pyDataReporting.daeNoOpDataReporter() #pyDataReporting.daeTCPIPDataReporter() self.simulations = [] self.events_heap = [] self.average_firing_rate = {} self.raster_plot_data = [] self.pathParser = CanonicalNameParser() self.report_variables = {} self.output_plots = [] self.number_of_equations = 0 self.number_of_neurones = 0 self.number_of_synapses = 0 self.spike_count = 0 self.minimal_delay = 1.0E10 heapify(self.events_heap) # Create daetoolsPointNeuroneNetwork object and the simulation runtime information self.processSEDMLExperiment(sedml_experiment) # Connect the DataReporter simName = self.name + strftime(" [%d.%m.%Y %H.%M.%S]", localtime()) if not self.datareporter.Connect("", simName): raise RuntimeError('Cannot connect the data reporter') # Set the random number generators of the daetoolsComponentSetup daetoolsComponentSetup._random_number_generators = self.network.randomNumberGenerators # Setup neurones try: self.log.Enabled = False for group_name, group in self.network._groups.iteritems(): for projection_name, projection in group._projections.iteritems(): if projection.minimal_delay < self.minimal_delay: self.minimal_delay = projection.minimal_delay for population_name, population in group._populations.iteritems(): print("Creating simulations for: {0}...".format(population_name)) for neurone in population.neurones: simulation = daetoolsPointNeuroneSimulation(neurone, population._parameters, {}) neurone.events_heap = self.events_heap self.simulations.append(simulation) self.number_of_neurones += 1 for (synapse, params) in neurone.incoming_synapses: self.number_of_synapses += synapse.Nitems self.simulations.sort() if self.minimal_delay < self.reportingInterval: raise RuntimeError('The minimal delay ({0}s) is greater than the reporting interval ({1}s)'.format(self.minimal_delay, self.reportingInterval)) except: raise finally: self.log.Enabled = True
def __init__(self, sedml_experiment): """ :rtype: None :raises: RuntimeError """ self.name = '' self.network = None self.reportingInterval = 0.0 self.timeHorizon = 0.0 self.log = daeLogs.daePythonStdOutLog() self.datareporter = pyDataReporting.daeNoOpDataReporter( ) #pyDataReporting.daeTCPIPDataReporter() self.simulations = [] self.events_heap = [] self.average_firing_rate = {} self.raster_plot_data = [] self.pathParser = CanonicalNameParser() self.report_variables = {} self.output_plots = [] self.number_of_equations = 0 self.number_of_neurones = 0 self.number_of_synapses = 0 self.spike_count = 0 self.minimal_delay = 1.0E10 heapify(self.events_heap) # Create daetoolsPointNeuroneNetwork object and the simulation runtime information self.processSEDMLExperiment(sedml_experiment) # Connect the DataReporter simName = self.name + strftime(" [%d.%m.%Y %H.%M.%S]", localtime()) if not self.datareporter.Connect("", simName): raise RuntimeError('Cannot connect the data reporter') # Set the random number generators of the daetoolsComponentSetup daetoolsComponentSetup._random_number_generators = self.network.randomNumberGenerators # Setup neurones try: self.log.Enabled = False for group_name, group in self.network._groups.iteritems(): for projection_name, projection in group._projections.iteritems( ): if projection.minimal_delay < self.minimal_delay: self.minimal_delay = projection.minimal_delay for population_name, population in group._populations.iteritems( ): print("Creating simulations for: {0}...".format( population_name)) for neurone in population.neurones: simulation = daetoolsPointNeuroneSimulation( neurone, population._parameters, {}) neurone.events_heap = self.events_heap self.simulations.append(simulation) self.number_of_neurones += 1 for (synapse, params) in neurone.incoming_synapses: self.number_of_synapses += synapse.Nitems self.simulations.sort() if self.minimal_delay < self.reportingInterval: raise RuntimeError( 'The minimal delay ({0}s) is greater than the reporting interval ({1}s)' .format(self.minimal_delay, self.reportingInterval)) except: raise finally: self.log.Enabled = True
class daetoolsPointNeuroneNetworkSimulation(object): """ Simulates a network of neurones (specified by a daetoolsPointNeuroneNetworkSimulation object) and produces outputs according to information in a SED-ML experiment object. The daetoolsPointNeuroneNetworkSimulation object can be obtained from the SED-ML experiment object. """ def __init__(self, sedml_experiment): """ :rtype: None :raises: RuntimeError """ self.name = '' self.network = None self.reportingInterval = 0.0 self.timeHorizon = 0.0 self.log = daeLogs.daePythonStdOutLog() self.datareporter = pyDataReporting.daeNoOpDataReporter() #pyDataReporting.daeTCPIPDataReporter() self.simulations = [] self.events_heap = [] self.average_firing_rate = {} self.raster_plot_data = [] self.pathParser = CanonicalNameParser() self.report_variables = {} self.output_plots = [] self.number_of_equations = 0 self.number_of_neurones = 0 self.number_of_synapses = 0 self.spike_count = 0 self.minimal_delay = 1.0E10 heapify(self.events_heap) # Create daetoolsPointNeuroneNetwork object and the simulation runtime information self.processSEDMLExperiment(sedml_experiment) # Connect the DataReporter simName = self.name + strftime(" [%d.%m.%Y %H.%M.%S]", localtime()) if not self.datareporter.Connect("", simName): raise RuntimeError('Cannot connect the data reporter') # Set the random number generators of the daetoolsComponentSetup daetoolsComponentSetup._random_number_generators = self.network.randomNumberGenerators # Setup neurones try: self.log.Enabled = False for group_name, group in self.network._groups.iteritems(): for projection_name, projection in group._projections.iteritems(): if projection.minimal_delay < self.minimal_delay: self.minimal_delay = projection.minimal_delay for population_name, population in group._populations.iteritems(): print("Creating simulations for: {0}...".format(population_name)) for neurone in population.neurones: simulation = daetoolsPointNeuroneSimulation(neurone, population._parameters, {}) neurone.events_heap = self.events_heap self.simulations.append(simulation) self.number_of_neurones += 1 for (synapse, params) in neurone.incoming_synapses: self.number_of_synapses += synapse.Nitems self.simulations.sort() if self.minimal_delay < self.reportingInterval: raise RuntimeError('The minimal delay ({0}s) is greater than the reporting interval ({1}s)'.format(self.minimal_delay, self.reportingInterval)) except: raise finally: self.log.Enabled = True def initializeAndSolveInitial(self): try: self.log.Enabled = False self.number_of_equations = 0 for i, simulation in enumerate(self.simulations): print 'Setting up the neurone {0} out of {1} (total number of equations: {2})...'.format(i+1, self.number_of_neurones, self.number_of_equations), "\r", sys.stdout.flush() simulation.init(self.log, self.datareporter, self.reportingInterval, self.timeHorizon) self.number_of_equations += simulation.daesolver.NumberOfVariables simulation.SolveInitial() simulation.CleanUpSetupData() except: raise finally: print '\n' self.log.Enabled = True # Run the garbage collector to free some memory #print('garbage before collect:\n'.format(gc.garbage)) collected = gc.collect() #print "Garbage collector: collected %d objects." % (collected) #print('garbage after collect:\n'.format(gc.garbage)) def run(self): # First create the reporting times list reporting_times = numpy.arange(self.reportingInterval, self.timeHorizon, self.reportingInterval) prev_time = 0.0 # Iterate over the queue. The (delayed) events will be added to the queue as they are trigerred. for next_time in reporting_times: self.log.Message("Simulating from {0:.5f}s to {1:.5f}s...".format(prev_time, next_time), 0) try: while True: # Get the first item from the heap (t_event, inlet_event_port, target_neurone) = heappop(self.events_heap) # If out of the interval put it back if t_event > next_time: heappush(self.events_heap, (t_event, inlet_event_port, target_neurone)) break #print('{0} --> {1}s (trigger event on {2})'.format(target_neurone.Name, t_event, inlet_event_port.CanonicalName)) # Integrate until next event time and report the data if there is a discontinuity target_neurone.simulation.IntegrateUntilTime(t_event, pyActivity.eDoNotStopAtDiscontinuity, True) # Trigger the event and reinitialize the system inlet_event_port.ReceiveEvent(t_event) target_neurone.simulation.Reinitialize() self.spike_count += 1 except IndexError: pass # Integrate each neurone until the *next_time* is reached and report the data for simulation in self.simulations: #print('{0}........ {1} {2} {3}'.format(simulation.m.Name, # simulation.CurrentTime, # '<' if simulation.CurrentTime < next_time else '=' , # next_time)) if simulation.CurrentTime < next_time: simulation.IntegrateUntilTime(next_time, pyActivity.eDoNotStopAtDiscontinuity, True) simulation.ReportData(next_time) # Set the progress self.log.SetProgress(100.0 * next_time / self.timeHorizon) prev_time = next_time print('Simulation has ended successfuly.') print('Processing the results...') # Finally, process the results (generate 2D plots, raster plots, and other voodoo-mojo stuff) self.processResults() def processSEDMLExperiment(self, sedml_experiment): if len(sedml_experiment.tasks) != 1: raise RuntimeError('The number of SED-ML tasks must be one') sedml_task = sedml_experiment.tasks[0] self.name = sedml_task.simulation.name ul_model = sedml_task.model.getUserLayerModel() self.network = daetoolsPointNeuroneNetwork(ul_model) self.reportingInterval = float(sedml_task.simulation.outputEndTime - sedml_task.simulation.outputStartTime) / (sedml_task.simulation.numberOfPoints - 1) self.timeHorizon = float(sedml_task.simulation.outputEndTime) for data_generator in sedml_experiment.data_generators: for variable in data_generator.variables: if variable.target: try: items = self.pathParser.parse(str(variable.target)) except Exception as e: RuntimeError('Invalid SED-ML variable name: {0}'.format(variable.target)) if len(items) != 3: raise RuntimeError('Invalid SED-ML variable name: {0}'.format(variable.target)) if items[0].Type != pathItem.typeID: raise RuntimeError('Invalid SED-ML variable name: {0}'.format(variable.target)) group = self.network.getGroup(items[0].Name) if items[1].Type != pathItem.typeIndexedID: raise RuntimeError('Invalid SED-ML variable name: {0}'.format(variable.target)) population = group.getPopulation(items[1].Name) neurone = population.getNeurone(items[1].Index) if items[2].Type != pathItem.typeID: raise RuntimeError('Invalid SED-ML variable name: {0}'.format(variable.target)) variable_name = items[2].Name if variable_name in neurone.nineml_aliases: dae_variable = neurone.nineml_aliases[variable_name] elif variable_name in neurone.nineml_variables: dae_variable = neurone.nineml_variables[variable_name] elif variable_name in neurone.nineml_inlet_ports: dae_variable = neurone.nineml_inlet_ports[variable_name] elif variable_name in neurone.nineml_reduce_ports: dae_variable = neurone.nineml_reduce_ports[variable_name] else: raise RuntimeError('Cannot find SED-ML variable: {0}'.format(variable.target)) self.report_variables[variable.target] = dae_variable dae_variable.ReportingOn = True elif variable.symbol: if variable.symbol == 'urn:sedml:symbol:time': self.report_variables['time'] = None else: raise RuntimeError('Unsupported SED-ML symbol: {0}'.format(variable.symbol)) else: raise RuntimeError('Both SED-ML variable symbol and target are None') for output in sedml_experiment.outputs: variable_names = [] x_label = 'Time, s' y_labels = [] x_log = False y_log = False for curve in output.curves: if curve.logX: x_log = True if curve.logY: y_log = True x_dg = curve.xDataReference y_dg = curve.yDataReference if (len(x_dg.variables) != 1) or (not x_dg.variables[0].symbol) or (x_dg.variables[0].symbol != 'urn:sedml:symbol:time'): raise RuntimeError('The number of variables in data referrence: {0} must be one with the symbol = urn:sedml:symbol:time'.format(x_dg.id)) for variable in y_dg.variables: if not variable.target: raise RuntimeError('SED-ML variable: {0} target is invalid'.format(variable.name)) if not variable.target in self.report_variables: raise RuntimeError('SED-ML variable {0} does not exist in the network'.format(variable.name)) variable_names.append(self.report_variables[variable.target].CanonicalName) y_labels.append(variable.name) self.output_plots.append( (output.name, variable_names, x_label, y_labels, x_log, y_log) ) def processResults(self): results_dir = '{0} {1}'.format(self.name, strftime("[%d.%m.%Y %H.%M.%S]", localtime())) os.mkdir(results_dir) print(' Total number of equations: {0:>10d}'.format(self.number_of_equations)) print(' Total number of neurones: {0:>10d}'.format(self.number_of_neurones)) print(' Total number of synapses: {0:>10d}'.format(self.number_of_synapses)) print(' Total number of spikes: {0:>10d}'.format(self.spike_count)) print(' Minimal network delay: {0:>10.6f}s'.format(self.minimal_delay)) # 1. Create a raster plot file (.ras) neurone_index = 0 population_events = {} for group_name, group in self.network._groups.iteritems(): for population_name, population in group._populations.iteritems(): count = 0 events = [] for neurone in population.neurones: event_port = neurone.getOutletEventPort() count += len(event_port.Events) for (t, data) in event_port.Events: self.raster_plot_data.append((t, neurone_index)) events.append((t, neurone_index)) neurone_index += 1 population_events[population_name] = sorted(events) self.average_firing_rate[population_name] = count / (self.timeHorizon * len(population.neurones)) print(' [{0}] average firing rate: {1:.3f} Hz'.format(population_name, self.average_firing_rate[population_name])) self.raster_plot_data.sort() self.createRasterFile(os.path.join(results_dir, 'raster-plot.ras'), self.raster_plot_data, self.number_of_neurones) # 2. Create a raster plot image (.png) pop_times = [] pop_indexes = [] pop_names = [] for i, (population_name, events) in enumerate(population_events.iteritems()): if len(events) > 0: pop_times.append( [item[0] for item in events] ) pop_indexes.append( [item[1] for item in events] ) pop_names.append( population_name ) self.createRasterPlot(os.path.join(results_dir, 'raster-plot.png'), pop_times, pop_indexes, pop_names) # 3. Create 2D plots (.png) for (name, variable_names, x_label, y_labels, x_log, y_log) in self.output_plots: x_values = [] y_values = [] for var_canonical_name in variable_names: for variable in self.datareporter.Process.Variables: if var_canonical_name == variable.Name: x_values.append(variable.TimeValues) y_values.append(variable.Values.reshape(len(variable.Values))) self.create2DPlot(os.path.join(results_dir, '{0}.png'.format(name)), x_values, y_values, x_label, y_labels, x_log, y_log) @staticmethod def createRasterFile(filename, data, n): """ :param filename: string :param data: list of floats :param n: integer :rtype: None :raises: IOError """ f = open(filename, "w") f.write('# size = {0}\n'.format(n)) f.write('# first_index = {0}\n'.format(0)) f.write('# first_id = {0}\n'.format(0)) f.write('# n = {0}\n'.format(len(data))) f.write('# variable = spikes\n') f.write('# last_id = {0}\n'.format(n - 1)) f.write('# dt = {0}\n'.format(0.0)) f.write('# label = {0}\n'.format('spikes')) for t, index in data: f.write('%.14e\t%d\n' % (t, index)) f.close() @staticmethod def createRasterPlot(filename, pop_times, pop_indexes, pop_names): """ :param filename: string :param pop_times: 2D list (list of float lists) :param pop_indexes: 2D list (list of integer lists) :param pop_names: string list :rtype: None :raises: ValueError, IOError """ font = {'family' : 'serif', 'weight' : 'normal', 'size' : 8} matplotlib.rc('font', **font) params = {'axes.labelsize' : 10, 'legend.fontsize': 5, 'text.fontsize' : 8, 'xtick.labelsize': 8, 'ytick.labelsize': 8, 'text.usetex': False} matplotlib.rcParams.update(params) colors = ['red', 'blue', 'green', 'black', 'c', 'm', 'k', 'y'] figure = Figure(figsize=(8, 6)) canvas = FigureCanvas(figure) axes = figure.add_subplot(111) axes.set_xlabel('Time, s') axes.set_ylabel('Neurones') axes.grid(True, linestyle = '-', color = '0.75') i = 0 min_times = 1.0E10 max_times = 0.0 min_indexes = 1E10 max_indexes = 0 for (times, indexes, name) in zip(pop_times, pop_indexes, pop_names): color = colors[i % len(colors)] if len(times) > 0: axes.scatter(times, indexes, label = name, marker = 's', s = 1, color = color) min_times = min(min_times, min(times)) max_times = max(max_times, max(times)) min_indexes = min(min_indexes, min(indexes)) max_indexes = max(max_indexes, max(indexes)) + 1 i += 1 box = axes.get_position() axes.set_position([box.x0, box.y0, box.width * 0.9, box.height]) axes.legend(loc = 'center left', bbox_to_anchor = (1, 0.5), ncol = 1, scatterpoints = 1, fancybox = True) axes.set_xbound(lower = min_times, upper = max_times) axes.set_ybound(lower = min_indexes, upper = max_indexes) canvas.print_figure(filename, dpi = 300) @staticmethod def create2DPlot(filename, x_values, y_values, x_label, y_labels, x_log, y_log): """ :param filename: string :param x_values: 2D list (list of float lists) :param y_values: 2D list (list of float lists) :param x_label: string :param y_labels: string list :param x_log: bool :param y_log: bool :rtype: None :raises: ValueError, IOError """ font = {'family' : 'serif', 'weight' : 'normal', 'size' : 8} matplotlib.rc('font', **font) params = {'axes.labelsize': 9, 'legend.fontsize': 6, 'text.fontsize': 8, 'xtick.labelsize': 8, 'ytick.labelsize': 8, 'text.usetex': False} matplotlib.rcParams.update(params) colors = ['blue', 'red', 'green', 'black', 'c', 'm', 'k', 'y'] figure = Figure(figsize=(8, 6)) canvas = FigureCanvas(figure) axes = figure.add_subplot(111) axes.set_xlabel(x_label) axes.grid(True, linestyle = '-', color = '0.75') i = 0 for (x, y, label) in zip(x_values, y_values, y_labels): color = colors[i % len(colors)] axes.plot(x, y, label = label, color = color, linewidth = 0.5, linestyle = 'solid', marker ='', markersize = 0, markerfacecolor = color, markeredgecolor = color) i += 1 axes.legend(loc = 0, ncol = 1, fancybox = True) if x_log: axes.set_xscale('log') else: axes.set_xscale('linear') if y_log: axes.set_yscale('log') else: axes.set_yscale('linear') canvas.print_figure(filename, dpi = 300) def finalize(self): for simulation in self.simulations: simulation.Finalize()
class daetoolsPointNeuroneNetworkSimulation(object): """ Simulates a network of neurones (specified by a daetoolsPointNeuroneNetworkSimulation object) and produces outputs according to information in a SED-ML experiment object. The daetoolsPointNeuroneNetworkSimulation object can be obtained from the SED-ML experiment object. """ def __init__(self, sedml_experiment): """ :rtype: None :raises: RuntimeError """ self.name = '' self.network = None self.reportingInterval = 0.0 self.timeHorizon = 0.0 self.log = daeLogs.daePythonStdOutLog() self.datareporter = pyDataReporting.daeNoOpDataReporter( ) #pyDataReporting.daeTCPIPDataReporter() self.simulations = [] self.events_heap = [] self.average_firing_rate = {} self.raster_plot_data = [] self.pathParser = CanonicalNameParser() self.report_variables = {} self.output_plots = [] self.number_of_equations = 0 self.number_of_neurones = 0 self.number_of_synapses = 0 self.spike_count = 0 self.minimal_delay = 1.0E10 heapify(self.events_heap) # Create daetoolsPointNeuroneNetwork object and the simulation runtime information self.processSEDMLExperiment(sedml_experiment) # Connect the DataReporter simName = self.name + strftime(" [%d.%m.%Y %H.%M.%S]", localtime()) if not self.datareporter.Connect("", simName): raise RuntimeError('Cannot connect the data reporter') # Set the random number generators of the daetoolsComponentSetup daetoolsComponentSetup._random_number_generators = self.network.randomNumberGenerators # Setup neurones try: self.log.Enabled = False for group_name, group in self.network._groups.iteritems(): for projection_name, projection in group._projections.iteritems( ): if projection.minimal_delay < self.minimal_delay: self.minimal_delay = projection.minimal_delay for population_name, population in group._populations.iteritems( ): print("Creating simulations for: {0}...".format( population_name)) for neurone in population.neurones: simulation = daetoolsPointNeuroneSimulation( neurone, population._parameters, {}) neurone.events_heap = self.events_heap self.simulations.append(simulation) self.number_of_neurones += 1 for (synapse, params) in neurone.incoming_synapses: self.number_of_synapses += synapse.Nitems self.simulations.sort() if self.minimal_delay < self.reportingInterval: raise RuntimeError( 'The minimal delay ({0}s) is greater than the reporting interval ({1}s)' .format(self.minimal_delay, self.reportingInterval)) except: raise finally: self.log.Enabled = True def initializeAndSolveInitial(self): try: self.log.Enabled = False self.number_of_equations = 0 for i, simulation in enumerate(self.simulations): print 'Setting up the neurone {0} out of {1} (total number of equations: {2})...'.format( i + 1, self.number_of_neurones, self.number_of_equations), "\r", sys.stdout.flush() simulation.init(self.log, self.datareporter, self.reportingInterval, self.timeHorizon) self.number_of_equations += simulation.daesolver.NumberOfVariables simulation.SolveInitial() simulation.CleanUpSetupData() except: raise finally: print '\n' self.log.Enabled = True # Run the garbage collector to free some memory #print('garbage before collect:\n'.format(gc.garbage)) collected = gc.collect() #print "Garbage collector: collected %d objects." % (collected) #print('garbage after collect:\n'.format(gc.garbage)) def run(self): # First create the reporting times list reporting_times = numpy.arange(self.reportingInterval, self.timeHorizon, self.reportingInterval) prev_time = 0.0 # Iterate over the queue. The (delayed) events will be added to the queue as they are trigerred. for next_time in reporting_times: self.log.Message( "Simulating from {0:.5f}s to {1:.5f}s...".format( prev_time, next_time), 0) try: while True: # Get the first item from the heap (t_event, inlet_event_port, target_neurone) = heappop(self.events_heap) # If out of the interval put it back if t_event > next_time: heappush(self.events_heap, (t_event, inlet_event_port, target_neurone)) break #print('{0} --> {1}s (trigger event on {2})'.format(target_neurone.Name, t_event, inlet_event_port.CanonicalName)) # Integrate until next event time and report the data if there is a discontinuity target_neurone.simulation.IntegrateUntilTime( t_event, pyActivity.eDoNotStopAtDiscontinuity, True) # Trigger the event and reinitialize the system inlet_event_port.ReceiveEvent(t_event) target_neurone.simulation.Reinitialize() self.spike_count += 1 except IndexError: pass # Integrate each neurone until the *next_time* is reached and report the data for simulation in self.simulations: #print('{0}........ {1} {2} {3}'.format(simulation.m.Name, # simulation.CurrentTime, # '<' if simulation.CurrentTime < next_time else '=' , # next_time)) if simulation.CurrentTime < next_time: simulation.IntegrateUntilTime( next_time, pyActivity.eDoNotStopAtDiscontinuity, True) simulation.ReportData(next_time) # Set the progress self.log.SetProgress(100.0 * next_time / self.timeHorizon) prev_time = next_time print('Simulation has ended successfuly.') print('Processing the results...') # Finally, process the results (generate 2D plots, raster plots, and other voodoo-mojo stuff) self.processResults() def processSEDMLExperiment(self, sedml_experiment): if len(sedml_experiment.tasks) != 1: raise RuntimeError('The number of SED-ML tasks must be one') sedml_task = sedml_experiment.tasks[0] self.name = sedml_task.simulation.name ul_model = sedml_task.model.getUserLayerModel() self.network = daetoolsPointNeuroneNetwork(ul_model) self.reportingInterval = float( sedml_task.simulation.outputEndTime - sedml_task.simulation.outputStartTime) / ( sedml_task.simulation.numberOfPoints - 1) self.timeHorizon = float(sedml_task.simulation.outputEndTime) for data_generator in sedml_experiment.data_generators: for variable in data_generator.variables: if variable.target: try: items = self.pathParser.parse(str(variable.target)) except Exception as e: RuntimeError( 'Invalid SED-ML variable name: {0}'.format( variable.target)) if len(items) != 3: raise RuntimeError( 'Invalid SED-ML variable name: {0}'.format( variable.target)) if items[0].Type != pathItem.typeID: raise RuntimeError( 'Invalid SED-ML variable name: {0}'.format( variable.target)) group = self.network.getGroup(items[0].Name) if items[1].Type != pathItem.typeIndexedID: raise RuntimeError( 'Invalid SED-ML variable name: {0}'.format( variable.target)) population = group.getPopulation(items[1].Name) neurone = population.getNeurone(items[1].Index) if items[2].Type != pathItem.typeID: raise RuntimeError( 'Invalid SED-ML variable name: {0}'.format( variable.target)) variable_name = items[2].Name if variable_name in neurone.nineml_aliases: dae_variable = neurone.nineml_aliases[variable_name] elif variable_name in neurone.nineml_variables: dae_variable = neurone.nineml_variables[variable_name] elif variable_name in neurone.nineml_inlet_ports: dae_variable = neurone.nineml_inlet_ports[ variable_name] elif variable_name in neurone.nineml_reduce_ports: dae_variable = neurone.nineml_reduce_ports[ variable_name] else: raise RuntimeError( 'Cannot find SED-ML variable: {0}'.format( variable.target)) self.report_variables[variable.target] = dae_variable dae_variable.ReportingOn = True elif variable.symbol: if variable.symbol == 'urn:sedml:symbol:time': self.report_variables['time'] = None else: raise RuntimeError( 'Unsupported SED-ML symbol: {0}'.format( variable.symbol)) else: raise RuntimeError( 'Both SED-ML variable symbol and target are None') for output in sedml_experiment.outputs: variable_names = [] x_label = 'Time, s' y_labels = [] x_log = False y_log = False for curve in output.curves: if curve.logX: x_log = True if curve.logY: y_log = True x_dg = curve.xDataReference y_dg = curve.yDataReference if (len(x_dg.variables) != 1 ) or (not x_dg.variables[0].symbol) or ( x_dg.variables[0].symbol != 'urn:sedml:symbol:time'): raise RuntimeError( 'The number of variables in data referrence: {0} must be one with the symbol = urn:sedml:symbol:time' .format(x_dg.id)) for variable in y_dg.variables: if not variable.target: raise RuntimeError( 'SED-ML variable: {0} target is invalid'.format( variable.name)) if not variable.target in self.report_variables: raise RuntimeError( 'SED-ML variable {0} does not exist in the network' .format(variable.name)) variable_names.append( self.report_variables[variable.target].CanonicalName) y_labels.append(variable.name) self.output_plots.append( (output.name, variable_names, x_label, y_labels, x_log, y_log)) def processResults(self): results_dir = '{0} {1}'.format( self.name, strftime("[%d.%m.%Y %H.%M.%S]", localtime())) os.mkdir(results_dir) print(' Total number of equations: {0:>10d}'.format( self.number_of_equations)) print(' Total number of neurones: {0:>10d}'.format( self.number_of_neurones)) print(' Total number of synapses: {0:>10d}'.format( self.number_of_synapses)) print(' Total number of spikes: {0:>10d}'.format(self.spike_count)) print(' Minimal network delay: {0:>10.6f}s'.format( self.minimal_delay)) # 1. Create a raster plot file (.ras) neurone_index = 0 population_events = {} for group_name, group in self.network._groups.iteritems(): for population_name, population in group._populations.iteritems(): count = 0 events = [] for neurone in population.neurones: event_port = neurone.getOutletEventPort() count += len(event_port.Events) for (t, data) in event_port.Events: self.raster_plot_data.append((t, neurone_index)) events.append((t, neurone_index)) neurone_index += 1 population_events[population_name] = sorted(events) self.average_firing_rate[population_name] = count / ( self.timeHorizon * len(population.neurones)) print(' [{0}] average firing rate: {1:.3f} Hz'.format( population_name, self.average_firing_rate[population_name])) self.raster_plot_data.sort() self.createRasterFile(os.path.join(results_dir, 'raster-plot.ras'), self.raster_plot_data, self.number_of_neurones) # 2. Create a raster plot image (.png) pop_times = [] pop_indexes = [] pop_names = [] for i, (population_name, events) in enumerate(population_events.iteritems()): if len(events) > 0: pop_times.append([item[0] for item in events]) pop_indexes.append([item[1] for item in events]) pop_names.append(population_name) self.createRasterPlot(os.path.join(results_dir, 'raster-plot.png'), pop_times, pop_indexes, pop_names) # 3. Create 2D plots (.png) for (name, variable_names, x_label, y_labels, x_log, y_log) in self.output_plots: x_values = [] y_values = [] for var_canonical_name in variable_names: for variable in self.datareporter.Process.Variables: if var_canonical_name == variable.Name: x_values.append(variable.TimeValues) y_values.append( variable.Values.reshape(len(variable.Values))) self.create2DPlot( os.path.join(results_dir, '{0}.png'.format(name)), x_values, y_values, x_label, y_labels, x_log, y_log) @staticmethod def createRasterFile(filename, data, n): """ :param filename: string :param data: list of floats :param n: integer :rtype: None :raises: IOError """ f = open(filename, "w") f.write('# size = {0}\n'.format(n)) f.write('# first_index = {0}\n'.format(0)) f.write('# first_id = {0}\n'.format(0)) f.write('# n = {0}\n'.format(len(data))) f.write('# variable = spikes\n') f.write('# last_id = {0}\n'.format(n - 1)) f.write('# dt = {0}\n'.format(0.0)) f.write('# label = {0}\n'.format('spikes')) for t, index in data: f.write('%.14e\t%d\n' % (t, index)) f.close() @staticmethod def createRasterPlot(filename, pop_times, pop_indexes, pop_names): """ :param filename: string :param pop_times: 2D list (list of float lists) :param pop_indexes: 2D list (list of integer lists) :param pop_names: string list :rtype: None :raises: ValueError, IOError """ font = {'family': 'serif', 'weight': 'normal', 'size': 8} matplotlib.rc('font', **font) params = { 'axes.labelsize': 10, 'legend.fontsize': 5, 'text.fontsize': 8, 'xtick.labelsize': 8, 'ytick.labelsize': 8, 'text.usetex': False } matplotlib.rcParams.update(params) colors = ['red', 'blue', 'green', 'black', 'c', 'm', 'k', 'y'] figure = Figure(figsize=(8, 6)) canvas = FigureCanvas(figure) axes = figure.add_subplot(111) axes.set_xlabel('Time, s') axes.set_ylabel('Neurones') axes.grid(True, linestyle='-', color='0.75') i = 0 min_times = 1.0E10 max_times = 0.0 min_indexes = 1E10 max_indexes = 0 for (times, indexes, name) in zip(pop_times, pop_indexes, pop_names): color = colors[i % len(colors)] if len(times) > 0: axes.scatter(times, indexes, label=name, marker='s', s=1, color=color) min_times = min(min_times, min(times)) max_times = max(max_times, max(times)) min_indexes = min(min_indexes, min(indexes)) max_indexes = max(max_indexes, max(indexes)) + 1 i += 1 box = axes.get_position() axes.set_position([box.x0, box.y0, box.width * 0.9, box.height]) axes.legend(loc='center left', bbox_to_anchor=(1, 0.5), ncol=1, scatterpoints=1, fancybox=True) axes.set_xbound(lower=min_times, upper=max_times) axes.set_ybound(lower=min_indexes, upper=max_indexes) canvas.print_figure(filename, dpi=300) @staticmethod def create2DPlot(filename, x_values, y_values, x_label, y_labels, x_log, y_log): """ :param filename: string :param x_values: 2D list (list of float lists) :param y_values: 2D list (list of float lists) :param x_label: string :param y_labels: string list :param x_log: bool :param y_log: bool :rtype: None :raises: ValueError, IOError """ font = {'family': 'serif', 'weight': 'normal', 'size': 8} matplotlib.rc('font', **font) params = { 'axes.labelsize': 9, 'legend.fontsize': 6, 'text.fontsize': 8, 'xtick.labelsize': 8, 'ytick.labelsize': 8, 'text.usetex': False } matplotlib.rcParams.update(params) colors = ['blue', 'red', 'green', 'black', 'c', 'm', 'k', 'y'] figure = Figure(figsize=(8, 6)) canvas = FigureCanvas(figure) axes = figure.add_subplot(111) axes.set_xlabel(x_label) axes.grid(True, linestyle='-', color='0.75') i = 0 for (x, y, label) in zip(x_values, y_values, y_labels): color = colors[i % len(colors)] axes.plot(x, y, label=label, color=color, linewidth=0.5, linestyle='solid', marker='', markersize=0, markerfacecolor=color, markeredgecolor=color) i += 1 axes.legend(loc=0, ncol=1, fancybox=True) if x_log: axes.set_xscale('log') else: axes.set_xscale('linear') if y_log: axes.set_yscale('log') else: axes.set_yscale('linear') canvas.print_figure(filename, dpi=300) def finalize(self): for simulation in self.simulations: simulation.Finalize()