Пример #1
0
 def compile_source_files(self, compile_dir, component_name):
     # Run configure script, make and make install
     os.chdir(compile_dir)
     logger.info("Compiling NEST model class in '{}' directory.".format(
         compile_dir))
     stdout, stderr = self.run_command(
         ['make', '-j{}'.format(self._build_cores)],
         fail_msg=("Compilation of '{}' NEST module failed (see compile "
                   "directory '{}'):\n\n {{}}".format(
                       component_name, compile_dir)))
     if re.search(r'error:', stderr):  # Ignores warnings
         raise Pype9BuildError(
             "Compilation of '{}' NEST module directory failed:\n\n{}\n{}".
             format(compile_dir, stdout, stderr))
     logger.debug("make '{}':\nstdout:\n{}stderr:\n{}\n".format(
         compile_dir, stdout, stderr))
     stdout, stderr = self.run_command(
         ['make', 'install'],
         fail_msg=("Installation of '{}' NEST module failed (see compile "
                   "directory '{}'):\n\n {{}}".format(
                       component_name, compile_dir)))
     if stderr:
         raise Pype9BuildError(
             "Installation of '{}' NEST module directory failed:\n\n{}\n{}".
             format(compile_dir, stdout, stderr))
     logger.debug("make install'{}':\nstdout:\n{}stderr:\n{}\n".format(
         compile_dir, stdout, stderr))
     logger.info("Compilation of '{}' NEST module completed "
                 "successfully".format(component_name))
Пример #2
0
 def _set_seeds(self):
     """
     Generate seeds for each process/thread
     """
     seed = self.gen_seed() if self._base_seed is None else self._base_seed
     seed_gen_rng = numpy.random.RandomState(seed)
     if self._base_properties_seed is None:
         logger.info("Using {} as seed for both properties and dynamics of "
                     "{} simulation".format(seed, self.name))
         prop_seed_gen_rng = seed_gen_rng
     else:
         logger.info("Using {} as seed for properties and {} as seed for "
                     "dynamics of {} simulation".format(
                         self._base_properties_seed, seed, self.name))
         prop_seed_gen_rng = numpy.random.RandomState(
             self._base_properties_seed)
     # Properties seeds are drawn before dynamics_seeds
     self._properties_seeds = numpy.asarray(prop_seed_gen_rng.uniform(
         low=0, high=self.max_seed, size=self.num_threads()),
                                            dtype=int)
     self._dynamics_seeds = numpy.asarray(seed_gen_rng.uniform(
         low=0, high=self.max_seed, size=self.num_threads()),
                                          dtype=int)
     self._global_seed = int(
         seed_gen_rng.uniform(
             low=0,
             high=self.max_seed,
             size=1,
         ))
     self._properties_rng = NumpyRNG(int(self.properties_seed))
Пример #3
0
 def _set_seeds(self):
     """
     Generate seeds for each process/thread
     """
     seed = self.gen_seed() if self._base_seed is None else self._base_seed
     seed_gen_rng = numpy.random.RandomState(seed)
     if self._base_properties_seed is None:
         logger.info("Using {} as seed for both properties and dynamics of "
                     "{} simulation".format(seed, self.name))
         prop_seed_gen_rng = seed_gen_rng
     else:
         logger.info("Using {} as seed for properties and {} as seed for "
                     "dynamics of {} simulation"
                     .format(self._base_properties_seed, seed, self.name))
         prop_seed_gen_rng = numpy.random.RandomState(
             self._base_properties_seed)
     # Properties seeds are drawn before dynamics_seeds
     self._properties_seeds = numpy.asarray(
         prop_seed_gen_rng.uniform(low=0, high=self.max_seed,
                                     size=self.num_threads()), dtype=int)
     self._dynamics_seeds = numpy.asarray(
         seed_gen_rng.uniform(low=0, high=self.max_seed,
                              size=self.num_threads()), dtype=int)
     self._global_seed = int(seed_gen_rng.uniform(low=0, high=self.max_seed,
                                                  size=1,))
     self._properties_rng = NumpyRNG(int(self.properties_seed))
Пример #4
0
 def compile_source_files(self, compile_dir, component_name):
     # Run configure script, make and make install
     os.chdir(compile_dir)
     logger.info("Compiling NEST model class in '{}' directory."
                 .format(compile_dir))
     stdout, stderr = self.run_command(
         ['make',
          '-j{}'.format(self._build_cores)],
         fail_msg=("Compilation of '{}' NEST module failed (see compile "
                   "directory '{}'):\n\n {{}}".format(component_name,
                                                      compile_dir)))
     if re.search(r'error:', stderr):  # Ignores warnings
         raise Pype9BuildError(
             "Compilation of '{}' NEST module directory failed:\n\n{}\n{}"
             .format(compile_dir, stdout, stderr))
     logger.debug("make '{}':\nstdout:\n{}stderr:\n{}\n"
                  .format(compile_dir, stdout, stderr))
     stdout, stderr = self.run_command(['make',
                                        'install'], fail_msg=(
         "Installation of '{}' NEST module failed (see compile "
         "directory '{}'):\n\n {{}}"
         .format(component_name, compile_dir)))
     if stderr:
         raise Pype9BuildError(
             "Installation of '{}' NEST module directory failed:\n\n{}\n{}"
             .format(compile_dir, stdout, stderr))
     logger.debug("make install'{}':\nstdout:\n{}stderr:\n{}\n"
                  .format(compile_dir, stdout, stderr))
     logger.info("Compilation of '{}' NEST module completed "
                 "successfully".format(component_name))
Пример #5
0
 def configure_build_files(self, name, src_dir, compile_dir, install_dir,
                           **kwargs):  # @UnusedVariable
     # Generate Makefile if it is not present
     if not path.exists(path.join(compile_dir, 'Makefile')):
         if not path.exists(compile_dir):
             os.mkdir(compile_dir)
         logger.info("Configuring build files in '{}' directory"
                     .format(compile_dir))
         orig_dir = os.getcwd()
         config_args = {'name': name, 'src_dir': src_dir,
                        # NB: ODE solver currently ignored
                        # 'ode_solver': kwargs.get('ode_solver',
                        #                          self.ODE_SOLVER_DEFAULT),
                        'version': pype9.__version__,
                        'executable': sys.executable}
         self.render_to_file('CMakeLists.txt.tmpl', config_args,
                              'CMakeLists.txt', src_dir)
         os.chdir(compile_dir)
         stdout, stderr = self.run_command(
             ['cmake',
              '-Dwith-nest={}'.format(self.nest_config),
              '-DCMAKE_INSTALL_PREFIX={}'.format(install_dir), src_dir],
             fail_msg=(
                 "Cmake of '{}' NEST module failed (see src "
                 "directory '{}'):\n\n {{}}".format(name, src_dir)))
         if stderr:
             raise Pype9BuildError(
                 "Configure of '{}' NEST module failed (see src "
                 "directory '{}'):\n\n{}\n{}"
                 .format(name or src_dir, src_dir, stdout, stderr))
             logger.debug("cmake '{}':\nstdout:\n{}stderr:\n{}\n"
                          .format(compile_dir, stdout, stderr))
         os.chdir(orig_dir)
Пример #6
0
def run(argv):
    args = argparser().parse_args(argv)

    doc = args.in_file.clone()
    kwargs = {}
    if args.nineml_version is not None:
        kwargs['version'] = args.nineml_version
    doc.write(args.out_file, **kwargs)
    logger.info("Converted '{}' to '{}'".format(args.in_file, args.out_file))
Пример #7
0
def run(argv):
    args = argparser().parse_args(argv)

    doc = args.in_file.clone()
    kwargs = {}
    if args.nineml_version is not None:
        kwargs['version'] = args.nineml_version
    doc.write(args.out_file, **kwargs)
    logger.info("Converted '{}' to '{}'".format(args.in_file, args.out_file))
Пример #8
0
    def _init_matrices_and_cache(cls, basis, compounds):
        """
        Creates matrix corresponding to unit basis and loads cache of
        previously calculated mappings from dimensions onto this basis.
        """
        assert all(u.offset == 0 for u in basis), (
            "Non-zero offsets found in basis units")
        assert any(u.dimension == un.time for u in basis), (
            "No pure time dimension found in basis units")
        # Get matrix of basis unit dimensions
        cls._A = array([list(b.dimension) for b in basis]).T
        logger.info("Initialising unit conversion cache")
        cls._cache = cls._init_cache(basis, compounds)

        # The lengths in terms of SI dimension bases of each of the unit
        # basis compounds.
        si_lengths = [sum(abs(si) for si in d.dimension) for d in basis]
        return cls._A, cls._cache, si_lengths
Пример #9
0
 def configure_build_files(self, name, src_dir, compile_dir, install_dir,
                           **kwargs):  # @UnusedVariable
     # Generate Makefile if it is not present
     if not path.exists(path.join(compile_dir, 'Makefile')):
         if not path.exists(compile_dir):
             os.mkdir(compile_dir)
         logger.info("Configuring build files in '{}' directory".format(
             compile_dir))
         orig_dir = os.getcwd()
         config_args = {
             'name': name,
             'src_dir': src_dir,
             # NB: ODE solver currently ignored
             # 'ode_solver': kwargs.get('ode_solver',
             #                          self.ODE_SOLVER_DEFAULT),
             'version': pype9.__version__,
             'executable': sys.executable
         }
         self.render_to_file('CMakeLists.txt.tmpl', config_args,
                             'CMakeLists.txt', src_dir)
         os.chdir(compile_dir)
         stdout, stderr = self.run_command(
             [
                 'cmake', '-Dwith-nest={}'.format(self.nest_config),
                 '-DCMAKE_INSTALL_PREFIX={}'.format(install_dir), src_dir
             ],
             fail_msg=("Cmake of '{}' NEST module failed (see src "
                       "directory '{}'):\n\n {{}}".format(name, src_dir)))
         if stderr:
             raise Pype9BuildError(
                 "Configure of '{}' NEST module failed (see src "
                 "directory '{}'):\n\n{}\n{}".format(
                     name or src_dir, src_dir, stdout, stderr))
             logger.debug("cmake '{}':\nstdout:\n{}stderr:\n{}\n".format(
                 compile_dir, stdout, stderr))
         os.chdir(orig_dir)
Пример #10
0
from pype9.utils.logging import logger  # @IgnorePep8

OUT_PATH = os.path.join(BASE_BUILD_DIR, 'examples')
FIG_PATH = os.path.join(OUT_PATH, 'fig')
PACKAGE_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..',
                                            '..'))
EXAMPLES_PATH = os.path.join(PACKAGE_ROOT, 'examples')
SCRIPTS_SRC_PATH = os.path.join(PACKAGE_ROOT, 'scripts')
SCRIPTS_DEST_PATH = os.path.join(OUT_PATH, 'scripts')

api_path = os.path.join(EXAMPLES_PATH, 'api')
bash_path = os.path.join(EXAMPLES_PATH, 'bash')

# Import example run methods
sys.path.insert(0, api_path)
logger.info("sys.path: {}".format(sys.path))
logger.info(os.listdir(api_path))
from brunel import run as brunel_run  # @UnresolvedImport @IgnorePep8
from izhikevich import run as izhikevich_run  # @UnresolvedImport @IgnorePep8
from liaf_with_alpha import run as liaf_with_alpha_run  # @UnresolvedImport @IgnorePep8
from simple_hh import run as simple_hh_run  # @UnresolvedImport @IgnorePep8
sys.path.pop(0)


class TestExamples(TestCase):

    def setUp(self):
        try:
            shutil.rmtree(OUT_PATH)
        except OSError as e:
            if e.errno != errno.ENOENT:  # Ignore if it is missing
Пример #11
0
def plot(seg,
         dims=(20, 16),
         resolution=300,
         save=None,
         show=True,
         regime_alpha=0.05,
         regime_linestyle=':',
         title=None):
    if title is None:
        title = 'PyPe9 Simulation Output'
    num_subplots = bool(seg.analogsignals) + bool(seg.spiketrains)
    fig, axes = plt.subplots(num_subplots, 1)
    fig.suptitle(title)
    fig.set_figwidth(dims[0])
    fig.set_figheight(dims[1])
    # Set the dimension of the figure
    plt_name = seg.name + ' ' if seg.name else ''
    if seg.spiketrains:
        spike_times = []
        ids = []
        for i, spiketrain in enumerate(seg.spiketrains):
            spike_times.extend(spiketrain)
            ids.extend([i] * len(spiketrain))
        plt.sca(axes[0] if num_subplots > 1 else axes)
        plt.scatter(spike_times, ids)
        plt.xlim((seg.spiketrains[0].t_start, seg.spiketrains[0].t_stop))
        plt.ylim((-1, len(seg.spiketrains)))
        plt.xlabel('Times (ms)')
        plt.ylabel('Cell Indices')
        plt.title("{}Spike Trains".format(plt_name), fontsize=12)
    if seg.analogsignals:
        legend = []
        plt.sca(axes[-1] if num_subplots > 1 else axes)
        units = set(s.units.dimensionality.string for s in seg.analogsignals)
        # Plot signals
        for i, signal in enumerate(seg.analogsignals):
            un_str = (signal.units.dimensionality.string
                      if len(units) > 1 else '')
            label = signal.name + un_str if signal.name else str(i)
            line, = plt.plot(signal.times, signal, label=label)
            legend.append(line)
        # Plot regime epochs (if present)
        for epochs in seg.epochs:
            # Generate colours for each regime
            labels = sort_epochs_by_duration(epochs)
            # Make the 'mode' regime transparent
            label_colours = OrderedDict([(labels[0], None)])
            for label in labels[1:]:
                label_colours[label] = plt.gca()._get_lines.get_next_color()
            for label, start, duration in zip(epochs.labels, epochs.times,
                                              epochs.durations):
                if label_colours[label] is not None:
                    end = start + duration
                    plt.axvspan(start,
                                end,
                                facecolor=label_colours[label],
                                alpha=regime_alpha)
                    plt.axvline(start,
                                linestyle=regime_linestyle,
                                color='gray',
                                linewidth=0.5)
                    plt.axvline(end,
                                linestyle=regime_linestyle,
                                color='gray',
                                linewidth=0.5)
            for label, colour in label_colours.items():
                if colour is None:
                    colour = 'white'
                legend.append(
                    mpatches.Patch(facecolor=colour,
                                   edgecolor='grey',
                                   label=label + ' regime',
                                   linewidth=0.5,
                                   linestyle=regime_linestyle))
        plt.xlim((seg.analogsignals[0].t_start, seg.analogsignals[0].t_stop))
        plt.xlabel('Time (ms)')
        un_str = (' ({})'.format(next(iter(units))) if len(units) == 1 else '')
        plt.ylabel('Analog signals{}'.format(un_str))
        plt.title("{}Analog Signals".format(plt_name), fontsize=12)
        plt.legend(handles=legend)
    if save is not None:
        fig.savefig(save, dpi=resolution)
        logger.info("Saved{} figure to '{}'".format(plt_name, save))
    if show:
        plt.show()
Пример #12
0
def run(argv):
    """
    Runs the simulation script from the provided arguments
    """
    import nineml
    from pype9.exceptions import Pype9UsageError
    import neo.io

    args = argparser().parse_args(argv)

    time = args.time * un.ms
    timestep = args.timestep * un.ms

    if args.simulator == 'neuron':
        from pype9.simulate.neuron import Network, CellMetaClass, Simulation  # @UnusedImport @IgnorePep8
    elif args.simulator == 'nest':
        from pype9.simulate.nest import Network, CellMetaClass, Simulation  # @Reimport @IgnorePep8
    else:
        assert False

    if not args.record:
        raise Pype9UsageError(
            "No recorders set, please specify at least one with the '--record'"
            " option")

    min_delay = (float(args.min_delay[0]) *
                    parse_units(args.min_delay[1])
                    if args.min_delay is not None else 1.0 * un.ms)

    device_delay = (float(args.device_delay[0]) *
                    parse_units(args.device_delay[1])
                    if args.device_delay is not None else None)

    # Parse record specs
    record_specs = []
    for rec in args.record:
        if len(rec) == 4:
            rec_t_start = pq.Quantity(float(rec[2]), rec[3])
        elif len(rec) == 2:
            rec_t_start = None
        else:
            raise Pype9UsageError(
                "Record options can be passed either have 2 or 4 (provided {})"
                ": PORT/STATE-VARIABLE FILENAME [T_START T_START_UNITS]")
        record_specs.append(RecordSpec(rec[0], rec[1], rec_t_start))

    # Check for clashing record paths
    record_paths = [r.fname for r in record_specs]
    for pth in record_paths:
        if record_paths.count(pth) > 1:
            raise Pype9UsageError(
                "Duplicate record paths '{}' given to separate '--record' "
                "options".format(pth))

    # For convenience
    model = args.model

    if isinstance(model, nineml.Network) and not model.num_projections:
        raise Pype9UsageError(
            "Provided network model '{}' (may have been implicitly created "
            "from complete document) does not contain any projections"
            .format(model))

    if isinstance(model, nineml.Network):
        with Simulation(dt=timestep, seed=args.seed,
                        properties_seed=args.properties_seed,
                        device_delay=device_delay,
                        **model.delay_limits()) as sim:
            # Construct the network
            logger.info("Constructing network")
            network = Network(model, build_mode=args.build_mode,
                              build_base_dir=args.build_dir)
            logger.info("Finished constructing the '{}' network"
                        .format(model.name))
            for rspec in record_specs:
                pop_name, port_name = rspec.port.split('.')
                network.component_array(pop_name).record(port_name)
            logger.info("Running the simulation")
            sim.run(time)
        logger.info("Writing recorded data to file")
        for rspec in record_specs:
            pop_name, port_name = rspec.port.split('.')
            pop = network.component_array(pop_name)
            neo.PickleIO(rspec.fname).write(pop.recording(
                port_name, t_start=rspec.t_start))
    else:
        assert isinstance(model, (nineml.DynamicsProperties, nineml.Dynamics))
        # Override properties passed as options
        if args.prop:
            props_dict = dict((parm, float(val) * parse_units(unts))
                              for parm, val, unts in args.prop)
            props = nineml.DynamicsProperties(
                model.name + '_props', model, props_dict)
            component_class = model
        elif isinstance(model, nineml.DynamicsProperties):
            props = model
            component_class = model.component_class
        else:
            raise Pype9UsageError(
                "Specified model {} is not a dynamics properties object and "
                "no properties supplied to simulate command via --prop option"
                .format(model))
        # Get the initial state
        init_state = dict((sv, float(val) * parse_units(units))
                          for sv, val, units in args.init_value)
        # Get the init_regime
        init_regime = args.init_regime
        if init_regime is None:
            if component_class.num_regimes == 1:
                # If there is only one regime it doesn't need to be specified
                init_regime = next(component_class.regimes).name
            else:
                raise Pype9UsageError(
                    "Need to specify initial regime as dynamics has more than "
                    "one '{}'".format("', '".join(
                        r.name for r in component_class.regimes)))
        # FIXME: A bit of a hack until better detection of input currents is
        #        implemented in neuron code gen.
        external_currents = []
        for port_name, _ in args.play:
            if component_class.port(port_name).dimension == un.current:
                external_currents.append(port_name)
        # Build cell class
        Cell = CellMetaClass(component_class,
                             build_mode=args.build_mode,
                             external_currents=external_currents,
                             build_version=args.build_version,
                             build_base_dir=args.build_dir)
        record_regime = False
        with Simulation(dt=timestep, seed=args.seed,
                        min_delay=min_delay,
                        device_delay=device_delay,
                        build_base_dir=args.build_dir) as sim:
            # Create cell
            cell = Cell(props, regime_=init_regime, **init_state)
            # Play inputs
            for port_name, fname in args.play:
                port = component_class.receive_port(port_name)
                seg = neo.io.PickleIO(filename=fname).read()[0]
                if port.communicates == 'event':
                    signal = seg.spiketrains[0]
                else:
                    signal = seg.analogsignals[0]
                logger.info("Playing signal (t_start: {}, t_stop: {}, dt: {}) "
                            "into port '{}"
                            .format(signal.t_start, signal.t_stop,
                                    signal.sampling_period, port_name))
                # Input is an event train or analog signal
                cell.play(port_name, signal)
            # Set up recorders
            for rspec in record_specs:
                if (component_class.num_regimes > 1 and component_class.port(
                        rspec.port).communicates == 'analog'):
                    record_regime = True
                cell.record(rspec.port, t_start=rspec.t_start)
            if record_regime:
                cell.record_regime()
            # Run simulation
            sim.run(time)
        # Collect data into Neo Segments
        fnames = set(r.fname for r in record_specs)
        data_segs = {}
        for fname in fnames:
            data_segs[fname] = neo.Segment(
                description="Simulation of '{}' cell".format(model.name))
        for rspec in record_specs:
            data = cell.recording(rspec.port, t_start=rspec.t_start)
            if isinstance(data, neo.AnalogSignal):
                data_segs[rspec.fname].analogsignals.append(data)
            else:
                data_segs[rspec.fname].spiketrains.append(data)
            if record_regime:
                data_segs[rspec.fname].epochs.append(cell.regime_epochs())
        # Write data to file
        for fname, data_seg in data_segs.items():
            neo.io.PickleIO(fname).write(data_seg)
    logger.info("Finished simulation of '{}' for {}".format(model.name, time))
Пример #13
0
    def generate(self, component_class, build_mode='lazy', url=None, **kwargs):
        """
        Generates and builds the required simulator-specific files for a given
        NineML cell class

        Parameters
        ----------
        component_class : nineml.Dynamics
            9ML Dynamics object
        name : str
            Name of the generated cell class
        install_dir : str
            Path to the directory where the NMODL files
            will be generated and compiled
        build_mode : str
            Available build options:
                lazy - only build if files are modified
                force - always generate and build
                purge - remove all config files, generate and rebuild
                require - require built binaries are present
                build_only - build and then quit
                generate_only - generate src and then quit
                recompile - don't generate src but compile
        build_version : str
            A suffix appended to the cell build name to distinguish
            it from other code generated from the component class
        url : str
            The URL where the component class is stored (used to form the
            build path)
        kwargs : dict
            A dictionary of (potentially simulator- specific) template
            arguments
        """
        # Save original working directory to reinstate it afterwards (just to
        # be polite)
        name = component_class.name
        orig_dir = os.getcwd()
        if url is None:
            url = component_class.url
        # Calculate compile directory path within build directory
        src_dir = self.get_source_dir(name, url)
        compile_dir = self.get_compile_dir(name, url)
        install_dir = self.get_install_dir(name, url)
        # Path of the build component class
        built_comp_class_pth = os.path.join(src_dir, self._BUILT_COMP_CLASS)
        # Determine whether the installation needs rebuilding or whether there
        # is an existing library module to use.
        if build_mode == 'purge':
            remove_ignore_missing(src_dir)
            remove_ignore_missing(install_dir)
            remove_ignore_missing(compile_dir)
            generate_source = compile_source = True
        elif build_mode in ('force', 'build_only'):  # Force build
            generate_source = compile_source = True
        elif build_mode == 'require':  # Just check that prebuild is present
            generate_source = compile_source = False
        elif build_mode == 'generate_only':  # Only generate
            generate_source = True
            compile_source = False
        elif build_mode == 'lazy':  # Generate if source has been modified
            compile_source = True
            if not os.path.exists(built_comp_class_pth):
                generate_source = True
            else:
                try:
                    built_component_class = read(built_comp_class_pth)[name]
                    if built_component_class.equals(component_class,
                                                    annotations_ns=[PYPE9_NS]):
                        generate_source = False
                        logger.info("Found existing source in '{}' directory, "
                                    "code generation skipped (set 'build_mode'"
                                    " argument to 'force' or 'build_only' to "
                                    "enforce regeneration)".format(src_dir))
                    else:
                        generate_source = True
                        logger.info("Found existing source in '{}' directory, "
                                    "but the component classes differ so "
                                    "regenerating sources".format(src_dir))
                except (NineMLNameError, NineMLSerializationError):
                    generate_source = True
                    logger.info("Found existing source in '{}' directory, "
                                "but could not find '{}' component class so "
                                "regenerating sources".format(name, src_dir))
        # Check if required directories are present depending on build_mode
        elif build_mode == 'require':
            if not os.path.exists(install_dir):
                raise Pype9BuildError(
                    "Prebuilt installation directory '{}' is not "
                    "present, and is required for  'require' build option".
                    format(install_dir))
        else:
            raise Pype9BuildError(
                "Unrecognised build option '{}', must be one of ('{}')".format(
                    build_mode, "', '".join(self.BUILD_MODE_OPTIONS)))
        # Generate source files from NineML code
        if generate_source:
            self.clean_src_dir(src_dir, name)
            self.generate_source_files(name=name,
                                       component_class=component_class,
                                       src_dir=src_dir,
                                       compile_dir=compile_dir,
                                       install_dir=install_dir,
                                       **kwargs)
            component_class.write(built_comp_class_pth,
                                  preserve_order=True,
                                  version=2.0)
        if compile_source:
            # Clean existing compile & install directories from previous builds
            if generate_source:
                self.clean_compile_dir(compile_dir,
                                       purge=(build_mode == 'purge'))
                self.configure_build_files(name=name,
                                           src_dir=src_dir,
                                           compile_dir=compile_dir,
                                           install_dir=install_dir,
                                           **kwargs)
                self.clean_install_dir(install_dir)
            self.compile_source_files(compile_dir, name)
        # Switch back to original dir
        os.chdir(orig_dir)
        # Cache any dimension maps that were calculated during the generation
        # process
        return install_dir
Пример #14
0
def plot(seg, dims=(20, 16), resolution=300, save=None, show=True,
         regime_alpha=0.05, regime_linestyle=':', title=None):
    if title is None:
        title = 'PyPe9 Simulation Output'
    num_subplots = bool(seg.analogsignals) + bool(seg.spiketrains)
    fig, axes = plt.subplots(num_subplots, 1)
    fig.suptitle(title)
    fig.set_figwidth(dims[0])
    fig.set_figheight(dims[1])
    # Set the dimension of the figure
    plt_name = seg.name + ' ' if seg.name else ''
    if seg.spiketrains:
        spike_times = []
        ids = []
        for i, spiketrain in enumerate(seg.spiketrains):
            spike_times.extend(spiketrain)
            ids.extend([i] * len(spiketrain))
        plt.sca(axes[0] if num_subplots > 1 else axes)
        plt.scatter(spike_times, ids)
        plt.xlim((seg.spiketrains[0].t_start, seg.spiketrains[0].t_stop))
        plt.ylim((-1, len(seg.spiketrains)))
        plt.xlabel('Times (ms)')
        plt.ylabel('Cell Indices')
        plt.title("{}Spike Trains".format(plt_name), fontsize=12)
    if seg.analogsignals:
        legend = []
        plt.sca(axes[-1] if num_subplots > 1 else axes)
        units = set(s.units.dimensionality.string for s in seg.analogsignals)
        # Plot signals
        for i, signal in enumerate(seg.analogsignals):
            un_str = (signal.units.dimensionality.string
                      if len(units) > 1 else '')
            label = signal.name + un_str if signal.name else str(i)
            line, = plt.plot(signal.times, signal, label=label)
            legend.append(line)
        # Plot regime epochs (if present)
        for epochs in seg.epochs:
            # Generate colours for each regime
            labels = sort_epochs_by_duration(epochs)
            # Make the 'mode' regime transparent
            label_colours = OrderedDict([(labels[0], None)])
            for label in labels[1:]:
                label_colours[label] = plt.gca()._get_lines.get_next_color()
            for label, start, duration in zip(epochs.labels,
                                              epochs.times,
                                              epochs.durations):
                if label_colours[label] is not None:
                    end = start + duration
                    plt.axvspan(start, end, facecolor=label_colours[label],
                                alpha=regime_alpha)
                    plt.axvline(start, linestyle=regime_linestyle,
                                color='gray', linewidth=0.5)
                    plt.axvline(end, linestyle=regime_linestyle, color='gray',
                                linewidth=0.5)
            for label, colour in label_colours.items():
                if colour is None:
                    colour = 'white'
                legend.append(
                    mpatches.Patch(facecolor=colour, edgecolor='grey',
                                   label=label + ' regime', linewidth=0.5,
                                   linestyle=regime_linestyle))
        plt.xlim((seg.analogsignals[0].t_start, seg.analogsignals[0].t_stop))
        plt.xlabel('Time (ms)')
        un_str = (' ({})'.format(next(iter(units)))
                  if len(units) == 1 else '')
        plt.ylabel('Analog signals{}'.format(un_str))
        plt.title("{}Analog Signals".format(plt_name), fontsize=12)
        plt.legend(handles=legend)
    if save is not None:
        fig.savefig(save, dpi=resolution)
        logger.info("Saved{} figure to '{}'".format(plt_name, save))
    if show:
        plt.show()
Пример #15
0
def run(argv):
    """
    Runs the simulation script from the provided arguments
    """
    import nineml
    from pype9.exceptions import Pype9UsageError
    import neo.io

    args = argparser().parse_args(argv)

    time = args.time * un.ms
    timestep = args.timestep * un.ms

    if args.simulator == 'neuron':
        from pype9.simulate.neuron import Network, CellMetaClass, Simulation  # @UnusedImport @IgnorePep8
    elif args.simulator == 'nest':
        from pype9.simulate.nest import Network, CellMetaClass, Simulation  # @Reimport @IgnorePep8
    else:
        assert False

    if not args.record:
        raise Pype9UsageError(
            "No recorders set, please specify at least one with the '--record'"
            " option")

    min_delay = (float(args.min_delay[0]) * parse_units(args.min_delay[1])
                 if args.min_delay is not None else 1.0 * un.ms)

    device_delay = (float(args.device_delay[0]) *
                    parse_units(args.device_delay[1])
                    if args.device_delay is not None else None)

    # Parse record specs
    record_specs = []
    for rec in args.record:
        if len(rec) == 4:
            rec_t_start = pq.Quantity(float(rec[2]), rec[3])
        elif len(rec) == 2:
            rec_t_start = None
        else:
            raise Pype9UsageError(
                "Record options can be passed either have 2 or 4 (provided {})"
                ": PORT/STATE-VARIABLE FILENAME [T_START T_START_UNITS]")
        record_specs.append(RecordSpec(rec[0], rec[1], rec_t_start))

    # Check for clashing record paths
    record_paths = [r.fname for r in record_specs]
    for pth in record_paths:
        if record_paths.count(pth) > 1:
            raise Pype9UsageError(
                "Duplicate record paths '{}' given to separate '--record' "
                "options".format(pth))

    # For convenience
    model = args.model

    if isinstance(model, nineml.Network) and not model.num_projections:
        raise Pype9UsageError(
            "Provided network model '{}' (may have been implicitly created "
            "from complete document) does not contain any projections".format(
                model))

    if isinstance(model, nineml.Network):
        with Simulation(dt=timestep,
                        seed=args.seed,
                        properties_seed=args.properties_seed,
                        device_delay=device_delay,
                        **model.delay_limits()) as sim:
            # Construct the network
            logger.info("Constructing network")
            network = Network(model,
                              build_mode=args.build_mode,
                              build_base_dir=args.build_dir)
            logger.info("Finished constructing the '{}' network".format(
                model.name))
            for rspec in record_specs:
                pop_name, port_name = rspec.port.split('.')
                network.component_array(pop_name).record(port_name)
            logger.info("Running the simulation")
            sim.run(time)
        logger.info("Writing recorded data to file")
        for rspec in record_specs:
            pop_name, port_name = rspec.port.split('.')
            pop = network.component_array(pop_name)
            neo.PickleIO(rspec.fname).write(
                pop.recording(port_name, t_start=rspec.t_start))
    else:
        assert isinstance(model, (nineml.DynamicsProperties, nineml.Dynamics))
        # Override properties passed as options
        if args.prop:
            props_dict = dict((parm, float(val) * parse_units(unts))
                              for parm, val, unts in args.prop)
            props = nineml.DynamicsProperties(model.name + '_props', model,
                                              props_dict)
            component_class = model
        elif isinstance(model, nineml.DynamicsProperties):
            props = model
            component_class = model.component_class
        else:
            raise Pype9UsageError(
                "Specified model {} is not a dynamics properties object and "
                "no properties supplied to simulate command via --prop option".
                format(model))
        # Get the initial state
        init_state = dict((sv, float(val) * parse_units(units))
                          for sv, val, units in args.init_value)
        # Get the init_regime
        init_regime = args.init_regime
        if init_regime is None:
            if component_class.num_regimes == 1:
                # If there is only one regime it doesn't need to be specified
                init_regime = next(component_class.regimes).name
            else:
                raise Pype9UsageError(
                    "Need to specify initial regime as dynamics has more than "
                    "one '{}'".format("', '".join(
                        r.name for r in component_class.regimes)))
        # FIXME: A bit of a hack until better detection of input currents is
        #        implemented in neuron code gen.
        external_currents = []
        for port_name, _ in args.play:
            if component_class.port(port_name).dimension == un.current:
                external_currents.append(port_name)
        # Build cell class
        Cell = CellMetaClass(component_class,
                             build_mode=args.build_mode,
                             external_currents=external_currents,
                             build_version=args.build_version,
                             build_base_dir=args.build_dir)
        record_regime = False
        with Simulation(dt=timestep,
                        seed=args.seed,
                        min_delay=min_delay,
                        device_delay=device_delay,
                        build_base_dir=args.build_dir) as sim:
            # Create cell
            cell = Cell(props, regime_=init_regime, **init_state)
            # Play inputs
            for port_name, fname in args.play:
                port = component_class.receive_port(port_name)
                seg = neo.io.PickleIO(filename=fname).read()[0]
                if port.communicates == 'event':
                    signal = seg.spiketrains[0]
                else:
                    signal = seg.analogsignals[0]
                logger.info("Playing signal (t_start: {}, t_stop: {}, dt: {}) "
                            "into port '{}".format(signal.t_start,
                                                   signal.t_stop,
                                                   signal.sampling_period,
                                                   port_name))
                # Input is an event train or analog signal
                cell.play(port_name, signal)
            # Set up recorders
            for rspec in record_specs:
                if (component_class.num_regimes > 1 and component_class.port(
                        rspec.port).communicates == 'analog'):
                    record_regime = True
                cell.record(rspec.port, t_start=rspec.t_start)
            if record_regime:
                cell.record_regime()
            # Run simulation
            sim.run(time)
        # Collect data into Neo Segments
        fnames = set(r.fname for r in record_specs)
        data_segs = {}
        for fname in fnames:
            data_segs[fname] = neo.Segment(
                description="Simulation of '{}' cell".format(model.name))
        for rspec in record_specs:
            data = cell.recording(rspec.port, t_start=rspec.t_start)
            if isinstance(data, neo.AnalogSignal):
                data_segs[rspec.fname].analogsignals.append(data)
            else:
                data_segs[rspec.fname].spiketrains.append(data)
            if record_regime:
                data_segs[rspec.fname].epochs.append(cell.regime_epochs())
        # Write data to file
        for fname, data_seg in data_segs.items():
            neo.io.PickleIO(fname).write(data_seg)
    logger.info("Finished simulation of '{}' for {}".format(model.name, time))