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 __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 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)
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)
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)
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)