예제 #1
0
    def __init__(self, path, snapfile):
        """ """

        # potential used for the simulation
        self.potential = LawMajewski2010()

        # some smart pathness
        if not os.path.exists(path):
            _path = os.path.join(streamspath, "data", "simulation", path)
            if os.path.exists(_path):
                path = _path
            else:
                raise IOError("Path '{}' doesn't exist".format(path))
        self.path = path

        self.reader = SCFReader(self.path)
        self.particle_table = self.reader.read_snap(snapfile, units=usys)
        self.units = _usys

        # get mass column from table
        m = np.array(self.particle_table['m']) * self.particle_table['m'].unit
        self.mass = np.sum(m)
        self.t1 = self.particle_table.meta["time"]
        self.t2 = 0.
예제 #2
0
파일: sgr.py 프로젝트: adrn/streams
    def __init__(self, path, snapfile):
        """ """

        # potential used for the simulation
        self.potential = LawMajewski2010()

        # some smart pathness
        if not os.path.exists(path):
            _path = os.path.join(streamspath, "data", "simulation", path)
            if os.path.exists(_path):
                path = _path
            else:
                raise IOError("Path '{}' doesn't exist".format(path))
        self.path = path

        self.reader = SCFReader(self.path)
        self.particle_table = self.reader.read_snap(snapfile, units=usys)
        self.units = _usys

        # get mass column from table
        m = np.array(self.particle_table['m'])*self.particle_table['m'].unit
        self.mass = np.sum(m)
        self.t1 = self.particle_table.meta["time"]
        self.t2 = 0.
예제 #3
0
def observe_simulation(star_error_model=None,
                       progenitor_error_model=None,
                       selection_expr=None,
                       output_file=None,
                       overwrite=False,
                       seed=None,
                       simulation_path=None,
                       snapfile=None):
    """ Observe simulation data and write the output to an HDF5 file """

    if os.path.exists(output_file) and overwrite:
        os.remove(output_file)

    if os.path.exists(output_file):
        raise IOError("File '{}' already exists! Did you "
                      "want to use overwrite=True?".format(output_file))

    # read the simulation data from the specified class
    if seed is None:
        seed = np.random.randint(100)

    logger.debug("Using seed: {}".format(seed))
    np.random.seed(seed)
    random.seed(seed)

    scf = SCFReader(simulation_path)
    snap_data = scf.read_snap(snapfile, units=usys)

    # select out particles that meet these cuts
    idx = numexpr.evaluate("(tub!=0)", snap_data)
    star_data = snap_data[idx]
    logger.debug("Read in {} particles".format(len(star_data)))

    # coordinate transform
    star_gc = np.vstack([star_data[n] for n in galactocentric_names]).T
    star_hel = gal_to_hel(star_gc)

    # create table for star data
    star_tbl = at.Table(star_hel, names=heliocentric_names)
    star_tbl.add_column(star_data["tub"])  # add tub

    # select bound particles to median to get satellite position
    idx = numexpr.evaluate("(tub==0)", snap_data)
    prog_data = snap_data[idx]

    # coordinate transform
    prog_gc = np.vstack([prog_data[n] for n in galactocentric_names]).T
    prog_gc = np.median(prog_gc, axis=0).reshape(1, 6)
    logger.debug("Used {} particles to estimate progenitor position.".format(
        len(prog_data)))
    prog_hel = gal_to_hel(prog_gc)

    # create table for progenitor data
    prog_tbl = at.Table(prog_hel, names=heliocentric_names)
    prog_tbl.add_column(at.Column([snap_data["m"].sum()],
                                  name="m0"))  # add mass

    # determine tail assignment for stars by relative energy
    dE = energy(star_gc) - energy(prog_gc)
    tail = np.zeros(len(star_tbl))
    lead = dE <= 0.
    trail = dE > 0.
    tail[lead] = -1.  # leading tail
    tail[trail] = 1.  # trailing
    star_tbl.add_column(at.Column(tail, name="tail"))  # add tail

    # observe the data
    observed_star_tbl, star_err_tbl = observe_table(star_tbl, star_error_model)
    observed_prog_tbl, prog_err_tbl = observe_table(prog_tbl,
                                                    progenitor_error_model)

    # make a plot of true and observed positions
    obs_hel = np.vstack([observed_star_tbl[n] for n in heliocentric_names]).T
    obs_gc = hel_to_gal(obs_hel)

    fig, axes = plt.subplots(2, 2, figsize=(16, 16))

    mpl = dict(markersize=3., marker='o', linestyle='none', alpha=0.5)
    axes[0, 0].plot(star_gc[:, 0], star_gc[:, 1], **mpl)
    axes[0, 1].plot(star_gc[:, 0], star_gc[:, 2], **mpl)
    axes[0, 0].plot(obs_gc[trail, 0],
                    obs_gc[trail, 1],
                    label='trailing',
                    c='#ca0020',
                    **mpl)
    axes[0, 1].plot(obs_gc[trail, 0], obs_gc[trail, 2], c='#ca0020', **mpl)
    axes[0, 0].plot(obs_gc[lead, 0], obs_gc[lead, 1], label='leading', **mpl)
    axes[0, 1].plot(obs_gc[lead, 0], obs_gc[lead, 2], **mpl)
    axes[0, 0].legend()

    axes[1, 0].plot(star_gc[:, 3], star_gc[:, 4], **mpl)
    axes[1, 1].plot(star_gc[:, 3], star_gc[:, 5], **mpl)
    axes[1, 0].plot(obs_gc[trail, 3], obs_gc[trail, 4], c='#ca0020', **mpl)
    axes[1, 1].plot(obs_gc[trail, 3], obs_gc[trail, 5], c='#ca0020', **mpl)
    axes[1, 0].plot(obs_gc[lead, 3], obs_gc[lead, 4], **mpl)
    axes[1, 1].plot(obs_gc[lead, 3], obs_gc[lead, 5], **mpl)

    fname = os.path.splitext(os.path.basename(output_file))[0]
    fig.savefig(
        os.path.join(
            os.path.split(output_file)[0], "{}.{}".format(fname, 'png')))

    # write tables to output_file
    observed_star_tbl.write(output_file,
                            format="hdf5",
                            path="stars",
                            overwrite=overwrite)
    observed_prog_tbl.write(output_file,
                            format="hdf5",
                            path="progenitor",
                            append=True)
    star_err_tbl.write(output_file,
                       format="hdf5",
                       path="error_stars",
                       append=True)
    prog_err_tbl.write(output_file,
                       format="hdf5",
                       path="error_progenitor",
                       append=True)
    star_tbl.write(output_file, format="hdf5", path="true_stars", append=True)
    prog_tbl.write(output_file,
                   format="hdf5",
                   path="true_progenitor",
                   append=True)

    integ_tbl = at.Table(np.array([[np.nan]]))
    integ_tbl.meta['t1'] = snap_data.meta['time']
    integ_tbl.meta['t2'] = 0.
    integ_tbl.write(output_file,
                    format="hdf5",
                    path="integration",
                    append=True)
예제 #4
0
def observe_simulation(star_error_model=None, progenitor_error_model=None,
                       selection_expr=None, output_file=None, overwrite=False,
                       seed=None, simulation_path=None, snapfile=None):
    """ Observe simulation data and write the output to an HDF5 file """

    if os.path.exists(output_file) and overwrite:
        os.remove(output_file)

    if os.path.exists(output_file):
        raise IOError("File '{}' already exists! Did you "
                      "want to use overwrite=True?".format(output_file))

    # read the simulation data from the specified class
    if seed is None:
        seed = np.random.randint(100)

    logger.debug("Using seed: {}".format(seed))
    np.random.seed(seed)
    random.seed(seed)

    scf = SCFReader(simulation_path)
    snap_data = scf.read_snap(snapfile, units=usys)

    # select out particles that meet these cuts
    idx = numexpr.evaluate("(tub!=0)", snap_data)
    star_data = snap_data[idx]
    logger.debug("Read in {} particles".format(len(star_data)))

    # coordinate transform
    star_gc = np.vstack([star_data[n] for n in galactocentric_names]).T
    star_hel = gal_to_hel(star_gc)

    # create table for star data
    star_tbl = at.Table(star_hel, names=heliocentric_names)
    star_tbl.add_column(star_data["tub"]) # add tub

    # select bound particles to median to get satellite position
    idx = numexpr.evaluate("(tub==0)", snap_data)
    prog_data = snap_data[idx]

    # coordinate transform
    prog_gc = np.vstack([prog_data[n] for n in galactocentric_names]).T
    prog_gc = np.median(prog_gc, axis=0).reshape(1,6)
    logger.debug("Used {} particles to estimate progenitor position.".format(len(prog_data)))
    prog_hel = gal_to_hel(prog_gc)

    # create table for progenitor data
    prog_tbl = at.Table(prog_hel, names=heliocentric_names)
    prog_tbl.add_column(at.Column([snap_data["m"].sum()], name="m0")) # add mass

    # determine tail assignment for stars by relative energy
    dE = energy(star_gc) - energy(prog_gc)
    tail = np.zeros(len(star_tbl))
    lead = dE <= 0.
    trail = dE > 0.
    tail[lead] = -1. # leading tail
    tail[trail] = 1. # trailing
    star_tbl.add_column(at.Column(tail, name="tail")) # add tail

    # observe the data
    observed_star_tbl,star_err_tbl = observe_table(star_tbl, star_error_model)
    observed_prog_tbl,prog_err_tbl = observe_table(prog_tbl, progenitor_error_model)

    # make a plot of true and observed positions
    obs_hel = np.vstack([observed_star_tbl[n] for n in heliocentric_names]).T
    obs_gc = hel_to_gal(obs_hel)

    fig,axes = plt.subplots(2,2,figsize=(16,16))

    mpl = dict(markersize=3., marker='o', linestyle='none', alpha=0.5)
    axes[0,0].plot(star_gc[:,0], star_gc[:,1], **mpl)
    axes[0,1].plot(star_gc[:,0], star_gc[:,2], **mpl)
    axes[0,0].plot(obs_gc[trail,0], obs_gc[trail,1], label='trailing', c='#ca0020', **mpl)
    axes[0,1].plot(obs_gc[trail,0], obs_gc[trail,2], c='#ca0020', **mpl)
    axes[0,0].plot(obs_gc[lead,0], obs_gc[lead,1], label='leading', **mpl)
    axes[0,1].plot(obs_gc[lead,0], obs_gc[lead,2], **mpl)
    axes[0,0].legend()

    axes[1,0].plot(star_gc[:,3], star_gc[:,4], **mpl)
    axes[1,1].plot(star_gc[:,3], star_gc[:,5], **mpl)
    axes[1,0].plot(obs_gc[trail,3], obs_gc[trail,4], c='#ca0020', **mpl)
    axes[1,1].plot(obs_gc[trail,3], obs_gc[trail,5], c='#ca0020', **mpl)
    axes[1,0].plot(obs_gc[lead,3], obs_gc[lead,4], **mpl)
    axes[1,1].plot(obs_gc[lead,3], obs_gc[lead,5], **mpl)

    fname = os.path.splitext(os.path.basename(output_file))[0]
    fig.savefig(os.path.join(os.path.split(output_file)[0],
                             "{}.{}".format(fname, 'png')))

    # write tables to output_file
    observed_star_tbl.write(output_file, format="hdf5", path="stars", overwrite=overwrite)
    observed_prog_tbl.write(output_file, format="hdf5", path="progenitor", append=True)
    star_err_tbl.write(output_file, format="hdf5", path="error_stars", append=True)
    prog_err_tbl.write(output_file, format="hdf5", path="error_progenitor", append=True)
    star_tbl.write(output_file, format="hdf5", path="true_stars", append=True)
    prog_tbl.write(output_file, format="hdf5", path="true_progenitor", append=True)

    integ_tbl = at.Table(np.array([[np.nan]]))
    integ_tbl.meta['t1'] = snap_data.meta['time']
    integ_tbl.meta['t2'] = 0.
    integ_tbl.write(output_file, format="hdf5", path="integration", append=True)
예제 #5
0
class SgrSimulation(object):
    def __init__(self, path, snapfile):
        """ """

        # potential used for the simulation
        self.potential = LawMajewski2010()

        # some smart pathness
        if not os.path.exists(path):
            _path = os.path.join(streamspath, "data", "simulation", path)
            if os.path.exists(_path):
                path = _path
            else:
                raise IOError("Path '{}' doesn't exist".format(path))
        self.path = path

        self.reader = SCFReader(self.path)
        self.particle_table = self.reader.read_snap(snapfile, units=usys)
        self.units = _usys

        # get mass column from table
        m = np.array(self.particle_table['m']) * self.particle_table['m'].unit
        self.mass = np.sum(m)
        self.t1 = self.particle_table.meta["time"]
        self.t2 = 0.

    def particles(self, n=None, expr=None, tail_bit=False, clean=False):
        """ Return a Particle object with N particles selected from the
            simulation with expression expr.

            Parameters
            ----------
            n : int or None (optional)
                Number of particles to return. None or 0 means 'all'
            expr : str (optional)
                Use numexpr to select out only rows that match criteria.
            tail_bit : bool (optional)
                Compute tail bit or not.
        """

        if expr is not None:
            expr_idx = numexpr.evaluate(str(expr), self.particle_table)
        else:
            expr_idx = np.ones(len(self.particle_table)).astype(bool)

        table = self.particle_table[expr_idx]
        n_idx = np.array(sample(xrange(len(table)), len(table)))
        if n is not None and n > 0:
            idx = n_idx[:n]
        else:
            idx = n_idx
        table = table[idx]

        # get a list of quantities for each column
        coords = []
        for colname in galactocentric.coord_names:
            coords.append(np.array(table[colname]) * table[colname].unit)

        meta = dict(expr=expr)
        meta["tub"] = (np.array(table["tub"]) * table["tub"].unit).to(
            _usys["time"]).value

        # create the particle object
        p = Particle(coords, frame=galactocentric, meta=meta)
        p = p.decompose(usys)

        # guess whether in leading or trailing tail
        if tail_bit:
            coord, r_tide, v_disp = particles_x1x2x3(p,
                                                     self.satellite(),
                                                     self.potential,
                                                     self.t1,
                                                     self.t2,
                                                     -1,
                                                     at_tub=True)
            (x1, x2, x3, vx1, vx2, vx3) = coord
            p.meta["tail_bit"] = p.tail_bit = guess_tail_bit(x1, x2)
        else:
            tail_bit = np.ones(p.nparticles) * np.nan

        if clean:
            if not tail_bit:
                coord, r_tide, v_disp = particles_x1x2x3(p,
                                                         self.satellite(),
                                                         self.potential,
                                                         self.t1,
                                                         self.t2,
                                                         -1,
                                                         at_tub=True)
                (x1, x2, x3, vx1, vx2, vx3) = coord

                tail_bit = guess_tail_bit(x1, x2)
            else:
                tail_bit = p.tail_bit

            # reject any with nan tail_bit
            idx = ~np.isnan(tail_bit)

            # reject any with |x1| > 2.5  or |x2| > 1.2
            idx &= np.fabs(x1 / r_tide) < 2.5
            idx &= np.fabs(x2 / r_tide) < 1.2

            _X = p._X[idx]
            meta["tub"] = p.tub[idx]
            meta["tail_bit"] = tail_bit[idx]
            p = Particle(_X.T.copy(),
                         frame=p.frame,
                         units=p._internal_units,
                         meta=meta)

        return p

    def satellite(self):
        """ Return a Particle object with the present-day position of the
            satellite, computed from the still-bound particles.
        """
        expr_idx = numexpr.evaluate("tub==0", self.particle_table)
        bound = self.particle_table[expr_idx]

        q = []
        for colname in galactocentric.coord_names:
            q.append(np.median(np.array(bound[colname])) * bound[colname].unit)

        meta = dict()
        meta["m0"] = self.mass.to(_usys['mass']).value
        mdot = 3.3 * 10**(np.floor(np.log10(meta["m0"])) - 4)
        meta['mdot'] = mdot

        p = Particle(q, frame=galactocentric, meta=meta)
        return p.decompose(usys)
예제 #6
0
파일: sgr.py 프로젝트: adrn/streams
class SgrSimulation(object):

    def __init__(self, path, snapfile):
        """ """

        # potential used for the simulation
        self.potential = LawMajewski2010()

        # some smart pathness
        if not os.path.exists(path):
            _path = os.path.join(streamspath, "data", "simulation", path)
            if os.path.exists(_path):
                path = _path
            else:
                raise IOError("Path '{}' doesn't exist".format(path))
        self.path = path

        self.reader = SCFReader(self.path)
        self.particle_table = self.reader.read_snap(snapfile, units=usys)
        self.units = _usys

        # get mass column from table
        m = np.array(self.particle_table['m'])*self.particle_table['m'].unit
        self.mass = np.sum(m)
        self.t1 = self.particle_table.meta["time"]
        self.t2 = 0.

    def particles(self, n=None, expr=None, tail_bit=False, clean=False):
        """ Return a Particle object with N particles selected from the
            simulation with expression expr.

            Parameters
            ----------
            n : int or None (optional)
                Number of particles to return. None or 0 means 'all'
            expr : str (optional)
                Use numexpr to select out only rows that match criteria.
            tail_bit : bool (optional)
                Compute tail bit or not.
        """

        if expr is not None:
            expr_idx = numexpr.evaluate(str(expr), self.particle_table)
        else:
            expr_idx = np.ones(len(self.particle_table)).astype(bool)

        table = self.particle_table[expr_idx]
        n_idx = np.array(sample(xrange(len(table)), len(table)))
        if n is not None and n > 0:
            idx = n_idx[:n]
        else:
            idx = n_idx
        table = table[idx]

        # get a list of quantities for each column
        coords = []
        for colname in galactocentric.coord_names:
            coords.append(np.array(table[colname])*table[colname].unit)

        meta = dict(expr=expr)
        meta["tub"] = (np.array(table["tub"])*table["tub"].unit).to(_usys["time"]).value

        # create the particle object
        p = Particle(coords, frame=galactocentric, meta=meta)
        p = p.decompose(usys)

        # guess whether in leading or trailing tail
        if tail_bit:
            coord, r_tide, v_disp = particles_x1x2x3(p, self.satellite(),
                                                     self.potential,
                                                     self.t1, self.t2, -1,
                                                     at_tub=True)
            (x1,x2,x3,vx1,vx2,vx3) = coord
            p.meta["tail_bit"] = p.tail_bit = guess_tail_bit(x1,x2)
        else:
            tail_bit = np.ones(p.nparticles)*np.nan

        if clean:
            if not tail_bit:
                coord, r_tide, v_disp = particles_x1x2x3(p, self.satellite(),
                                                         self.potential,
                                                         self.t1, self.t2, -1,
                                                         at_tub=True)
                (x1,x2,x3,vx1,vx2,vx3) = coord

                tail_bit = guess_tail_bit(x1,x2)
            else:
                tail_bit = p.tail_bit

            # reject any with nan tail_bit
            idx = ~np.isnan(tail_bit)

            # reject any with |x1| > 2.5  or |x2| > 1.2
            idx &= np.fabs(x1/r_tide) < 2.5
            idx &= np.fabs(x2/r_tide) < 1.2

            _X = p._X[idx]
            meta["tub"] = p.tub[idx]
            meta["tail_bit"] = tail_bit[idx]
            p = Particle(_X.T.copy(), frame=p.frame, units=p._internal_units, meta=meta)

        return p

    def satellite(self):
        """ Return a Particle object with the present-day position of the
            satellite, computed from the still-bound particles.
        """
        expr_idx = numexpr.evaluate("tub==0", self.particle_table)
        bound = self.particle_table[expr_idx]

        q = []
        for colname in galactocentric.coord_names:
            q.append(np.median(np.array(bound[colname]))*bound[colname].unit)

        meta = dict()
        meta["m0"] = self.mass.to(_usys['mass']).value
        mdot = 3.3*10**(np.floor(np.log10(meta["m0"]))-4)
        meta['mdot'] = mdot

        p = Particle(q, frame=galactocentric, meta=meta)
        return p.decompose(usys)