[yt-svn] commit/yt: 17 new changesets
commits-noreply at bitbucket.org
commits-noreply at bitbucket.org
Fri Oct 6 07:52:11 PDT 2017
17 new commits in yt:
https://bitbucket.org/yt_analysis/yt/commits/1e137c888a30/
Changeset: 1e137c888a30
User: Corentin Cadiou
Date: 2017-09-04 14:53:58+00:00
Summary: add support for sink particles in RAMSES
Affected #: 3 files
diff -r e6ea9f86b3eeaf95f3ece1ccec8b35253eff4459 -r 1e137c888a30d5a25ba0e6ba42c8fab62067e04c yt/frontends/ramses/data_structures.py
--- a/yt/frontends/ramses/data_structures.py
+++ b/yt/frontends/ramses/data_structures.py
@@ -62,11 +62,12 @@
os.path.abspath(
os.path.dirname(ds.parameter_filename)),
num, domain_id)
- for t in ['grav', 'hydro', 'part', 'amr']:
+ for t in ['grav', 'hydro', 'part', 'amr', 'sink']:
setattr(self, "%s_fn" % t, basename % t)
self._read_amr_header()
self._read_hydro_header()
self._read_particle_header()
+ self._read_sink_header()
self._read_amr()
_hydro_offset = None
@@ -75,13 +76,21 @@
def __repr__(self):
return "RAMSESDomainFile: %i" % self.domain_id
- def _is_hydro(self):
+ @property
+ def _has_hydro(self):
'''
Does the output include hydro?
'''
return os.path.exists(self.hydro_fn)
@property
+ def _has_sink(self):
+ '''
+ Does the output include sinks (black holes)?
+ '''
+ return os.path.exists(self.sink_fn)
+
+ @property
def level_count(self):
if self._level_count is not None: return self._level_count
self.hydro_offset
@@ -125,14 +134,75 @@
def _read_hydro_header(self):
# If no hydro file is found, return
- if not self._is_hydro():
+ if not self._has_hydro:
return
if self.nvar > 0: return self.nvar
- # Read the number of hydro variables
+ # Read the number of hydro variables
f = open(self.hydro_fn, "rb")
fpu.skip(f, 1)
self.nvar = fpu.read_vector(f, "i")[0]
+
+ def _read_sink_header(self):
+ if not self._has_sink:
+ self.local_sink_count = 0
+ self.sink_field_offsets = {}
+ return
+ f = open(self.sink_fn, "rb")
+ f.seek(0, os.SEEK_END)
+ flen = f.tell()
+ f.seek(0)
+ hvals = {}
+ attrs = (('nsink', 1, 'I'),
+ ('nindsink', 1, 'I'))
+ hvals.update(fpu.read_attrs(f, attrs))
+ self.sink_header = hvals
+ self.local_sink_count = hvals['nsink']
+
+ sink_fields = [
+ ("particle_identifier", "i"),
+ ("particle_mass", "d"),
+ ("particle_position_x", "d"),
+ ("particle_position_y", "d"),
+ ("particle_position_z", "d"),
+ ("particle_velocity_x", "d"),
+ ("particle_velocity_y", "d"),
+ ("particle_velocity_z", "d"),
+ ("particle_age", "d"),
+ ("real_accretion", "d"),
+ ("bondi_accretion", "d"),
+ ("eddington_accretion", "d"),
+ ("esave", "d"),
+ ("spin_x", "d"),
+ ("spin_y", "d"),
+ ("spin_z", "d"),
+ ("spin", "d"),
+ ("efficiency", "d")]
+
+ for i in range(self.ds.dimensionality*2+1):
+ for j in range(self.ds.max_level, self.ds.min_level):
+ sink_fields.append((
+ "particle_prop_%s_%s" % (i, j), "d"
+ ))
+
+ field_offsets = {}
+ _pfields = {}
+ for field, vtype in sink_fields:
+ if f.tell() >= flen: break
+ field_offsets["sink", field] = f.tell()
+ _pfields["sink", field] = vtype
+ fpu.skip(f, 1)
+ self.sink_field_offsets = field_offsets
+ self.sink_field_types = _pfields
+
+ try:
+ ptypes = list(self.particles_types)
+ except AttributeError:
+ ptypes = []
+ finally:
+ ptypes.append('sink')
+ self.particle_types = self.particle_types_raw = tuple(ptypes)
+
def _read_particle_header(self):
if not os.path.exists(self.part_fn):
self.local_particle_count = 0
@@ -175,14 +245,16 @@
field_offsets = {}
_pfields = {}
+
+ ptype = 'particle' if self._has_sink else 'io'
+
for field, vtype in particle_fields:
if f.tell() >= flen: break
- field_offsets["io", field] = f.tell()
- _pfields["io", field] = vtype
+ field_offsets[ptype, field] = f.tell()
+ _pfields[ptype, field] = vtype
fpu.skip(f, 1)
self.particle_field_offsets = field_offsets
self.particle_field_types = _pfields
- self.particle_types = self.particle_types_raw = ("io",)
def _read_amr_header(self):
hvals = {}
@@ -210,7 +282,7 @@
def _read_amr(self):
"""Open the oct file, read in octs level-by-level.
- For each oct, only the position, index, level and domain
+ For each oct, only the position, index, level and domain
are needed - its position in the octree is found automatically.
The most important is finding all the information to feed
oct_handler.add
@@ -236,7 +308,7 @@
min_level = self.ds.min_level
# yt max level is not the same as the RAMSES one.
# yt max level is the maximum number of additional refinement levels
- # so for a uni grid run with no refinement, it would be 0.
+ # so for a uni grid run with no refinement, it would be 0.
# So we initially assume that.
max_level = 0
nx, ny, nz = (((i-1.0)/2.0) for i in self.amr_header['nx'])
@@ -369,8 +441,12 @@
dsl = set([])
if self.fluid_field_list is None or len(self.fluid_field_list) <= 0:
self._setup_auto_fields()
+
for domain in self.domains:
dsl.update(set(domain.particle_field_offsets.keys()))
+ dsl.update(set(domain.sink_field_offsets.keys()))
+ ptypes = domain.particle_types
+
self.particle_field_list = list(dsl)
self.field_list = [("ramses", f) for f in self.fluid_field_list] \
+ self.particle_field_list
@@ -388,6 +464,7 @@
os.path.dirname(self.dataset.parameter_filename)),
num, testdomain)
hydro_fn = basename % "hydro"
+ sink_fn = basename % "sink"
# Do we have a hydro file?
if not os.path.exists(hydro_fn):
self.fluid_field_list = []
@@ -405,7 +482,7 @@
self.ds.gamma = hvals['gamma']
nvar = hvals['nvar']
# OK, we got NVAR, now set up the arrays depending on what NVAR is
- # but first check for radiative transfer!
+ # but first check for radiative transfer!
foldername = os.path.abspath(os.path.dirname(self.ds.parameter_filename))
rt_flag = any(glob.glob(os.sep.join([foldername, 'info_rt_*.txt'])))
if rt_flag: # rt run
@@ -414,32 +491,32 @@
fields = ["Density", "x-velocity", "y-velocity", "z-velocity", "Pressure", "Metallicity", "HII", "HeII", "HeIII"]
else:
mylog.info('Detected RAMSES-RT file WITH IR trapping.')
- fields = ["Density", "x-velocity", "y-velocity", "z-velocity", "Pres_IR", "Pressure", "Metallicity", "HII", "HeII", "HeIII"]
- else:
+ fields = ["Density", "x-velocity", "y-velocity", "z-velocity", "Pres_IR", "Pressure", "Metallicity", "HII", "HeII", "HeIII"]
+ else:
if nvar < 5:
mylog.debug("nvar=%s is too small! YT doesn't currently support 1D/2D runs in RAMSES %s")
raise ValueError
# Basic hydro runs
if nvar == 5:
fields = ["Density",
- "x-velocity", "y-velocity", "z-velocity",
+ "x-velocity", "y-velocity", "z-velocity",
"Pressure"]
if nvar > 5 and nvar < 11:
- fields = ["Density",
- "x-velocity", "y-velocity", "z-velocity",
+ fields = ["Density",
+ "x-velocity", "y-velocity", "z-velocity",
"Pressure", "Metallicity"]
# MHD runs - NOTE: THE MHD MODULE WILL SILENTLY ADD 3 TO THE NVAR IN THE MAKEFILE
if nvar == 11:
- fields = ["Density",
- "x-velocity", "y-velocity", "z-velocity",
- "x-Bfield-left", "y-Bfield-left", "z-Bfield-left",
- "x-Bfield-right", "y-Bfield-right", "z-Bfield-right",
+ fields = ["Density",
+ "x-velocity", "y-velocity", "z-velocity",
+ "x-Bfield-left", "y-Bfield-left", "z-Bfield-left",
+ "x-Bfield-right", "y-Bfield-right", "z-Bfield-right",
"Pressure"]
if nvar > 11:
- fields = ["Density",
- "x-velocity", "y-velocity", "z-velocity",
- "x-Bfield-left", "y-Bfield-left", "z-Bfield-left",
- "x-Bfield-right", "y-Bfield-right", "z-Bfield-right",
+ fields = ["Density",
+ "x-velocity", "y-velocity", "z-velocity",
+ "x-Bfield-left", "y-Bfield-left", "z-Bfield-left",
+ "x-Bfield-right", "y-Bfield-right", "z-Bfield-right",
"Pressure","Metallicity"]
# Allow some wiggle room for users to add too many variables
while len(fields) < nvar:
@@ -498,9 +575,9 @@
return {'io': npart}
def print_stats(self):
-
+
# This function prints information based on the fluid on the grids,
- # and therefore does not work for DM only runs.
+ # and therefore does not work for DM only runs.
if not self.fluid_field_list:
print("This function is not implemented for DM only runs")
return
@@ -540,7 +617,7 @@
_index_class = RAMSESIndex
_field_info_class = RAMSESFieldInfo
gamma = 1.4 # This will get replaced on hydro_fn open
-
+
def __init__(self, filename, dataset_type='ramses',
fields=None, storage_filename=None,
units_override=None, unit_system="cgs",
@@ -552,7 +629,7 @@
fields: An array of hydro variable fields in order of position in the hydro_XXXXX.outYYYYY file
If set to None, will try a default set of fields
extra_particle_fields: An array of extra particle variables in order of position in the particle_XXXXX.outYYYYY file.
- cosmological: If set to None, automatically detect cosmological simulation. If a boolean, force
+ cosmological: If set to None, automatically detect cosmological simulation. If a boolean, force
its value.
'''
self.fluid_types += ("ramses",)
@@ -561,6 +638,7 @@
self.force_cosmological = cosmological
Dataset.__init__(self, filename, dataset_type, units_override=units_override,
unit_system=unit_system)
+
self.storage_filename = storage_filename
@@ -578,7 +656,7 @@
time_unit = self.parameters['unit_t']
# calculating derived units (except velocity and temperature, done below)
- mass_unit = density_unit * length_unit**3
+ mass_unit = density_unit * length_unit**3
magnetic_unit = np.sqrt(4*np.pi * mass_unit /
(time_unit**2 * length_unit))
pressure_unit = density_unit * (length_unit / time_unit)**2
@@ -685,9 +763,11 @@
self.time_simu = self.t_frw[iage ]*(age-self.tau_frw[iage-1])/(self.tau_frw[iage]-self.tau_frw[iage-1])+ \
self.t_frw[iage-1]*(age-self.tau_frw[iage ])/(self.tau_frw[iage-1]-self.tau_frw[iage])
-
+
self.current_time = (self.time_tot + self.time_simu)/(self.hubble_constant*1e7/3.08e24)/self.parameters['unit_t']
+ self.particle_types = self.particle_types_raw = ('sink', 'particle')
+
@classmethod
def _is_valid(self, *args, **kwargs):
diff -r e6ea9f86b3eeaf95f3ece1ccec8b35253eff4459 -r 1e137c888a30d5a25ba0e6ba42c8fab62067e04c yt/frontends/ramses/fields.py
--- a/yt/frontends/ramses/fields.py
+++ b/yt/frontends/ramses/fields.py
@@ -32,6 +32,7 @@
rho_units = "code_density"
vel_units = "code_velocity"
pressure_units = "code_pressure"
+e_units = "code_mass * code_velocity**2 / code_time**2"
known_species_masses = dict(
(sp, mh * v) for sp, v in [
@@ -89,6 +90,27 @@
("particle_metallicity", ("", [], None)),
)
+ known_sink_fields = (
+ ("particle_position_x", ("code_length", [], None)),
+ ("particle_position_y", ("code_length", [], None)),
+ ("particle_position_z", ("code_length", [], None)),
+ ("particle_velocity_x", (vel_units, [], None)),
+ ("particle_velocity_y", (vel_units, [], None)),
+ ("particle_velocity_z", (vel_units, [], None)),
+ ("particle_mass", ("code_mass", [], None)),
+ ("particle_identifier", ("", ["particle_index"], None)),
+ ("particle_age", ("code_time", ['age'], None)),
+ ("particle_real_accretion", ("code_mass/code_time", [], None)),
+ ("particle_bondi_accretion", ("code_mass/code_time", [], None)),
+ ("particle_eddington_accretion", ("code_mass/code_time", [], None)),
+ ("particle_esave", (e_units, [], None)),
+ ("particle_spin_x", ("", [], None)),
+ ("particle_spin_y", ("", [], None)),
+ ("particle_spin_z", ("", [], None)),
+ ("particle_spin", ("", [], None)),
+ ("particle_efficiency", ("", [], None))
+ )
+
def setup_fluid_fields(self):
def _temperature(field, data):
rv = data["gas", "pressure"]/data["gas", "density"]
diff -r e6ea9f86b3eeaf95f3ece1ccec8b35253eff4459 -r 1e137c888a30d5a25ba0e6ba42c8fab62067e04c yt/frontends/ramses/io.py
--- a/yt/frontends/ramses/io.py
+++ b/yt/frontends/ramses/io.py
@@ -91,28 +91,53 @@
data = np.asarray(rv.pop((ptype, field))[mask], "=f8")
yield (ptype, field), data
- def _read_particle_subset(self, subset, fields):
- f = open(subset.domain.part_fn, "rb")
- foffsets = subset.domain.particle_field_offsets
+ def _generic_handler(self, fname, foffsets, data_types,
+ subset, fields):
tr = {}
- # We do *all* conversion into boxlen here.
- # This means that no other conversions need to be applied to convert
- # positions into the same domain as the octs themselves.
- for field in sorted(fields, key = lambda a: foffsets[a]):
- f.seek(foffsets[field])
- dt = subset.domain.particle_field_types[field]
- tr[field] = fpu.read_vector(f, dt)
- if field[1].startswith("particle_position"):
- np.divide(tr[field], subset.domain.ds["boxlen"], tr[field])
- cosmo = subset.domain.ds.cosmological_simulation
- if cosmo == 1 and field[1] == "particle_age":
- tf = subset.domain.ds.t_frw
- dtau = subset.domain.ds.dtau
- tauf = subset.domain.ds.tau_frw
- tsim = subset.domain.ds.time_simu
- h100 = subset.domain.ds.hubble_constant
- nOver2 = subset.domain.ds.n_frw/2
- t_scale = 1./(h100 * 100 * cm_per_km / cm_per_mpc)/subset.domain.ds['unit_t']
- ages = tr[field]
- tr[field] = get_ramses_ages(tf,tauf,dtau,tsim,t_scale,ages,nOver2,len(ages))
+ with open(fname, "rb") as f:
+ # We do *all* conversion into boxlen here.
+ # This means that no other conversions need to be applied to convert
+ # positions into the same domain as the octs themselves.
+ for field in sorted(fields, key=lambda a: foffsets[a]):
+ f.seek(foffsets[field])
+ dt = data_types[field]
+ tr[field] = fpu.read_vector(f, dt)
+ if field[1].startswith("particle_position"):
+ np.divide(tr[field], subset.domain.ds["boxlen"], tr[field])
+ cosmo = subset.domain.ds.cosmological_simulation
+ if cosmo == 1 and field[1] == "particle_age":
+ tf = subset.domain.ds.t_frw
+ dtau = subset.domain.ds.dtau
+ tauf = subset.domain.ds.tau_frw
+ tsim = subset.domain.ds.time_simu
+ h100 = subset.domain.ds.hubble_constant
+ nOver2 = subset.domain.ds.n_frw/2
+ t_scale = 1./(h100 * 100 * cm_per_km / cm_per_mpc)/subset.domain.ds['unit_t']
+ ages = tr[field]
+ tr[field] = get_ramses_ages(tf,tauf,dtau,tsim,t_scale,ages,nOver2,len(ages))
return tr
+
+
+ def _read_particle_subset(self, subset, fields):
+ tr = {}
+
+ # Read the particles by types (particle, sinks)
+ for ptype in set(f[0] for f in fields):
+
+ # Group by particle type
+ subs_fields = filter(lambda f: f[0] == ptype, fields)
+
+ if ptype in ['particle', 'io']:
+ fname = subset.domain.part_fn
+ foffsets = subset.domain.particle_field_offsets
+ data_types = subset.domain.particle_field_types
+
+ elif ptype in ['sink']:
+ fname = subset.domain.sink_fn
+ foffsets = subset.domain.sink_field_offsets
+ data_types = subset.domain.sink_field_types
+
+ tr.update(self._generic_handler(fname, foffsets, data_types,
+ subset, subs_fields))
+
+ return tr
https://bitbucket.org/yt_analysis/yt/commits/c4bd4c3b442f/
Changeset: c4bd4c3b442f
User: Corentin Cadiou
Date: 2017-09-04 14:59:59+00:00
Summary: passes flake8
Affected #: 1 file
diff -r 1e137c888a30d5a25ba0e6ba42c8fab62067e04c -r c4bd4c3b442ff3ca1be31c1bf0ad1195b51957c8 yt/frontends/ramses/data_structures.py
--- a/yt/frontends/ramses/data_structures.py
+++ b/yt/frontends/ramses/data_structures.py
@@ -445,7 +445,6 @@
for domain in self.domains:
dsl.update(set(domain.particle_field_offsets.keys()))
dsl.update(set(domain.sink_field_offsets.keys()))
- ptypes = domain.particle_types
self.particle_field_list = list(dsl)
self.field_list = [("ramses", f) for f in self.fluid_field_list] \
@@ -464,12 +463,11 @@
os.path.dirname(self.dataset.parameter_filename)),
num, testdomain)
hydro_fn = basename % "hydro"
- sink_fn = basename % "sink"
# Do we have a hydro file?
if not os.path.exists(hydro_fn):
self.fluid_field_list = []
return
- # Read the number of hydro variables
+ # Read the number of hydro variables
f = open(hydro_fn, "rb")
hydro_header = ( ('ncpu', 1, 'i'),
('nvar', 1, 'i'),
https://bitbucket.org/yt_analysis/yt/commits/323bdd5a7461/
Changeset: 323bdd5a7461
User: Corentin Cadiou
Date: 2017-09-04 15:07:04+00:00
Summary: add exception
Affected #: 1 file
diff -r c4bd4c3b442ff3ca1be31c1bf0ad1195b51957c8 -r 323bdd5a7461e4d5a4f406aa1caa34cede77d77e yt/frontends/ramses/io.py
--- a/yt/frontends/ramses/io.py
+++ b/yt/frontends/ramses/io.py
@@ -24,6 +24,7 @@
from yt.utilities.lib.cosmology_time import \
get_ramses_ages
from yt.extern.six import PY3
+from yt.utilities.exceptions import YTFieldNotFound
if PY3:
from io import BytesIO as IO
@@ -137,6 +138,10 @@
foffsets = subset.domain.sink_field_offsets
data_types = subset.domain.sink_field_types
+ else:
+ # Raise here an exception
+ raise Exception('Unknown field %s' % ptype)
+
tr.update(self._generic_handler(fname, foffsets, data_types,
subset, subs_fields))
https://bitbucket.org/yt_analysis/yt/commits/b57a079c758d/
Changeset: b57a079c758d
User: Corentin Cadiou
Date: 2017-09-04 15:19:36+00:00
Summary: fix units + fields
Affected #: 2 files
diff -r 323bdd5a7461e4d5a4f406aa1caa34cede77d77e -r b57a079c758d517d7b2b04ac544de4927da27c2a yt/frontends/ramses/data_structures.py
--- a/yt/frontends/ramses/data_structures.py
+++ b/yt/frontends/ramses/data_structures.py
@@ -169,15 +169,18 @@
("particle_velocity_y", "d"),
("particle_velocity_z", "d"),
("particle_age", "d"),
- ("real_accretion", "d"),
- ("bondi_accretion", "d"),
- ("eddington_accretion", "d"),
- ("esave", "d"),
- ("spin_x", "d"),
- ("spin_y", "d"),
- ("spin_z", "d"),
- ("spin", "d"),
- ("efficiency", "d")]
+ ("BH_real_accretion", "d"),
+ ("BH_bondi_accretion", "d"),
+ ("BH_eddington_accretion", "d"),
+ ("BH_esave", "d"),
+ ("gas_spin_x", "d"),
+ ("gas_spin_y", "d"),
+ ("gas_spin_z", "d"),
+ ("BH_spin_x", "d"),
+ ("BH_spin_y", "d"),
+ ("BH_spin_z", "d"),
+ ("BH_spin", "d"),
+ ("BH_efficiency", "d")]
for i in range(self.ds.dimensionality*2+1):
for j in range(self.ds.max_level, self.ds.min_level):
diff -r 323bdd5a7461e4d5a4f406aa1caa34cede77d77e -r b57a079c758d517d7b2b04ac544de4927da27c2a yt/frontends/ramses/fields.py
--- a/yt/frontends/ramses/fields.py
+++ b/yt/frontends/ramses/fields.py
@@ -33,6 +33,7 @@
vel_units = "code_velocity"
pressure_units = "code_pressure"
e_units = "code_mass * code_velocity**2 / code_time**2"
+am_units = "code_mass * code_velocity * code_length"
known_species_masses = dict(
(sp, mh * v) for sp, v in [
@@ -100,15 +101,18 @@
("particle_mass", ("code_mass", [], None)),
("particle_identifier", ("", ["particle_index"], None)),
("particle_age", ("code_time", ['age'], None)),
- ("particle_real_accretion", ("code_mass/code_time", [], None)),
- ("particle_bondi_accretion", ("code_mass/code_time", [], None)),
- ("particle_eddington_accretion", ("code_mass/code_time", [], None)),
- ("particle_esave", (e_units, [], None)),
- ("particle_spin_x", ("", [], None)),
- ("particle_spin_y", ("", [], None)),
- ("particle_spin_z", ("", [], None)),
- ("particle_spin", ("", [], None)),
- ("particle_efficiency", ("", [], None))
+ ("BH_real_accretion", ("code_mass/code_time", [], None)),
+ ("BH_bondi_accretion", ("code_mass/code_time", [], None)),
+ ("BH_eddington_accretion", ("code_mass/code_time", [], None)),
+ ("BH_esave", (e_units, [], None)),
+ ("gas_spin_x", (am_units, [], None)),
+ ("gas_spin_y", (am_units, [], None)),
+ ("gas_spin_z", (am_units, [], None)),
+ ("BH_spin_x", ("", [], None)),
+ ("BH_spin_y", ("", [], None)),
+ ("BH_spin_z", ("", [], None)),
+ ("BH_spin", (am_units, [], None)),
+ ("BH_efficiency", ("", [], None))
)
def setup_fluid_fields(self):
https://bitbucket.org/yt_analysis/yt/commits/2e28ccccf604/
Changeset: 2e28ccccf604
User: Corentin Cadiou
Date: 2017-09-06 08:03:08+00:00
Summary: default particle type: io
Affected #: 2 files
diff -r b57a079c758d517d7b2b04ac544de4927da27c2a -r 2e28ccccf604605a5981c97444b63017d7b273a9 yt/frontends/ramses/data_structures.py
--- a/yt/frontends/ramses/data_structures.py
+++ b/yt/frontends/ramses/data_structures.py
@@ -249,7 +249,7 @@
field_offsets = {}
_pfields = {}
- ptype = 'particle' if self._has_sink else 'io'
+ ptype = 'io'
for field, vtype in particle_fields:
if f.tell() >= flen: break
@@ -767,7 +767,13 @@
self.current_time = (self.time_tot + self.time_simu)/(self.hubble_constant*1e7/3.08e24)/self.parameters['unit_t']
- self.particle_types = self.particle_types_raw = ('sink', 'particle')
+ if self.index.domains[0]._has_sink:
+ ptypes = ('io', 'sink')
+ else:
+ ptypes = ('io', )
+
+ self.particle_types = self.particle_types_raw = ptypes
+
@classmethod
diff -r b57a079c758d517d7b2b04ac544de4927da27c2a -r 2e28ccccf604605a5981c97444b63017d7b273a9 yt/frontends/ramses/io.py
--- a/yt/frontends/ramses/io.py
+++ b/yt/frontends/ramses/io.py
@@ -128,19 +128,19 @@
# Group by particle type
subs_fields = filter(lambda f: f[0] == ptype, fields)
- if ptype in ['particle', 'io']:
+ if ptype == 'particle':
fname = subset.domain.part_fn
foffsets = subset.domain.particle_field_offsets
data_types = subset.domain.particle_field_types
- elif ptype in ['sink']:
+ elif ptype == 'sink':
fname = subset.domain.sink_fn
foffsets = subset.domain.sink_field_offsets
data_types = subset.domain.sink_field_types
else:
# Raise here an exception
- raise Exception('Unknown field %s' % ptype)
+ raise Exception('Unknown particle type %s' % ptype)
tr.update(self._generic_handler(fname, foffsets, data_types,
subset, subs_fields))
https://bitbucket.org/yt_analysis/yt/commits/d2c1bf5889bc/
Changeset: d2c1bf5889bc
User: Corentin Cadiou
Date: 2017-09-06 08:11:33+00:00
Summary: autodetect sinks
Affected #: 1 file
diff -r 2e28ccccf604605a5981c97444b63017d7b273a9 -r d2c1bf5889bc8d2ced9b23db4c6813b0ec1385b6 yt/frontends/ramses/data_structures.py
--- a/yt/frontends/ramses/data_structures.py
+++ b/yt/frontends/ramses/data_structures.py
@@ -767,7 +767,12 @@
self.current_time = (self.time_tot + self.time_simu)/(self.hubble_constant*1e7/3.08e24)/self.parameters['unit_t']
- if self.index.domains[0]._has_sink:
+ sink_files = os.path.join(
+ os.path.split(self.parameter_filename)[0],
+ 'sink_?????.out?????')
+ has_sink = len(glob.glob(sink_files))
+
+ if has_sink:
ptypes = ('io', 'sink')
else:
ptypes = ('io', )
https://bitbucket.org/yt_analysis/yt/commits/6f93d125f68d/
Changeset: 6f93d125f68d
User: Corentin Cadiou
Date: 2017-09-06 08:13:49+00:00
Summary: fix particle type in io
Affected #: 1 file
diff -r d2c1bf5889bc8d2ced9b23db4c6813b0ec1385b6 -r 6f93d125f68dd9434a6176119e51bf0e6e6926f0 yt/frontends/ramses/io.py
--- a/yt/frontends/ramses/io.py
+++ b/yt/frontends/ramses/io.py
@@ -128,7 +128,7 @@
# Group by particle type
subs_fields = filter(lambda f: f[0] == ptype, fields)
- if ptype == 'particle':
+ if ptype == 'io':
fname = subset.domain.part_fn
foffsets = subset.domain.particle_field_offsets
data_types = subset.domain.particle_field_types
https://bitbucket.org/yt_analysis/yt/commits/97f1050797d6/
Changeset: 97f1050797d6
User: Corentin Cadiou
Date: 2017-09-07 11:38:38+00:00
Summary: flak8
Affected #: 1 file
diff -r 6f93d125f68dd9434a6176119e51bf0e6e6926f0 -r 97f1050797d6843a4af0aaf74fbde84bfc8a715c yt/frontends/ramses/io.py
--- a/yt/frontends/ramses/io.py
+++ b/yt/frontends/ramses/io.py
@@ -24,7 +24,6 @@
from yt.utilities.lib.cosmology_time import \
get_ramses_ages
from yt.extern.six import PY3
-from yt.utilities.exceptions import YTFieldNotFound
if PY3:
from io import BytesIO as IO
https://bitbucket.org/yt_analysis/yt/commits/8d9c463a2fcf/
Changeset: 8d9c463a2fcf
User: Corentin Cadiou
Date: 2017-09-07 11:41:48+00:00
Summary: add test
Affected #: 1 file
diff -r 97f1050797d6843a4af0aaf74fbde84bfc8a715c -r 8d9c463a2fcf804305bca4a41d389592d50083bb yt/frontends/ramses/tests/test_outputs.py
--- a/yt/frontends/ramses/tests/test_outputs.py
+++ b/yt/frontends/ramses/tests/test_outputs.py
@@ -154,3 +154,30 @@
for field in special_fields:
assert(field in ds.derived_field_list)
ad[field]
+
+
+ramses_sink = "ramses_sink_00016/output_00016/info_00016.txt"
+ at requires_file(ramses_sink)
+def test_ramses_sink():
+ ds = yt.load(ramses_sink)
+ ad = ds.all_data()
+
+ expected_fields = ["BH_bondi_accretion", "BH_eddington_accretion",
+ "BH_efficiency", "BH_esave",
+ "BH_real_accretion", "BH_spin", "BH_spin_x",
+ "BH_spin_y", "BH_spin_z", "gas_spin_x",
+ "gas_spin_y", "gas_spin_z", "particle_age",
+ "particle_identifier", "particle_mass",
+ "particle_position_x", "particle_position_y",
+ "particle_position_z", "particle_prop_0_0",
+ "particle_prop_0_1", "particle_prop_0_2",
+ "particle_prop_0_3", "particle_prop_1_0",
+ "particle_prop_1_1", "particle_prop_1_2",
+ "particle_velocity_x", "particle_velocity_y",
+ "particle_velocity_z"]
+
+ for field in expected_fields:
+ assert(('sink', field) in ds.field_list)
+
+ # test that field access works
+ ad['sink', field]
https://bitbucket.org/yt_analysis/yt/commits/8099e2402c52/
Changeset: 8099e2402c52
User: Corentin Cadiou
Date: 2017-09-07 11:50:28+00:00
Summary: checking that sinks are *only* detected as necessary
Affected #: 1 file
diff -r 8d9c463a2fcf804305bca4a41d389592d50083bb -r 8099e2402c52842e1a70281c4008930c26658265 yt/frontends/ramses/tests/test_outputs.py
--- a/yt/frontends/ramses/tests/test_outputs.py
+++ b/yt/frontends/ramses/tests/test_outputs.py
@@ -158,10 +158,8 @@
ramses_sink = "ramses_sink_00016/output_00016/info_00016.txt"
@requires_file(ramses_sink)
+ at requires_file(ramsesNonCosmo)
def test_ramses_sink():
- ds = yt.load(ramses_sink)
- ad = ds.all_data()
-
expected_fields = ["BH_bondi_accretion", "BH_eddington_accretion",
"BH_efficiency", "BH_esave",
"BH_real_accretion", "BH_spin", "BH_spin_x",
@@ -176,8 +174,20 @@
"particle_velocity_x", "particle_velocity_y",
"particle_velocity_z"]
+ # Check that sinks are autodetected
+ ds = yt.load(ramses_sink)
+ ad = ds.all_data()
+
for field in expected_fields:
assert(('sink', field) in ds.field_list)
# test that field access works
ad['sink', field]
+
+
+ # Checking that sinks are autodetected
+ ds = yt.load(ramsesCosmo)
+ ad = ds.all_data()
+
+ for field in expected_fields:
+ assert(('sink', 'field') not in ds.field_list)
https://bitbucket.org/yt_analysis/yt/commits/c44a48e296e9/
Changeset: c44a48e296e9
User: Corentin Cadiou
Date: 2017-09-07 11:58:34+00:00
Summary: add documentation
Affected #: 1 file
diff -r 8099e2402c52842e1a70281c4008930c26658265 -r c44a48e296e95870d4aba21c50727240bd36eb55 doc/source/examining/loading_data.rst
--- a/doc/source/examining/loading_data.rst
+++ b/doc/source/examining/loading_data.rst
@@ -1988,13 +1988,21 @@
yt supports outputs made by the mainline ``RAMSES`` code as well as the
``RAMSES-RT`` fork. Files produces by ``RAMSES-RT`` are recognized as such
-based on the presence of a ``into_rt_*.txt`` file in the output directory.
+based on the presence of a ``info_rt_*.txt`` file in the output directory.
It is possible to force yt to treat the simulation as a cosmological
simulation by providing the ``cosmological=True`` parameter (or
``False`` to force non-cosmology). If left to ``None``, the kind of
the simulation is inferred from the data.
+yt also support outputs that include sinks (RAMSES' name for black
+holes) when the folder contains files like ``sink_XXXXX.outYYYYY``.
+
+Note: for backward compatibility, particles from the
+``particle_XXXXX.outYYYYY`` files have the particle type ``io`` by
+default (including dark matter, stars, tracer particles, …). Sink
+particles have the particle type ``sink``.
+
.. _loading-sph-data:
SPH Particle Data
https://bitbucket.org/yt_analysis/yt/commits/124cc374b0f9/
Changeset: 124cc374b0f9
User: Corentin Cadiou
Date: 2017-09-07 12:05:40+00:00
Summary: add coments
Affected #: 2 files
diff -r c44a48e296e95870d4aba21c50727240bd36eb55 -r 124cc374b0f970caf244afd8e156f61ff5748e50 yt/frontends/ramses/data_structures.py
--- a/yt/frontends/ramses/data_structures.py
+++ b/yt/frontends/ramses/data_structures.py
@@ -767,6 +767,7 @@
self.current_time = (self.time_tot + self.time_simu)/(self.hubble_constant*1e7/3.08e24)/self.parameters['unit_t']
+ # Check for the presence of sink files
sink_files = os.path.join(
os.path.split(self.parameter_filename)[0],
'sink_?????.out?????')
diff -r c44a48e296e95870d4aba21c50727240bd36eb55 -r 124cc374b0f970caf244afd8e156f61ff5748e50 yt/frontends/ramses/io.py
--- a/yt/frontends/ramses/io.py
+++ b/yt/frontends/ramses/io.py
@@ -93,6 +93,16 @@
def _generic_handler(self, fname, foffsets, data_types,
subset, fields):
+ '''General file handler, called by _read_particle_subset
+
+ params:
+ -------
+ fname: filename to read from
+ foffsets: dictionary-like of the offset for the fields
+ data_types: dictionary_like of the data type for the fields
+ subset: a subset object
+ fields: list of fields to read
+ '''
tr = {}
with open(fname, "rb") as f:
# We do *all* conversion into boxlen here.
@@ -119,12 +129,13 @@
def _read_particle_subset(self, subset, fields):
+ '''Read the particle files.'''
tr = {}
- # Read the particles by types (particle, sinks)
+ # Sequential read depending on particle type (io or sink)
for ptype in set(f[0] for f in fields):
- # Group by particle type
+ # Select relevant fiels
subs_fields = filter(lambda f: f[0] == ptype, fields)
if ptype == 'io':
https://bitbucket.org/yt_analysis/yt/commits/605a166f4429/
Changeset: 605a166f4429
User: Corentin Cadiou
Date: 2017-09-13 15:34:35+00:00
Summary: more explicit unit names
Affected #: 1 file
diff -r 124cc374b0f970caf244afd8e156f61ff5748e50 -r 605a166f4429e712179f5e77f4079141301923a9 yt/frontends/ramses/fields.py
--- a/yt/frontends/ramses/fields.py
+++ b/yt/frontends/ramses/fields.py
@@ -32,8 +32,8 @@
rho_units = "code_density"
vel_units = "code_velocity"
pressure_units = "code_pressure"
-e_units = "code_mass * code_velocity**2 / code_time**2"
-am_units = "code_mass * code_velocity * code_length"
+ener_units = "code_mass * code_velocity**2 / code_time**2"
+ang_mom_units = "code_mass * code_velocity * code_length"
known_species_masses = dict(
(sp, mh * v) for sp, v in [
@@ -104,14 +104,14 @@
("BH_real_accretion", ("code_mass/code_time", [], None)),
("BH_bondi_accretion", ("code_mass/code_time", [], None)),
("BH_eddington_accretion", ("code_mass/code_time", [], None)),
- ("BH_esave", (e_units, [], None)),
- ("gas_spin_x", (am_units, [], None)),
- ("gas_spin_y", (am_units, [], None)),
- ("gas_spin_z", (am_units, [], None)),
+ ("BH_esave", (ener_units, [], None)),
+ ("gas_spin_x", (ang_mom_units, [], None)),
+ ("gas_spin_y", (ang_mom_units, [], None)),
+ ("gas_spin_z", (ang_mom_units, [], None)),
("BH_spin_x", ("", [], None)),
("BH_spin_y", ("", [], None)),
("BH_spin_z", ("", [], None)),
- ("BH_spin", (am_units, [], None)),
+ ("BH_spin", (ang_mom_units, [], None)),
("BH_efficiency", ("", [], None))
)
https://bitbucket.org/yt_analysis/yt/commits/9e8e1512578c/
Changeset: 9e8e1512578c
User: Corentin Cadiou
Date: 2017-09-13 15:34:49+00:00
Summary: move generic file handler to own function
Affected #: 1 file
diff -r 605a166f4429e712179f5e77f4079141301923a9 -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 yt/frontends/ramses/io.py
--- a/yt/frontends/ramses/io.py
+++ b/yt/frontends/ramses/io.py
@@ -30,6 +30,48 @@
else:
from cStringIO import StringIO as IO
+def _ramses_particle_file_handler(fname, foffsets, data_types,
+ subset, fields):
+ '''General file handler, called by _read_particle_subset
+
+ Parameters
+ ----------
+ fname : string
+ filename to read from
+ foffsets: dict
+ Offsets in file of the fields
+ data_types: dict
+ Data type of the fields
+ subset: ``RAMSESDomainSubset``
+ A RAMSES domain subset object
+ fields: list of tuple
+ The fields to read
+ '''
+ tr = {}
+ with open(fname, "rb") as f:
+ # We do *all* conversion into boxlen here.
+ # This means that no other conversions need to be applied to convert
+ # positions into the same domain as the octs themselves.
+ for field in sorted(fields, key=lambda a: foffsets[a]):
+ f.seek(foffsets[field])
+ dt = data_types[field]
+ tr[field] = fpu.read_vector(f, dt)
+ if field[1].startswith("particle_position"):
+ np.divide(tr[field], subset.domain.ds["boxlen"], tr[field])
+ cosmo = subset.domain.ds.cosmological_simulation
+ if cosmo == 1 and field[1] == "particle_age":
+ tf = subset.domain.ds.t_frw
+ dtau = subset.domain.ds.dtau
+ tauf = subset.domain.ds.tau_frw
+ tsim = subset.domain.ds.time_simu
+ h100 = subset.domain.ds.hubble_constant
+ nOver2 = subset.domain.ds.n_frw/2
+ t_scale = 1./(h100 * 100 * cm_per_km / cm_per_mpc)/subset.domain.ds['unit_t']
+ ages = tr[field]
+ tr[field] = get_ramses_ages(tf,tauf,dtau,tsim,t_scale,ages,nOver2,len(ages))
+ return tr
+
+
class IOHandlerRAMSES(BaseIOHandler):
_dataset_type = "ramses"
@@ -91,42 +133,6 @@
data = np.asarray(rv.pop((ptype, field))[mask], "=f8")
yield (ptype, field), data
- def _generic_handler(self, fname, foffsets, data_types,
- subset, fields):
- '''General file handler, called by _read_particle_subset
-
- params:
- -------
- fname: filename to read from
- foffsets: dictionary-like of the offset for the fields
- data_types: dictionary_like of the data type for the fields
- subset: a subset object
- fields: list of fields to read
- '''
- tr = {}
- with open(fname, "rb") as f:
- # We do *all* conversion into boxlen here.
- # This means that no other conversions need to be applied to convert
- # positions into the same domain as the octs themselves.
- for field in sorted(fields, key=lambda a: foffsets[a]):
- f.seek(foffsets[field])
- dt = data_types[field]
- tr[field] = fpu.read_vector(f, dt)
- if field[1].startswith("particle_position"):
- np.divide(tr[field], subset.domain.ds["boxlen"], tr[field])
- cosmo = subset.domain.ds.cosmological_simulation
- if cosmo == 1 and field[1] == "particle_age":
- tf = subset.domain.ds.t_frw
- dtau = subset.domain.ds.dtau
- tauf = subset.domain.ds.tau_frw
- tsim = subset.domain.ds.time_simu
- h100 = subset.domain.ds.hubble_constant
- nOver2 = subset.domain.ds.n_frw/2
- t_scale = 1./(h100 * 100 * cm_per_km / cm_per_mpc)/subset.domain.ds['unit_t']
- ages = tr[field]
- tr[field] = get_ramses_ages(tf,tauf,dtau,tsim,t_scale,ages,nOver2,len(ages))
- return tr
-
def _read_particle_subset(self, subset, fields):
'''Read the particle files.'''
@@ -152,7 +158,7 @@
# Raise here an exception
raise Exception('Unknown particle type %s' % ptype)
- tr.update(self._generic_handler(fname, foffsets, data_types,
- subset, subs_fields))
+ tr.update(_ramses_particle_file_handler(
+ fname, foffsets, data_types, subset, subs_fields))
return tr
https://bitbucket.org/yt_analysis/yt/commits/309210b5e7f3/
Changeset: 309210b5e7f3
User: Corentin Cadiou
Date: 2017-10-06 11:49:40+00:00
Summary: Merge branch 'master' into feature/RAMSES-sinks
Affected #: 21 files
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd .travis.yml
--- a/.travis.yml
+++ b/.travis.yml
@@ -20,11 +20,12 @@
SCIPY=scipy
IPYTHON=ipython
FASTCACHE=fastcache
+ FLAKE8=flake8
matrix:
include:
- python: 2.7
- env: NUMPY=numpy==1.10.4 CYTHON=cython==0.24 MATPLOTLIB=matplotlib==1.5.3 SYMPY=sympy==1.0 H5PY= SCIPY= FASTCACHE= IPYTHON=ipython==1.0
+ env: NUMPY=numpy==1.10.4 CYTHON=cython==0.24 MATPLOTLIB=matplotlib==1.5.3 SYMPY=sympy==1.0 H5PY= SCIPY= FASTCACHE= FLAKE8= IPYTHON=ipython==1.0
- python: 2.7
- python: 3.4
- python: 3.5
@@ -65,7 +66,7 @@
pip install --upgrade wheel
pip install --upgrade setuptools
# Install dependencies
- pip install mock $NUMPY $SCIPY $H5PY $CYTHON $MATPLOTLIB $SYMPY $FASTCACHE $IPYTHON nose flake8 nose-timer
+ pip install mock $NUMPY $SCIPY $H5PY $CYTHON $MATPLOTLIB $SYMPY $FASTCACHE $IPYTHON $FLAKE8 nose nose-timer
# install yt
pip install -e .
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd doc/source/analyzing/units/2)_Fields_and_unit_conversion.ipynb
--- a/doc/source/analyzing/units/2)_Fields_and_unit_conversion.ipynb
+++ b/doc/source/analyzing/units/2)_Fields_and_unit_conversion.ipynb
@@ -322,7 +322,20 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "Since we have a copy of the data, we can mess with it however we wish without disturbing the original data returned by the yt data object."
+ "Since we have a copy of the data, we can mess with it however we wish without disturbing the original data returned by the yt data object.\n",
+ "\n",
+ "There is yet another way to return a copy of the array data in a `YTArray` or the floating-point value of a `YTQuantity`, which also allows for the possibility to convert to different units. This is done using the `to_value` method:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(dens.to_value()) # Don't change units\n",
+ "print(dens.to_value(\"Msun\")) # Change units to solar masses\n",
+ "print(dens[0].to_value(\"lbm\")) # Pick the first value and change its units to pounds"
]
},
{
@@ -388,7 +401,9 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {},
+ "metadata": {
+ "collapsed": true
+ },
"outputs": [],
"source": [
"from astropy import units as u\n",
@@ -410,7 +425,9 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {},
+ "metadata": {
+ "collapsed": true
+ },
"outputs": [],
"source": [
"a = np.random.random(size=10) * u.km/u.s\n",
@@ -437,7 +454,9 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {},
+ "metadata": {
+ "collapsed": true
+ },
"outputs": [],
"source": [
"temp = dd[\"temperature\"]\n",
@@ -464,7 +483,9 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {},
+ "metadata": {
+ "collapsed": true
+ },
"outputs": [],
"source": [
"from yt.units import kboltz\n",
@@ -496,7 +517,8 @@
"source": [
"k1 = kboltz.to_astropy()\n",
"k2 = yt.YTQuantity.from_astropy(kb)\n",
- "print (k1 == k2)"
+ "print(k1)\n",
+ "print(k2)"
]
},
{
@@ -520,7 +542,9 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {},
+ "metadata": {
+ "collapsed": true
+ },
"outputs": [],
"source": [
"from pint import UnitRegistry\n",
@@ -542,7 +566,9 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {},
+ "metadata": {
+ "collapsed": true
+ },
"outputs": [],
"source": [
"ptemp = temp.to_pint()"
@@ -593,9 +619,7 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": false
- },
+ "metadata": {},
"outputs": [],
"source": [
"from yt.units import clight\n",
@@ -612,9 +636,7 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": false
- },
+ "metadata": {},
"outputs": [],
"source": [
"from yt import YTQuantity\n",
@@ -633,7 +655,7 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
- "collapsed": false
+ "collapsed": true
},
"outputs": [],
"source": [
@@ -643,9 +665,7 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": false
- },
+ "metadata": {},
"outputs": [],
"source": [
"dd = ds.all_data()\n",
@@ -655,23 +675,23 @@
],
"metadata": {
"kernelspec": {
- "display_name": "Python 3",
+ "display_name": "Python [default]",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
- "version": 3.0
+ "version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.5.1"
+ "version": "3.6.1"
}
},
"nbformat": 4,
- "nbformat_minor": 0
+ "nbformat_minor": 1
}
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd doc/source/analyzing/units/6)_Unit_Equivalencies.ipynb
--- a/doc/source/analyzing/units/6)_Unit_Equivalencies.ipynb
+++ b/doc/source/analyzing/units/6)_Unit_Equivalencies.ipynb
@@ -18,15 +18,13 @@
"* `\"number_density\"`: conversions between density and number density ($n = \\rho/\\mu{m_p}$)\n",
"* `\"sound_speed\"`: conversions between temperature and sound speed for an ideal gas ($c_s^2 = \\gamma{k_BT}/\\mu{m_p}$)\n",
"\n",
- "A `YTArray` or `YTQuantity` can be converted to an equivalent using `to_equivalent`, where the unit and the equivalence name are provided as arguments:"
+ "A `YTArray` or `YTQuantity` can be converted to an equivalent using `in_units` (previously described in [Fields and Unit Conversion](fields_and_unit_conversion.html)), where the unit and the equivalence name are provided as additional arguments:"
]
},
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": false
- },
+ "metadata": {},
"outputs": [],
"source": [
"import yt\n",
@@ -37,12 +35,12 @@
"\n",
"dd = ds.all_data()\n",
"\n",
- "print (dd[\"temperature\"].to_equivalent(\"erg\", \"thermal\"))\n",
- "print (dd[\"temperature\"].to_equivalent(\"eV\", \"thermal\"))\n",
+ "print (dd[\"temperature\"].in_units(\"erg\", equivalence=\"thermal\"))\n",
+ "print (dd[\"temperature\"].in_units(\"eV\", equivalence=\"thermal\"))\n",
"\n",
"# Rest energy of the proton\n",
"from yt.units import mp\n",
- "E_p = mp.to_equivalent(\"GeV\", \"mass_energy\")\n",
+ "E_p = mp.in_units(\"GeV\", equivalence=\"mass_energy\")\n",
"print (E_p)"
]
},
@@ -56,16 +54,31 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": false
- },
+ "metadata": {},
"outputs": [],
"source": [
"from yt.units import clight\n",
"v = 0.1*clight\n",
- "g = v.to_equivalent(\"dimensionless\", \"lorentz\")\n",
+ "g = v.in_units(\"dimensionless\", equivalence=\"lorentz\")\n",
"print (g)\n",
- "print (g.to_equivalent(\"c\", \"lorentz\"))"
+ "print (g.in_units(\"c\", equivalence=\"lorentz\"))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The previously described `to_value` method, which works like `in_units` except that it returns a bare NumPy array or floating-point number, also accepts equivalencies:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print (dd[\"temperature\"].to_value(\"erg\", equivalence=\"thermal\"))\n",
+ "print (mp.to_value(\"GeV\", equivalence=\"mass_energy\"))"
]
},
{
@@ -85,14 +98,12 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": false
- },
+ "metadata": {},
"outputs": [],
"source": [
"print (dd[\"density\"].max())\n",
- "print (dd[\"density\"].to_equivalent(\"cm**-3\", \"number_density\").max())\n",
- "print (dd[\"density\"].to_equivalent(\"cm**-3\", \"number_density\", mu=0.75).max())"
+ "print (dd[\"density\"].in_units(\"cm**-3\", equivalence=\"number_density\").max())\n",
+ "print (dd[\"density\"].in_units(\"cm**-3\", equivalence=\"number_density\", mu=0.75).max())"
]
},
{
@@ -105,13 +116,11 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": false
- },
+ "metadata": {},
"outputs": [],
"source": [
- "print (dd[\"temperature\"].to_equivalent(\"km/s\", \"sound_speed\").mean())\n",
- "print (dd[\"temperature\"].to_equivalent(\"km/s\", \"sound_speed\", gamma=4./3., mu=0.5).mean())"
+ "print (dd[\"temperature\"].in_units(\"km/s\", equivalence=\"sound_speed\").mean())\n",
+ "print (dd[\"temperature\"].in_units(\"km/s\", equivalence=\"sound_speed\", gamma=4./3., mu=0.5).mean())"
]
},
{
@@ -138,9 +147,7 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": false
- },
+ "metadata": {},
"outputs": [],
"source": [
"Q1 = YTQuantity(1.0,\"C\")\n",
@@ -161,13 +168,11 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": false
- },
+ "metadata": {},
"outputs": [],
"source": [
"from yt.units import qp # the elementary charge in esu\n",
- "qp_SI = qp.to_equivalent(\"C\",\"SI\") # convert to Coulombs\n",
+ "qp_SI = qp.in_units(\"C\", equivalence=\"SI\") # convert to Coulombs\n",
"print (qp)\n",
"print (qp_SI)"
]
@@ -182,13 +187,11 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": false
- },
+ "metadata": {},
"outputs": [],
"source": [
"B = YTQuantity(1.0,\"T\") # magnetic field in Tesla\n",
- "print (B, B.to_equivalent(\"gauss\",\"CGS\")) # convert to Gauss"
+ "print (B, B.in_units(\"gauss\", equivalence=\"CGS\")) # convert to Gauss"
]
},
{
@@ -201,15 +204,13 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": false
- },
+ "metadata": {},
"outputs": [],
"source": [
"I = YTQuantity(1.0,\"A\")\n",
- "I_cgs = I.to_equivalent(\"statA\",\"CGS\")\n",
+ "I_cgs = I.in_units(\"statA\", equivalence=\"CGS\")\n",
"R = YTQuantity(1.0,\"ohm\")\n",
- "R_cgs = R.to_equivalent(\"statohm\",\"CGS\")\n",
+ "R_cgs = R.in_units(\"statohm\", equivalence=\"CGS\")\n",
"P = I**2*R\n",
"P_cgs = I_cgs**2*R_cgs"
]
@@ -224,9 +225,7 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": false
- },
+ "metadata": {},
"outputs": [],
"source": [
"print (P_cgs.units.dimensions == P.units.dimensions)\n",
@@ -250,15 +249,13 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": false
- },
+ "metadata": {},
"outputs": [],
"source": [
"from yt.utilities.exceptions import YTInvalidUnitEquivalence\n",
"\n",
"try:\n",
- " x = v.to_equivalent(\"angstrom\", \"spectral\")\n",
+ " x = v.in_units(\"angstrom\", equivalence=\"spectral\")\n",
"except YTInvalidUnitEquivalence as e:\n",
" print (e)"
]
@@ -273,9 +270,7 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": false
- },
+ "metadata": {},
"outputs": [],
"source": [
"print (mp.has_equivalent(\"compton\"))\n",
@@ -292,9 +287,7 @@
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": false
- },
+ "metadata": {},
"outputs": [],
"source": [
"E_p.list_equivalencies()"
@@ -303,7 +296,7 @@
],
"metadata": {
"kernelspec": {
- "display_name": "Python 3",
+ "display_name": "Python [default]",
"language": "python",
"name": "python3"
},
@@ -317,9 +310,9 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.5.1"
+ "version": "3.6.1"
}
},
"nbformat": 4,
- "nbformat_minor": 0
+ "nbformat_minor": 1
}
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd doc/source/analyzing/units/fields_and_unit_conversion.rst
--- a/doc/source/analyzing/units/fields_and_unit_conversion.rst
+++ b/doc/source/analyzing/units/fields_and_unit_conversion.rst
@@ -1,4 +1,4 @@
-.. _data_selection_and_fields:
+.. _fields_and_unit_conversion:
Fields and Unit Conversion
==========================
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd yt/analysis_modules/halo_analysis/halo_catalog.py
--- a/yt/analysis_modules/halo_analysis/halo_catalog.py
+++ b/yt/analysis_modules/halo_analysis/halo_catalog.py
@@ -20,6 +20,7 @@
save_as_dataset
from yt.funcs import \
ensure_dir, \
+ get_pbar, \
mylog
from yt.utilities.parallel_tools.parallel_analysis_interface import \
ParallelAnalysisInterface, \
@@ -419,7 +420,12 @@
self.add_default_quantities('all')
my_index = np.argsort(self.data_source["all", "particle_identifier"])
+ nhalos = my_index.size
+ my_i = 0
+ my_n = self.comm.size
+ pbar = get_pbar("Creating catalog", nhalos, parallel=True)
for i in parallel_objects(my_index, njobs=njobs, dynamic=dynamic):
+ my_i += min(my_n, nhalos - my_i)
new_halo = Halo(self)
halo_filter = True
for action_type, action in self.actions:
@@ -427,7 +433,9 @@
action(new_halo)
elif action_type == "filter":
halo_filter = action(new_halo)
- if not halo_filter: break
+ if not halo_filter:
+ pbar.update(my_i)
+ break
elif action_type == "quantity":
key, quantity = action
if quantity in self.halos_ds.field_info:
@@ -449,6 +457,8 @@
else:
del new_halo
+ pbar.update(my_i)
+
self.catalog.sort(key=lambda a:a['particle_identifier'].to_ndarray())
if save_catalog:
self.save_catalog()
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd yt/data_objects/grid_patch.py
--- a/yt/data_objects/grid_patch.py
+++ b/yt/data_objects/grid_patch.py
@@ -21,8 +21,6 @@
from yt.config import ytcfg
from yt.data_objects.data_containers import \
YTSelectionContainer
-from yt.data_objects.field_data import \
- YTFieldData
from yt.funcs import iterable
from yt.geometry.selection_routines import convert_mask_to_indices
import yt.geometry.particle_deposit as particle_deposit
@@ -58,8 +56,7 @@
OverlappingSiblings = None
def __init__(self, id, filename=None, index=None):
- self.field_data = YTFieldData()
- self.field_parameters = {}
+ super(AMRGridPatch, self).__init__(index.dataset, None)
self.id = id
self._child_mask = self._child_indices = self._child_index_mask = None
self.ds = index.dataset
@@ -69,8 +66,6 @@
self._last_mask = None
self._last_count = -1
self._last_selector_id = None
- self._current_particle_type = 'all'
- self._current_fluid_type = self.ds.default_fluid_type
def get_global_startindex(self):
"""
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd yt/data_objects/octree_subset.py
--- a/yt/data_objects/octree_subset.py
+++ b/yt/data_objects/octree_subset.py
@@ -55,10 +55,9 @@
_block_reorder = None
def __init__(self, base_region, domain, ds, over_refine_factor = 1):
+ super(OctreeSubset, self).__init__(ds, None)
self._num_zones = 1 << (over_refine_factor)
self._oref = over_refine_factor
- self.field_data = YTFieldData()
- self.field_parameters = {}
self.domain = domain
self.domain_id = domain.domain_id
self.ds = domain.ds
@@ -66,8 +65,6 @@
self.oct_handler = domain.oct_handler
self._last_mask = None
self._last_selector_id = None
- self._current_particle_type = 'all'
- self._current_fluid_type = self.ds.default_fluid_type
self.base_region = base_region
self.base_selector = base_region.selector
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd yt/data_objects/static_output.py
--- a/yt/data_objects/static_output.py
+++ b/yt/data_objects/static_output.py
@@ -24,6 +24,7 @@
from collections import defaultdict
from yt.extern.six import add_metaclass, string_types
+from six.moves import cPickle
from yt.config import ytcfg
from yt.fields.derived_field import \
@@ -252,14 +253,15 @@
obj.__init__(filename, *args, **kwargs)
return obj
apath = os.path.abspath(filename)
+ cache_key = (apath, cPickle.dumps(args), cPickle.dumps(kwargs))
if ytcfg.getboolean("yt","skip_dataset_cache"):
obj = object.__new__(cls)
- elif apath not in _cached_datasets:
+ elif cache_key not in _cached_datasets:
obj = object.__new__(cls)
if obj._skip_cache is False:
- _cached_datasets[apath] = obj
+ _cached_datasets[cache_key] = obj
else:
- obj = _cached_datasets[apath]
+ obj = _cached_datasets[cache_key]
return obj
def __init__(self, filename, dataset_type=None, file_style=None,
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd yt/data_objects/unstructured_mesh.py
--- a/yt/data_objects/unstructured_mesh.py
+++ b/yt/data_objects/unstructured_mesh.py
@@ -23,8 +23,6 @@
from yt.data_objects.data_containers import \
YTSelectionContainer
-from yt.data_objects.field_data import \
- YTFieldData
import yt.geometry.particle_deposit as particle_deposit
class UnstructuredMesh(YTSelectionContainer):
@@ -39,9 +37,8 @@
def __init__(self, mesh_id, filename, connectivity_indices,
connectivity_coords, index):
- self.field_data = YTFieldData()
+ super(UnstructuredMesh, self).__init__(index.dataset, None)
self.filename = filename
- self.field_parameters = {}
self.mesh_id = mesh_id
# This is where we set up the connectivity information
self.connectivity_indices = connectivity_indices
@@ -56,8 +53,6 @@
self._last_mask = None
self._last_count = -1
self._last_selector_id = None
- self._current_particle_type = 'all'
- self._current_fluid_type = self.ds.default_fluid_type
def _check_consistency(self):
if self.connectivity_indices.shape[1] != self._connectivity_length:
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd yt/frontends/fits/data_structures.py
--- a/yt/frontends/fits/data_structures.py
+++ b/yt/frontends/fits/data_structures.py
@@ -109,13 +109,15 @@
# the right case by comparing against known units. This
# only really works for common units.
units = set(re.split(regex_pattern, field_units))
- if '' in units: units.remove('')
+ if '' in units:
+ units.remove('')
n = int(0)
for unit in units:
if unit in known_units:
field_units = field_units.replace(unit, known_units[unit])
n += 1
- if n != len(units): field_units = "dimensionless"
+ if n != len(units) or n == 0:
+ field_units = "dimensionless"
if field_units[0] == "/":
field_units = "1%s" % field_units
return field_units
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd yt/frontends/gadget/definitions.py
--- a/yt/frontends/gadget/definitions.py
+++ b/yt/frontends/gadget/definitions.py
@@ -29,7 +29,7 @@
('OmegaLambda', 1, 'd'),
('HubbleParam', 1, 'd'),
('FlagAge', 1, 'i'),
- ('FlagMEtals', 1, 'i'),
+ ('FlagMetals', 1, 'i'),
('NallHW', 6, 'i'),
('unused', 16, 'i')),
pad32 = (('empty', 32, 'c'),),
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd yt/frontends/gamer/fields.py
--- a/yt/frontends/gamer/fields.py
+++ b/yt/frontends/gamer/fields.py
@@ -47,13 +47,14 @@
)
known_particle_fields = (
- ( "ParMass", ("code_mass", ["particle_mass"], None) ),
- ( "ParPosX", ("code_length", ["particle_position_x"], None) ),
- ( "ParPosY", ("code_length", ["particle_position_y"], None) ),
- ( "ParPosZ", ("code_length", ["particle_position_z"], None) ),
- ( "ParVelX", ("code_velocity", ["particle_velocity_x"], None) ),
- ( "ParVelY", ("code_velocity", ["particle_velocity_y"], None) ),
- ( "ParVelZ", ("code_velocity", ["particle_velocity_z"], None) ),
+ ( "ParMass", ("code_mass", ["particle_mass"], None) ),
+ ( "ParPosX", ("code_length", ["particle_position_x"], None) ),
+ ( "ParPosY", ("code_length", ["particle_position_y"], None) ),
+ ( "ParPosZ", ("code_length", ["particle_position_z"], None) ),
+ ( "ParVelX", ("code_velocity", ["particle_velocity_x"], None) ),
+ ( "ParVelY", ("code_velocity", ["particle_velocity_y"], None) ),
+ ( "ParVelZ", ("code_velocity", ["particle_velocity_z"], None) ),
+ ( "ParCreTime", ("code_time", ["particle_creation_time"], None) ),
)
def __init__(self, ds, field_list):
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd yt/frontends/ramses/data_structures.py
--- a/yt/frontends/ramses/data_structures.py
+++ b/yt/frontends/ramses/data_structures.py
@@ -240,22 +240,37 @@
("particle_mass", "d"),
("particle_identifier", "i"),
("particle_refinement_level", "I")]
- if hvals["nstar_tot"] > 0:
- particle_fields += [("particle_age", "d"),
- ("particle_metallicity", "d")]
+
if self.ds._extra_particle_fields is not None:
particle_fields += self.ds._extra_particle_fields
field_offsets = {}
_pfields = {}
- ptype = 'io'
-
+ # Read offsets
for field, vtype in particle_fields:
if f.tell() >= flen: break
field_offsets[ptype, field] = f.tell()
_pfields[ptype, field] = vtype
fpu.skip(f, 1)
+
+ iextra = 0
+ while f.tell() < flen:
+ iextra += 1
+ field, vtype = ('particle_extra_field_%i' % iextra, 'd')
+ particle_fields.append((field, vtype))
+
+ field_offsets["io", field] = f.tell()
+ _pfields["io", field] = vtype
+ fpu.skip(f, 1)
+
+ if iextra > 0 and not self.ds._warn_extra_fields:
+ self.ds._warn_extra_fields = True
+ w = ("Detected %s extra particle fields assuming kind "
+ "`double`. Consider using the `extra_particle_fields` "
+ "keyword argument if you have unexpected behavior.")
+ mylog.warning(w % iextra)
+
self.particle_field_offsets = field_offsets
self.particle_field_types = _pfields
@@ -636,6 +651,7 @@
self.fluid_types += ("ramses",)
self._fields_in_file = fields
self._extra_particle_fields = extra_particle_fields
+ self._warn_extra_fields = False
self.force_cosmological = cosmological
Dataset.__init__(self, filename, dataset_type, units_override=units_override,
unit_system=unit_system)
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd yt/frontends/ramses/tests/test_outputs.py
--- a/yt/frontends/ramses/tests/test_outputs.py
+++ b/yt/frontends/ramses/tests/test_outputs.py
@@ -114,7 +114,7 @@
ramsesExtraFieldsSmall = 'ramses_extra_fields_small/output_00001'
@requires_file(ramsesExtraFieldsSmall)
def test_extra_fields():
- extra_fields = [('family', 'I'), ('pointer', 'I')]
+ extra_fields = [('particle_family', 'I'), ('particle_pointer', 'I')]
ds = yt.load(os.path.join(ramsesExtraFieldsSmall, 'info_00001.txt'),
extra_particle_fields=extra_fields)
@@ -124,9 +124,22 @@
# Check the family (they should equal 100, for tracer particles)
dd = ds.all_data()
- families = dd[('all', 'family')]
+ families = dd[('all', 'particle_family')]
assert all(families == 100)
+
+ at requires_file(ramsesExtraFieldsSmall)
+def test_extra_fields_2():
+ extra_fields = ['particle_extra_field_%s' % (i + 1) for i in range(2)]
+ ds = yt.load(os.path.join(ramsesExtraFieldsSmall, 'info_00001.txt'))
+
+ # the dataset should contain the fields
+ for field in extra_fields:
+ assert ('io', field) in ds.field_list
+
+ # In the dataset, the fields are integers, so we cannot test
+ # that they are accessed correctly.
+
ramses_rt = "ramses_rt_00088/output_00088/info_00088.txt"
@requires_file(ramses_rt)
def test_ramses_rt():
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd yt/frontends/tipsy/io.py
--- a/yt/frontends/tipsy/io.py
+++ b/yt/frontends/tipsy/io.py
@@ -325,8 +325,10 @@
for f in glob.glob(data_file.filename + '.*'):
afield = f.rsplit('.')[-1]
filename = data_file.filename + '.' + afield
- if not os.path.exists(filename): continue
+ if not os.path.exists(filename):
+ continue
self._aux_fields.append(afield)
+ skip_afields = []
for afield in self._aux_fields:
filename = data_file.filename + '.' + afield
# We need to do some fairly ugly detection to see what format the
@@ -338,6 +340,11 @@
count=1) != tot_parts:
with open(filename, 'rb') as f:
header_nparts = f.readline()
+ try:
+ header_nparts = int(header_nparts)
+ except ValueError:
+ skip_afields.append(afield)
+ continue
if int(header_nparts) != tot_parts:
raise RuntimeError
self._aux_pdtypes[afield] = "ascii"
@@ -349,8 +356,9 @@
else:
self._aux_pdtypes[afield] = np.dtype([('aux', endian + 'f')])
else:
- raise RuntimeError
-
+ skip_afields.append(afield)
+ for afield in skip_afields:
+ self._aux_fields.remove(afield)
# Add the auxiliary fields to each ptype we have
for ptype in self._ptypes:
if any([ptype == field[0] for field in self._field_list]):
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd yt/frontends/ytdata/tests/test_outputs.py
--- a/yt/frontends/ytdata/tests/test_outputs.py
+++ b/yt/frontends/ytdata/tests/test_outputs.py
@@ -28,7 +28,8 @@
assert_allclose_units, \
assert_equal, \
assert_fname, \
- fake_random_ds
+ fake_random_ds, \
+ requires_module
from yt.utilities.answer_testing.framework import \
requires_ds, \
data_dir_load, \
@@ -229,6 +230,7 @@
os.chdir(curdir)
shutil.rmtree(tmpdir)
+ at requires_module('h5py')
def test_plot_data():
tmpdir = tempfile.mkdtemp()
curdir = os.getcwd()
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd yt/funcs.py
--- a/yt/funcs.py
+++ b/yt/funcs.py
@@ -642,7 +642,7 @@
import pkg_resources
yt_provider = pkg_resources.get_provider("yt")
path = os.path.dirname(yt_provider.module_path)
- version = get_hg_version(path)
+ version = get_git_version(path)
if version is None:
return version
else:
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd yt/units/tests/test_ytarray.py
--- a/yt/units/tests/test_ytarray.py
+++ b/yt/units/tests/test_ytarray.py
@@ -991,6 +991,17 @@
for op in [operator.abs, operator.neg, operator.pos]:
unary_op_registry_comparison(op)
+def test_to_value():
+
+ a = YTArray([1.0, 2.0, 3.0], "kpc")
+ assert_equal(a.to_value(), np.array([1.0, 2.0, 3.0]))
+ assert_equal(a.to_value(), a.value)
+ assert_equal(a.to_value("km"), a.in_units("km").value)
+
+ b = YTQuantity(5.5, "Msun")
+ assert_equal(b.to_value(), 5.5)
+ assert_equal(b.to_value("g"), b.in_units("g").value)
+
@requires_module("astropy")
def test_astropy():
from yt.utilities.on_demand_imports import _astropy
@@ -1113,83 +1124,88 @@
# Mass-energy
- E = mp.to_equivalent("keV","mass_energy")
+ E = mp.in_units("keV","mass_energy")
assert_equal(E, mp*clight*clight)
- assert_allclose_units(mp, E.to_equivalent("g", "mass_energy"))
+ assert_allclose_units(mp, E.in_units("g", "mass_energy"))
# Thermal
T = YTQuantity(1.0e8,"K")
- E = T.to_equivalent("W*hr","thermal")
+ E = T.in_units("W*hr","thermal")
assert_equal(E, (kboltz*T).in_units("W*hr"))
- assert_allclose_units(T, E.to_equivalent("K", "thermal"))
+ assert_allclose_units(T, E.in_units("K", "thermal"))
# Spectral
l = YTQuantity(4000.,"angstrom")
- nu = l.to_equivalent("Hz","spectral")
+ nu = l.in_units("Hz","spectral")
assert_equal(nu, clight/l)
E = hcgs*nu
- l2 = E.to_equivalent("angstrom", "spectral")
+ l2 = E.in_units("angstrom", "spectral")
assert_allclose_units(l, l2)
nu2 = clight/l2.in_units("cm")
assert_allclose_units(nu, nu2)
- E2 = nu2.to_equivalent("keV", "spectral")
+ E2 = nu2.in_units("keV", "spectral")
assert_allclose_units(E2, E.in_units("keV"))
# Sound-speed
mu = 0.6
gg = 5./3.
- c_s = T.to_equivalent("km/s","sound_speed")
+ c_s = T.in_units("km/s", equivalence="sound_speed")
assert_equal(c_s, np.sqrt(gg*kboltz*T/(mu*mh)))
- assert_allclose_units(T, c_s.to_equivalent("K","sound_speed"))
+ assert_allclose_units(T, c_s.in_units("K","sound_speed"))
mu = 0.5
gg = 4./3.
- c_s = T.to_equivalent("km/s","sound_speed", mu=mu, gamma=gg)
+ c_s = T.in_units("km/s","sound_speed", mu=mu, gamma=gg)
assert_equal(c_s, np.sqrt(gg*kboltz*T/(mu*mh)))
- assert_allclose_units(T, c_s.to_equivalent("K","sound_speed", mu=mu, gamma=gg))
+ assert_allclose_units(T, c_s.in_units("K","sound_speed", mu=mu, gamma=gg))
# Lorentz
v = 0.8*clight
- g = v.to_equivalent("dimensionless","lorentz")
+ g = v.in_units("dimensionless","lorentz")
g2 = YTQuantity(1./np.sqrt(1.-0.8*0.8), "dimensionless")
assert_allclose_units(g, g2)
- v2 = g2.to_equivalent("mile/hr", "lorentz")
+ v2 = g2.in_units("mile/hr", "lorentz")
assert_allclose_units(v2, v.in_units("mile/hr"))
# Schwarzschild
- R = mass_sun_cgs.to_equivalent("kpc","schwarzschild")
+ R = mass_sun_cgs.in_units("kpc","schwarzschild")
assert_equal(R.in_cgs(), 2*G*mass_sun_cgs/(clight*clight))
- assert_allclose_units(mass_sun_cgs, R.to_equivalent("g", "schwarzschild"))
+ assert_allclose_units(mass_sun_cgs, R.in_units("g", "schwarzschild"))
# Compton
- l = me.to_equivalent("angstrom","compton")
+ l = me.in_units("angstrom","compton")
assert_equal(l, hcgs/(me*clight))
- assert_allclose_units(me, l.to_equivalent("g", "compton"))
+ assert_allclose_units(me, l.in_units("g", "compton"))
# Number density
rho = mp/u.cm**3
- n = rho.to_equivalent("cm**-3","number_density")
+ n = rho.in_units("cm**-3","number_density")
assert_equal(n, rho/(mh*0.6))
- assert_allclose_units(rho, n.to_equivalent("g/cm**3","number_density"))
+ assert_allclose_units(rho, n.in_units("g/cm**3","number_density"))
- n = rho.to_equivalent("cm**-3","number_density", mu=0.75)
+ n = rho.in_units("cm**-3", equivalence="number_density", mu=0.75)
assert_equal(n, rho/(mh*0.75))
- assert_allclose_units(rho, n.to_equivalent("g/cm**3","number_density", mu=0.75))
+ assert_allclose_units(rho, n.in_units("g/cm**3", equivalence="number_density", mu=0.75))
# Effective temperature
T = YTQuantity(1.0e4, "K")
- F = T.to_equivalent("erg/s/cm**2","effective_temperature")
+ F = T.in_units("erg/s/cm**2",equivalence="effective_temperature")
assert_equal(F, stefan_boltzmann_constant_cgs*T**4)
- assert_allclose_units(T, F.to_equivalent("K", "effective_temperature"))
+ assert_allclose_units(T, F.in_units("K", equivalence="effective_temperature"))
+
+ # to_value test
+
+ assert_equal(F.value, T.to_value("erg/s/cm**2", equivalence="effective_temperature"))
+ assert_equal(n.value, rho.to_value("cm**-3", equivalence="number_density", mu=0.75))
def test_electromagnetic():
from yt.units.dimensions import charge_mks, pressure, current_cgs, \
@@ -1199,19 +1215,19 @@
# Various tests of SI and CGS electromagnetic units
- qp_mks = qp.to_equivalent("C", "SI")
+ qp_mks = qp.in_units("C", "SI")
assert_equal(qp_mks.units.dimensions, charge_mks)
assert_array_almost_equal(qp_mks.v, 10.0*qp.v/speed_of_light_cm_per_s)
- qp_cgs = qp_mks.to_equivalent("esu", "CGS")
+ qp_cgs = qp_mks.in_units("esu", "CGS")
assert_array_almost_equal(qp_cgs, qp)
assert_equal(qp_cgs.units.dimensions, qp.units.dimensions)
- qp_mks_k = qp.to_equivalent("kC", "SI")
+ qp_mks_k = qp.in_units("kC", "SI")
assert_array_almost_equal(qp_mks_k.v, 1.0e-2*qp.v/speed_of_light_cm_per_s)
B = YTQuantity(1.0, "T")
- B_cgs = B.to_equivalent("gauss", "CGS")
+ B_cgs = B.in_units("gauss", "CGS")
assert_equal(B.units.dimensions, magnetic_field_mks)
assert_equal(B_cgs.units.dimensions, magnetic_field_cgs)
assert_array_almost_equal(B_cgs, YTQuantity(1.0e4, "gauss"))
@@ -1223,13 +1239,13 @@
assert_array_almost_equal(u_mks.in_cgs(), u_cgs)
I = YTQuantity(1.0, "A")
- I_cgs = I.to_equivalent("statA", "CGS")
+ I_cgs = I.in_units("statA", equivalence="CGS")
assert_array_almost_equal(I_cgs, YTQuantity(0.1*speed_of_light_cm_per_s, "statA"))
- assert_array_almost_equal(I_cgs.to_equivalent("mA", "SI"), I.in_units("mA"))
+ assert_array_almost_equal(I_cgs.in_units("mA", equivalence="SI"), I.in_units("mA"))
assert_equal(I_cgs.units.dimensions, current_cgs)
R = YTQuantity(1.0, "ohm")
- R_cgs = R.to_equivalent("statohm", "CGS")
+ R_cgs = R.in_units("statohm", "CGS")
P_mks = I*I*R
P_cgs = I_cgs*I_cgs*R_cgs
assert_equal(P_mks.units.dimensions, power)
@@ -1238,7 +1254,7 @@
assert_array_almost_equal(P_cgs.in_mks(), YTQuantity(1.0, "W"))
V = YTQuantity(1.0, "statV")
- V_mks = V.to_equivalent("V", "SI")
+ V_mks = V.in_units("V", "SI")
assert_array_almost_equal(V_mks.v, 1.0e8*V.v/speed_of_light_cm_per_s)
def test_ytarray_coercion():
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd yt/units/yt_array.py
--- a/yt/units/yt_array.py
+++ b/yt/units/yt_array.py
@@ -589,38 +589,94 @@
"""
return self.convert_to_units(self.units.get_mks_equivalent())
- def in_units(self, units):
+ def in_units(self, units, equivalence=None, **kwargs):
"""
- Creates a copy of this array with the data in the supplied units, and
- returns it.
+ Creates a copy of this array with the data in the supplied
+ units, and returns it.
+
+ Optionally, an equivalence can be specified to convert to an
+ equivalent quantity which is not in the same dimensions.
+
+ .. note::
+
+ All additional keyword arguments are passed to the
+ equivalency, which should be used if that particular
+ equivalency requires them.
Parameters
----------
units : Unit object or string
The units you want to get a new quantity in.
+ equivalence : string, optional
+ The equivalence you wish to use. To see which
+ equivalencies are supported for this unitful
+ quantity, try the :meth:`list_equivalencies`
+ method. Default: None
Returns
-------
YTArray
+ """
+ if equivalence is None:
+ new_units = _unit_repr_check_same(self.units, units)
+ (conversion_factor, offset) = self.units.get_conversion_factor(new_units)
- """
- new_units = _unit_repr_check_same(self.units, units)
- (conversion_factor, offset) = self.units.get_conversion_factor(new_units)
-
- new_array = type(self)(self.ndview * conversion_factor, new_units)
+ new_array = type(self)(self.ndview * conversion_factor, new_units)
- if offset:
- np.subtract(new_array, offset*new_array.uq, new_array)
+ if offset:
+ np.subtract(new_array, offset*new_array.uq, new_array)
- return new_array
+ return new_array
+ else:
+ return self.to_equivalent(units, equivalence, **kwargs)
- def to(self, units):
+ def to(self, units, equivalence=None, **kwargs):
"""
An alias for YTArray.in_units().
See the docstrings of that function for details.
"""
- return self.in_units(units)
+ return self.in_units(units, equivalence=equivalence, **kwargs)
+
+ def to_value(self, units=None, equivalence=None, **kwargs):
+ """
+ Creates a copy of this array with the data in the supplied
+ units, and returns it without units. Output is therefore a
+ bare NumPy array.
+
+ Optionally, an equivalence can be specified to convert to an
+ equivalent quantity which is not in the same dimensions.
+
+ .. note::
+
+ All additional keyword arguments are passed to the
+ equivalency, which should be used if that particular
+ equivalency requires them.
+
+ Parameters
+ ----------
+ units : Unit object or string, optional
+ The units you want to get the bare quantity in. If not
+ specified, the value will be returned in the current units.
+
+ equivalence : string, optional
+ The equivalence you wish to use. To see which
+ equivalencies are supported for this unitful
+ quantity, try the :meth:`list_equivalencies`
+ method. Default: None
+
+ Returns
+ -------
+ NumPy array
+ """
+ if units is None:
+ v = self.value
+ else:
+ v = self.in_units(units, equivalence=equivalence, **kwargs).value
+ if isinstance(self, YTQuantity):
+ return float(v)
+ else:
+ return v
def in_base(self, unit_system="cgs"):
"""
@@ -684,6 +740,8 @@
>>> a.to_equivalent("keV", "thermal")
"""
conv_unit = Unit(unit, registry=self.units.registry)
+ if self.units.same_dimensions_as(conv_unit):
+ return self.in_units(conv_unit)
this_equiv = equivalence_registry[equiv]()
oneway_or_equivalent = (
conv_unit.has_equivalent(equiv) or this_equiv._one_way)
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd yt/utilities/grid_data_format/tests/test_writer.py
--- a/yt/utilities/grid_data_format/tests/test_writer.py
+++ b/yt/utilities/grid_data_format/tests/test_writer.py
@@ -17,7 +17,9 @@
import os
from yt.utilities.on_demand_imports import _h5py as h5
from yt.testing import \
- fake_random_ds, assert_equal
+ fake_random_ds, \
+ assert_equal, \
+ requires_module
from yt.utilities.grid_data_format.writer import \
write_to_gdf
from yt.frontends.gdf.data_structures import \
@@ -35,6 +37,7 @@
ytcfg["yt", "__withintesting"] = "True"
+ at requires_module('h5py')
def test_write_gdf():
"""Main test suite for write_gdf"""
tmpdir = tempfile.mkdtemp()
diff -r 9e8e1512578c6f23f8478c6d5d4be368f6e3a2e0 -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -2049,7 +2049,7 @@
"""
if ds.dimensionality != 2:
raise RuntimeError("plot_2d only plots 2D datasets!")
- if ds.geometry == "cartesian" or ds.geometry == "polar":
+ if ds.geometry in ["cartesian", "polar", "spectral_cube"]:
axis = "z"
elif ds.geometry == "cylindrical":
axis = "theta"
https://bitbucket.org/yt_analysis/yt/commits/e5a41015c49f/
Changeset: e5a41015c49f
User: Corentin Cadiou
Date: 2017-10-06 12:02:00+00:00
Summary: Use generic _add_ptype function
Affected #: 1 file
diff -r 309210b5e7f3e1d9cb19eb76baea3bbb7081b4cd -r e5a41015c49f368a2f299bc7fe23ac1c6deddf55 yt/frontends/ramses/data_structures.py
--- a/yt/frontends/ramses/data_structures.py
+++ b/yt/frontends/ramses/data_structures.py
@@ -132,6 +132,14 @@
self._level_count = level_count
return self._hydro_offset
+ def _add_ptype(self, ptype):
+ if hasattr(self, 'particle_types'):
+ new = set(self.particle_types)
+ else:
+ new = set()
+ new.add(ptype)
+ self.particle_types = self.particle_types_raw = tuple(new)
+
def _read_hydro_header(self):
# If no hydro file is found, return
if not self._has_hydro:
@@ -198,13 +206,8 @@
self.sink_field_offsets = field_offsets
self.sink_field_types = _pfields
- try:
- ptypes = list(self.particles_types)
- except AttributeError:
- ptypes = []
- finally:
- ptypes.append('sink')
- self.particle_types = self.particle_types_raw = tuple(ptypes)
+ self._add_ptype('sink')
+
def _read_particle_header(self):
if not os.path.exists(self.part_fn):
@@ -247,6 +250,8 @@
field_offsets = {}
_pfields = {}
+ ptype = 'io'
+
# Read offsets
for field, vtype in particle_fields:
if f.tell() >= flen: break
@@ -260,8 +265,8 @@
field, vtype = ('particle_extra_field_%i' % iextra, 'd')
particle_fields.append((field, vtype))
- field_offsets["io", field] = f.tell()
- _pfields["io", field] = vtype
+ field_offsets[ptype, field] = f.tell()
+ _pfields[ptype, field] = vtype
fpu.skip(f, 1)
if iextra > 0 and not self.ds._warn_extra_fields:
@@ -274,6 +279,9 @@
self.particle_field_offsets = field_offsets
self.particle_field_types = _pfields
+ # Register the particle type
+ self._add_ptype(ptype)
+
def _read_amr_header(self):
hvals = {}
f = open(self.amr_fn, "rb")
https://bitbucket.org/yt_analysis/yt/commits/a3b693280fad/
Changeset: a3b693280fad
User: ngoldbaum
Date: 2017-10-06 14:50:43+00:00
Summary: Merge pull request #1548 from cphyc/feature/RAMSES-sinks
[RAMSES] Add support for sink particles
Affected #: 5 files
diff -r 0231a9c04ac1101ef070028c7af3f71684643597 -r a3b693280fadc19b7c0d321a140eb3c117c1bdf6 doc/source/examining/loading_data.rst
--- a/doc/source/examining/loading_data.rst
+++ b/doc/source/examining/loading_data.rst
@@ -1988,13 +1988,21 @@
yt supports outputs made by the mainline ``RAMSES`` code as well as the
``RAMSES-RT`` fork. Files produces by ``RAMSES-RT`` are recognized as such
-based on the presence of a ``into_rt_*.txt`` file in the output directory.
+based on the presence of a ``info_rt_*.txt`` file in the output directory.
It is possible to force yt to treat the simulation as a cosmological
simulation by providing the ``cosmological=True`` parameter (or
``False`` to force non-cosmology). If left to ``None``, the kind of
the simulation is inferred from the data.
+yt also support outputs that include sinks (RAMSES' name for black
+holes) when the folder contains files like ``sink_XXXXX.outYYYYY``.
+
+Note: for backward compatibility, particles from the
+``particle_XXXXX.outYYYYY`` files have the particle type ``io`` by
+default (including dark matter, stars, tracer particles, …). Sink
+particles have the particle type ``sink``.
+
.. _loading-sph-data:
SPH Particle Data
diff -r 0231a9c04ac1101ef070028c7af3f71684643597 -r a3b693280fadc19b7c0d321a140eb3c117c1bdf6 yt/frontends/ramses/data_structures.py
--- a/yt/frontends/ramses/data_structures.py
+++ b/yt/frontends/ramses/data_structures.py
@@ -62,11 +62,12 @@
os.path.abspath(
os.path.dirname(ds.parameter_filename)),
num, domain_id)
- for t in ['grav', 'hydro', 'part', 'amr']:
+ for t in ['grav', 'hydro', 'part', 'amr', 'sink']:
setattr(self, "%s_fn" % t, basename % t)
self._read_amr_header()
self._read_hydro_header()
self._read_particle_header()
+ self._read_sink_header()
self._read_amr()
_hydro_offset = None
@@ -75,13 +76,21 @@
def __repr__(self):
return "RAMSESDomainFile: %i" % self.domain_id
- def _is_hydro(self):
+ @property
+ def _has_hydro(self):
'''
Does the output include hydro?
'''
return os.path.exists(self.hydro_fn)
@property
+ def _has_sink(self):
+ '''
+ Does the output include sinks (black holes)?
+ '''
+ return os.path.exists(self.sink_fn)
+
+ @property
def level_count(self):
if self._level_count is not None: return self._level_count
self.hydro_offset
@@ -123,16 +132,83 @@
self._level_count = level_count
return self._hydro_offset
+ def _add_ptype(self, ptype):
+ if hasattr(self, 'particle_types'):
+ new = set(self.particle_types)
+ else:
+ new = set()
+ new.add(ptype)
+ self.particle_types = self.particle_types_raw = tuple(new)
+
def _read_hydro_header(self):
# If no hydro file is found, return
- if not self._is_hydro():
+ if not self._has_hydro:
return
if self.nvar > 0: return self.nvar
- # Read the number of hydro variables
+ # Read the number of hydro variables
f = open(self.hydro_fn, "rb")
fpu.skip(f, 1)
self.nvar = fpu.read_vector(f, "i")[0]
+
+ def _read_sink_header(self):
+ if not self._has_sink:
+ self.local_sink_count = 0
+ self.sink_field_offsets = {}
+ return
+ f = open(self.sink_fn, "rb")
+ f.seek(0, os.SEEK_END)
+ flen = f.tell()
+ f.seek(0)
+ hvals = {}
+ attrs = (('nsink', 1, 'I'),
+ ('nindsink', 1, 'I'))
+ hvals.update(fpu.read_attrs(f, attrs))
+ self.sink_header = hvals
+ self.local_sink_count = hvals['nsink']
+
+ sink_fields = [
+ ("particle_identifier", "i"),
+ ("particle_mass", "d"),
+ ("particle_position_x", "d"),
+ ("particle_position_y", "d"),
+ ("particle_position_z", "d"),
+ ("particle_velocity_x", "d"),
+ ("particle_velocity_y", "d"),
+ ("particle_velocity_z", "d"),
+ ("particle_age", "d"),
+ ("BH_real_accretion", "d"),
+ ("BH_bondi_accretion", "d"),
+ ("BH_eddington_accretion", "d"),
+ ("BH_esave", "d"),
+ ("gas_spin_x", "d"),
+ ("gas_spin_y", "d"),
+ ("gas_spin_z", "d"),
+ ("BH_spin_x", "d"),
+ ("BH_spin_y", "d"),
+ ("BH_spin_z", "d"),
+ ("BH_spin", "d"),
+ ("BH_efficiency", "d")]
+
+ for i in range(self.ds.dimensionality*2+1):
+ for j in range(self.ds.max_level, self.ds.min_level):
+ sink_fields.append((
+ "particle_prop_%s_%s" % (i, j), "d"
+ ))
+
+ field_offsets = {}
+ _pfields = {}
+ for field, vtype in sink_fields:
+ if f.tell() >= flen: break
+ field_offsets["sink", field] = f.tell()
+ _pfields["sink", field] = vtype
+ fpu.skip(f, 1)
+ self.sink_field_offsets = field_offsets
+ self.sink_field_types = _pfields
+
+ self._add_ptype('sink')
+
+
def _read_particle_header(self):
if not os.path.exists(self.part_fn):
self.local_particle_count = 0
@@ -174,11 +250,13 @@
field_offsets = {}
_pfields = {}
+ ptype = 'io'
+
# Read offsets
for field, vtype in particle_fields:
if f.tell() >= flen: break
- field_offsets["io", field] = f.tell()
- _pfields["io", field] = vtype
+ field_offsets[ptype, field] = f.tell()
+ _pfields[ptype, field] = vtype
fpu.skip(f, 1)
iextra = 0
@@ -187,8 +265,8 @@
field, vtype = ('particle_extra_field_%i' % iextra, 'd')
particle_fields.append((field, vtype))
- field_offsets["io", field] = f.tell()
- _pfields["io", field] = vtype
+ field_offsets[ptype, field] = f.tell()
+ _pfields[ptype, field] = vtype
fpu.skip(f, 1)
if iextra > 0 and not self.ds._warn_extra_fields:
@@ -200,7 +278,9 @@
self.particle_field_offsets = field_offsets
self.particle_field_types = _pfields
- self.particle_types = self.particle_types_raw = ("io",)
+
+ # Register the particle type
+ self._add_ptype(ptype)
def _read_amr_header(self):
hvals = {}
@@ -228,7 +308,7 @@
def _read_amr(self):
"""Open the oct file, read in octs level-by-level.
- For each oct, only the position, index, level and domain
+ For each oct, only the position, index, level and domain
are needed - its position in the octree is found automatically.
The most important is finding all the information to feed
oct_handler.add
@@ -254,7 +334,7 @@
min_level = self.ds.min_level
# yt max level is not the same as the RAMSES one.
# yt max level is the maximum number of additional refinement levels
- # so for a uni grid run with no refinement, it would be 0.
+ # so for a uni grid run with no refinement, it would be 0.
# So we initially assume that.
max_level = 0
nx, ny, nz = (((i-1.0)/2.0) for i in self.amr_header['nx'])
@@ -387,8 +467,11 @@
dsl = set([])
if self.fluid_field_list is None or len(self.fluid_field_list) <= 0:
self._setup_auto_fields()
+
for domain in self.domains:
dsl.update(set(domain.particle_field_offsets.keys()))
+ dsl.update(set(domain.sink_field_offsets.keys()))
+
self.particle_field_list = list(dsl)
self.field_list = [("ramses", f) for f in self.fluid_field_list] \
+ self.particle_field_list
@@ -410,7 +493,7 @@
if not os.path.exists(hydro_fn):
self.fluid_field_list = []
return
- # Read the number of hydro variables
+ # Read the number of hydro variables
f = open(hydro_fn, "rb")
hydro_header = ( ('ncpu', 1, 'i'),
('nvar', 1, 'i'),
@@ -423,7 +506,7 @@
self.ds.gamma = hvals['gamma']
nvar = hvals['nvar']
# OK, we got NVAR, now set up the arrays depending on what NVAR is
- # but first check for radiative transfer!
+ # but first check for radiative transfer!
foldername = os.path.abspath(os.path.dirname(self.ds.parameter_filename))
rt_flag = any(glob.glob(os.sep.join([foldername, 'info_rt_*.txt'])))
if rt_flag: # rt run
@@ -432,32 +515,32 @@
fields = ["Density", "x-velocity", "y-velocity", "z-velocity", "Pressure", "Metallicity", "HII", "HeII", "HeIII"]
else:
mylog.info('Detected RAMSES-RT file WITH IR trapping.')
- fields = ["Density", "x-velocity", "y-velocity", "z-velocity", "Pres_IR", "Pressure", "Metallicity", "HII", "HeII", "HeIII"]
- else:
+ fields = ["Density", "x-velocity", "y-velocity", "z-velocity", "Pres_IR", "Pressure", "Metallicity", "HII", "HeII", "HeIII"]
+ else:
if nvar < 5:
mylog.debug("nvar=%s is too small! YT doesn't currently support 1D/2D runs in RAMSES %s")
raise ValueError
# Basic hydro runs
if nvar == 5:
fields = ["Density",
- "x-velocity", "y-velocity", "z-velocity",
+ "x-velocity", "y-velocity", "z-velocity",
"Pressure"]
if nvar > 5 and nvar < 11:
- fields = ["Density",
- "x-velocity", "y-velocity", "z-velocity",
+ fields = ["Density",
+ "x-velocity", "y-velocity", "z-velocity",
"Pressure", "Metallicity"]
# MHD runs - NOTE: THE MHD MODULE WILL SILENTLY ADD 3 TO THE NVAR IN THE MAKEFILE
if nvar == 11:
- fields = ["Density",
- "x-velocity", "y-velocity", "z-velocity",
- "x-Bfield-left", "y-Bfield-left", "z-Bfield-left",
- "x-Bfield-right", "y-Bfield-right", "z-Bfield-right",
+ fields = ["Density",
+ "x-velocity", "y-velocity", "z-velocity",
+ "x-Bfield-left", "y-Bfield-left", "z-Bfield-left",
+ "x-Bfield-right", "y-Bfield-right", "z-Bfield-right",
"Pressure"]
if nvar > 11:
- fields = ["Density",
- "x-velocity", "y-velocity", "z-velocity",
- "x-Bfield-left", "y-Bfield-left", "z-Bfield-left",
- "x-Bfield-right", "y-Bfield-right", "z-Bfield-right",
+ fields = ["Density",
+ "x-velocity", "y-velocity", "z-velocity",
+ "x-Bfield-left", "y-Bfield-left", "z-Bfield-left",
+ "x-Bfield-right", "y-Bfield-right", "z-Bfield-right",
"Pressure","Metallicity"]
# Allow some wiggle room for users to add too many variables
while len(fields) < nvar:
@@ -516,9 +599,9 @@
return {'io': npart}
def print_stats(self):
-
+
# This function prints information based on the fluid on the grids,
- # and therefore does not work for DM only runs.
+ # and therefore does not work for DM only runs.
if not self.fluid_field_list:
print("This function is not implemented for DM only runs")
return
@@ -570,7 +653,7 @@
fields: An array of hydro variable fields in order of position in the hydro_XXXXX.outYYYYY file
If set to None, will try a default set of fields
extra_particle_fields: An array of extra particle variables in order of position in the particle_XXXXX.outYYYYY file.
- cosmological: If set to None, automatically detect cosmological simulation. If a boolean, force
+ cosmological: If set to None, automatically detect cosmological simulation. If a boolean, force
its value.
'''
self.fluid_types += ("ramses",)
@@ -580,6 +663,7 @@
self.force_cosmological = cosmological
Dataset.__init__(self, filename, dataset_type, units_override=units_override,
unit_system=unit_system)
+
self.storage_filename = storage_filename
@@ -597,7 +681,7 @@
time_unit = self.parameters['unit_t']
# calculating derived units (except velocity and temperature, done below)
- mass_unit = density_unit * length_unit**3
+ mass_unit = density_unit * length_unit**3
magnetic_unit = np.sqrt(4*np.pi * mass_unit /
(time_unit**2 * length_unit))
pressure_unit = density_unit * (length_unit / time_unit)**2
@@ -704,9 +788,23 @@
self.time_simu = self.t_frw[iage ]*(age-self.tau_frw[iage-1])/(self.tau_frw[iage]-self.tau_frw[iage-1])+ \
self.t_frw[iage-1]*(age-self.tau_frw[iage ])/(self.tau_frw[iage-1]-self.tau_frw[iage])
-
+
self.current_time = (self.time_tot + self.time_simu)/(self.hubble_constant*1e7/3.08e24)/self.parameters['unit_t']
+ # Check for the presence of sink files
+ sink_files = os.path.join(
+ os.path.split(self.parameter_filename)[0],
+ 'sink_?????.out?????')
+ has_sink = len(glob.glob(sink_files))
+
+ if has_sink:
+ ptypes = ('io', 'sink')
+ else:
+ ptypes = ('io', )
+
+ self.particle_types = self.particle_types_raw = ptypes
+
+
@classmethod
def _is_valid(self, *args, **kwargs):
diff -r 0231a9c04ac1101ef070028c7af3f71684643597 -r a3b693280fadc19b7c0d321a140eb3c117c1bdf6 yt/frontends/ramses/fields.py
--- a/yt/frontends/ramses/fields.py
+++ b/yt/frontends/ramses/fields.py
@@ -32,6 +32,8 @@
rho_units = "code_density"
vel_units = "code_velocity"
pressure_units = "code_pressure"
+ener_units = "code_mass * code_velocity**2 / code_time**2"
+ang_mom_units = "code_mass * code_velocity * code_length"
known_species_masses = dict(
(sp, mh * v) for sp, v in [
@@ -89,6 +91,30 @@
("particle_metallicity", ("", [], None)),
)
+ known_sink_fields = (
+ ("particle_position_x", ("code_length", [], None)),
+ ("particle_position_y", ("code_length", [], None)),
+ ("particle_position_z", ("code_length", [], None)),
+ ("particle_velocity_x", (vel_units, [], None)),
+ ("particle_velocity_y", (vel_units, [], None)),
+ ("particle_velocity_z", (vel_units, [], None)),
+ ("particle_mass", ("code_mass", [], None)),
+ ("particle_identifier", ("", ["particle_index"], None)),
+ ("particle_age", ("code_time", ['age'], None)),
+ ("BH_real_accretion", ("code_mass/code_time", [], None)),
+ ("BH_bondi_accretion", ("code_mass/code_time", [], None)),
+ ("BH_eddington_accretion", ("code_mass/code_time", [], None)),
+ ("BH_esave", (ener_units, [], None)),
+ ("gas_spin_x", (ang_mom_units, [], None)),
+ ("gas_spin_y", (ang_mom_units, [], None)),
+ ("gas_spin_z", (ang_mom_units, [], None)),
+ ("BH_spin_x", ("", [], None)),
+ ("BH_spin_y", ("", [], None)),
+ ("BH_spin_z", ("", [], None)),
+ ("BH_spin", (ang_mom_units, [], None)),
+ ("BH_efficiency", ("", [], None))
+ )
+
def setup_fluid_fields(self):
def _temperature(field, data):
rv = data["gas", "pressure"]/data["gas", "density"]
diff -r 0231a9c04ac1101ef070028c7af3f71684643597 -r a3b693280fadc19b7c0d321a140eb3c117c1bdf6 yt/frontends/ramses/io.py
--- a/yt/frontends/ramses/io.py
+++ b/yt/frontends/ramses/io.py
@@ -30,6 +30,48 @@
else:
from cStringIO import StringIO as IO
+def _ramses_particle_file_handler(fname, foffsets, data_types,
+ subset, fields):
+ '''General file handler, called by _read_particle_subset
+
+ Parameters
+ ----------
+ fname : string
+ filename to read from
+ foffsets: dict
+ Offsets in file of the fields
+ data_types: dict
+ Data type of the fields
+ subset: ``RAMSESDomainSubset``
+ A RAMSES domain subset object
+ fields: list of tuple
+ The fields to read
+ '''
+ tr = {}
+ with open(fname, "rb") as f:
+ # We do *all* conversion into boxlen here.
+ # This means that no other conversions need to be applied to convert
+ # positions into the same domain as the octs themselves.
+ for field in sorted(fields, key=lambda a: foffsets[a]):
+ f.seek(foffsets[field])
+ dt = data_types[field]
+ tr[field] = fpu.read_vector(f, dt)
+ if field[1].startswith("particle_position"):
+ np.divide(tr[field], subset.domain.ds["boxlen"], tr[field])
+ cosmo = subset.domain.ds.cosmological_simulation
+ if cosmo == 1 and field[1] == "particle_age":
+ tf = subset.domain.ds.t_frw
+ dtau = subset.domain.ds.dtau
+ tauf = subset.domain.ds.tau_frw
+ tsim = subset.domain.ds.time_simu
+ h100 = subset.domain.ds.hubble_constant
+ nOver2 = subset.domain.ds.n_frw/2
+ t_scale = 1./(h100 * 100 * cm_per_km / cm_per_mpc)/subset.domain.ds['unit_t']
+ ages = tr[field]
+ tr[field] = get_ramses_ages(tf,tauf,dtau,tsim,t_scale,ages,nOver2,len(ages))
+ return tr
+
+
class IOHandlerRAMSES(BaseIOHandler):
_dataset_type = "ramses"
@@ -91,28 +133,32 @@
data = np.asarray(rv.pop((ptype, field))[mask], "=f8")
yield (ptype, field), data
+
def _read_particle_subset(self, subset, fields):
- f = open(subset.domain.part_fn, "rb")
- foffsets = subset.domain.particle_field_offsets
+ '''Read the particle files.'''
tr = {}
- # We do *all* conversion into boxlen here.
- # This means that no other conversions need to be applied to convert
- # positions into the same domain as the octs themselves.
- for field in sorted(fields, key = lambda a: foffsets[a]):
- f.seek(foffsets[field])
- dt = subset.domain.particle_field_types[field]
- tr[field] = fpu.read_vector(f, dt)
- if field[1].startswith("particle_position"):
- np.divide(tr[field], subset.domain.ds["boxlen"], tr[field])
- cosmo = subset.domain.ds.cosmological_simulation
- if cosmo == 1 and field[1] == "particle_age":
- tf = subset.domain.ds.t_frw
- dtau = subset.domain.ds.dtau
- tauf = subset.domain.ds.tau_frw
- tsim = subset.domain.ds.time_simu
- h100 = subset.domain.ds.hubble_constant
- nOver2 = subset.domain.ds.n_frw/2
- t_scale = 1./(h100 * 100 * cm_per_km / cm_per_mpc)/subset.domain.ds['unit_t']
- ages = tr[field]
- tr[field] = get_ramses_ages(tf,tauf,dtau,tsim,t_scale,ages,nOver2,len(ages))
+
+ # Sequential read depending on particle type (io or sink)
+ for ptype in set(f[0] for f in fields):
+
+ # Select relevant fiels
+ subs_fields = filter(lambda f: f[0] == ptype, fields)
+
+ if ptype == 'io':
+ fname = subset.domain.part_fn
+ foffsets = subset.domain.particle_field_offsets
+ data_types = subset.domain.particle_field_types
+
+ elif ptype == 'sink':
+ fname = subset.domain.sink_fn
+ foffsets = subset.domain.sink_field_offsets
+ data_types = subset.domain.sink_field_types
+
+ else:
+ # Raise here an exception
+ raise Exception('Unknown particle type %s' % ptype)
+
+ tr.update(_ramses_particle_file_handler(
+ fname, foffsets, data_types, subset, subs_fields))
+
return tr
diff -r 0231a9c04ac1101ef070028c7af3f71684643597 -r a3b693280fadc19b7c0d321a140eb3c117c1bdf6 yt/frontends/ramses/tests/test_outputs.py
--- a/yt/frontends/ramses/tests/test_outputs.py
+++ b/yt/frontends/ramses/tests/test_outputs.py
@@ -167,3 +167,40 @@
for field in special_fields:
assert(field in ds.derived_field_list)
ad[field]
+
+
+ramses_sink = "ramses_sink_00016/output_00016/info_00016.txt"
+ at requires_file(ramses_sink)
+ at requires_file(ramsesNonCosmo)
+def test_ramses_sink():
+ expected_fields = ["BH_bondi_accretion", "BH_eddington_accretion",
+ "BH_efficiency", "BH_esave",
+ "BH_real_accretion", "BH_spin", "BH_spin_x",
+ "BH_spin_y", "BH_spin_z", "gas_spin_x",
+ "gas_spin_y", "gas_spin_z", "particle_age",
+ "particle_identifier", "particle_mass",
+ "particle_position_x", "particle_position_y",
+ "particle_position_z", "particle_prop_0_0",
+ "particle_prop_0_1", "particle_prop_0_2",
+ "particle_prop_0_3", "particle_prop_1_0",
+ "particle_prop_1_1", "particle_prop_1_2",
+ "particle_velocity_x", "particle_velocity_y",
+ "particle_velocity_z"]
+
+ # Check that sinks are autodetected
+ ds = yt.load(ramses_sink)
+ ad = ds.all_data()
+
+ for field in expected_fields:
+ assert(('sink', field) in ds.field_list)
+
+ # test that field access works
+ ad['sink', field]
+
+
+ # Checking that sinks are autodetected
+ ds = yt.load(ramsesCosmo)
+ ad = ds.all_data()
+
+ for field in expected_fields:
+ assert(('sink', 'field') not in ds.field_list)
Repository URL: https://bitbucket.org/yt_analysis/yt/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
More information about the yt-svn
mailing list