Beispiel #1
0
def bng_simulate(model, times, method='ode', output_dir='/tmp', cleanup=True):
    """
    Simulate a model with BNG's simulator and return the trajectories.
    Adapted from pysb.bng.run_ssa.

    Parameters
    ----------
    model : pysb.Model or string
        Model to simulate. Can be either a pysb.Model or a string representing
        BNGL model.
    times: list of floats
        Sample times.
    method: string
        'ode' or 'ssa'
    output_dir : string, optional
        Location for temporary files generated by BNG. Defaults to '/tmp'.
    cleanup : bool, optional
        If True (default), delete the temporary files after the simulation is
        finished. If False, leave them in place (in `output_dir`). Useful for
        debugging.

    """

    times = list(times)
    run_ssa_code = """
    begin actions
    generate_network({overwrite=>1});
    simulate_%s({sample_times=>%s});\n
    end actions
    """ % (method, times)

    if not isinstance(model, str):
        model = BngGenerator(model).get_content()
    bng_filename = '%d_%d_temp.bngl' % (
        os.getpid(), random.randint(0, 10000))
    gdat_filename = bng_filename.replace('.bngl', '.gdat')
    cdat_filename = bng_filename.replace('.bngl', '.cdat')
    net_filename = bng_filename.replace('.bngl', '.net')

    try:
        working_dir = os.getcwd()
        os.chdir(output_dir)
        bng_file = open(bng_filename, 'w')
        bng_file.write(model)
        bng_file.write(run_ssa_code)
        bng_file.close()
        p = subprocess.Popen(['perl', _get_bng_path(), bng_filename],
                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        (p_out, p_err) = p.communicate()
        if p.returncode:
            raise GenerateNetworkError(p_out.rstrip("at line") + "\n" +
                                       p_err.rstrip())

        output_arr = _parse_bng_outfile(gdat_filename)
    finally:
        if cleanup:
            for filename in [bng_filename, gdat_filename,
                             cdat_filename, net_filename]:
                if os.access(filename, os.F_OK):
                    os.unlink(filename)
        os.chdir(working_dir)
    return output_arr
Beispiel #2
0
def save_bng_dirs_to_hdf5(data_basename, num_conditions, filename):
    """Load the .gdat files in each of the listed directories to HDF5.

    The HDF5 file created contains two datasets:

    * A dataset named ``'data'`` which contains the simulation results in a
      four-dimensional numpy array of floats with shape `(num_conditions,
      num_simulations, num_observables, num_timepoints)`.

    * A dataset named ``'dtypes'`` containing the string-pickled dtype of the
      simulation results. The dtype contains the names of all of the
      observables from the original record array, and hence can be used to
      get the index for a particular observable in the full table of simulation
      results.

    Parameters
    ----------
    data_basename : string

        For parsing multiple directories, the base name of the .gdat data
        directories before the index of the job condition is appended, e.g.,
        'data\_' for the list of directories 'data_0', 'data_1', 'data_2'.
        However, when there is only a single directory being parsed (i.e.,
        num_conditions is 1), then this argument is taken to be the full
        name of the data directory, e.g., 'data_0', and no index is appended.
    num_conditions : int
        The number of data directories/conditions, e.g., 3 for the list of
        directories 'data_0', 'data_1', 'data_2'.
    filename : string
        The name of the HDF5 file to create.

    Returns
    -------
    h5py dataset
        The dataset containing the parsed simulation results and the
        corresponding dtype list.
    """
    dataset = None
    print "Loading BNG simulation results from data directories..."
    for condition_index in range(num_conditions):
        if num_conditions == 1:
            data_dir = data_basename
        else:
            data_dir = '%s%d' % (data_basename, condition_index)
        print "Loading data from directory %s" % data_dir
        gdat_files = glob.glob('%s/*.gdat' % data_dir)

        for sim_index, gdat_file in enumerate(gdat_files):
            ssa_result = bng._parse_bng_outfile(gdat_file)
            # Initialize the dataset
            if dataset is None:
                num_simulations = len(gdat_files)
                num_observables = len(ssa_result.dtype)
                num_timepoints = len(ssa_result)
                f = h5py.File('%s.hdf5' % filename, 'w')
                dataset = f.create_dataset('data',
                               (num_conditions, num_simulations,
                                num_observables, num_timepoints),
                               dtype='float',
                               chunks=(1, min(SIM_CHUNK_SIZE, num_simulations),
                                       1, min(TIME_CHUNK_SIZE, num_timepoints)),
                               compression=9, shuffle=True)
            # Make sure there's no funny business
            assert len(gdat_files) == num_simulations
            assert len(ssa_result.dtype) == num_observables
            assert len(ssa_result) == num_timepoints
            # Load the data into the appropriate slot in the dataset
            dataset[condition_index, sim_index, :, :] = \
                         ssa_result.view('float').reshape(num_timepoints, -1).T
            print "\rLoaded BNG file %d of %d" % (sim_index+1, num_simulations),
            sys.stdout.flush()
        # (end iteration over all .gdat files in the directory)
        print # Add a newline
    # (end iteration over all data directories)

    # Pickle the dtype with the observables and save in the dataset
    dtype_pck = pickle.dumps(ssa_result.dtype)
    f.create_dataset('dtypes', dtype='uint8', data=map(ord, dtype_pck))
    f.close()
    return dataset