[yt-svn] commit/yt-3.0: 30 new changesets

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Mon Jun 3 05:09:11 PDT 2013


30 new commits in yt-3.0:

https://bitbucket.org/yt_analysis/yt-3.0/commits/d1ab7a9f1bd8/
Changeset:   d1ab7a9f1bd8
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-30 19:55:58
Summary:     Adding support for specifying units to Tipsy and Gadget files.

This is somewhat reluctantly implemented, and will change considerably when
YTEP-0011 is implemented.  Examples to follow.

Note also that I have changed the __repr__ for Tipsy and Gadget not to split
based on filenames.
Affected #:  1 file

diff -r cdcd37b6f2fa39e411569d1fde8972dbad7e737f -r d1ab7a9f1bd8372ab793566750e78b0110b6bfdd yt/frontends/sph/data_structures.py
--- a/yt/frontends/sph/data_structures.py
+++ b/yt/frontends/sph/data_structures.py
@@ -234,7 +234,36 @@
         self.field_offsets = self.io._calculate_field_offsets(
                 field_list, self.total_particles)
 
-class GadgetStaticOutput(StaticOutput):
+class ParticleStaticOutput(StaticOutput):
+    _unit_base = None
+
+    def _set_units(self):
+        self.units = {}
+        self.time_units = {}
+        self.conversion_factors = {}
+        self.units['1'] = 1.0
+        self.units['unitary'] = (self.domain_right_edge -
+                                 self.domain_left_edge).max()
+        # Check 
+        base = None
+        mpch = {}
+        mpch.update(mpc_conversion)
+        unit_base = self._unit_base or {}
+        for unit in mpc_conversion:
+            mpch['%sh' % unit] = mpch[unit] / self.hubble_constant
+            mpch['%shcm' % unit] = (mpch["%sh" % unit] / 
+                    (1 + self.current_redshift))
+            mpch['%scm' % unit] = mpch[unit] / (1 + self.current_redshift)
+        for unit_registry in [mpch, sec_conversion]:
+            for unit in sorted(unit_base):
+                if unit in unit_registry:
+                    base = unit_registry[unit] / unit_registry['mpc'] 
+                    break
+            if base is None: continue
+            for unit in unit_registry:
+                self.units[unit] = unit_registry[unit] / base
+
+class GadgetStaticOutput(ParticleStaticOutput):
     _hierarchy_class = ParticleGeometryHandler
     _domain_class = GadgetBinaryDomainFile
     _fieldinfo_fallback = GadgetFieldInfo
@@ -258,20 +287,17 @@
                     ('unused', 16, 'i') )
 
     def __init__(self, filename, data_style="gadget_binary",
-                 additional_fields = (), root_dimensions = 64):
+                 additional_fields = (), root_dimensions = 64,
+                 unit_base = None):
         self._root_dimensions = root_dimensions
         # Set up the template for domain files
         self.storage_filename = None
+        self._unit_base = unit_base
         super(GadgetStaticOutput, self).__init__(filename, data_style)
 
     def __repr__(self):
         return os.path.basename(self.parameter_filename).split(".")[0]
 
-    def _set_units(self):
-        self.units = {}
-        self.time_units = {}
-        self.conversion_factors = {}
-
     def _parse_parameter_file(self):
 
         # The entries in this header are capitalized and named to match Table 4
@@ -337,7 +363,7 @@
         io._create_dtypes(self)
 
 
-class TipsyStaticOutput(StaticOutput):
+class TipsyStaticOutput(ParticleStaticOutput):
     _hierarchy_class = ParticleGeometryHandler
     _domain_class = TipsyDomainFile
     _fieldinfo_fallback = TipsyFieldInfo
@@ -354,7 +380,8 @@
                  root_dimensions = 64, endian = ">",
                  field_dtypes = None,
                  domain_left_edge = None,
-                 domain_right_edge = None):
+                 domain_right_edge = None,
+                 unit_base = None):
         self.endian = endian
         self._root_dimensions = root_dimensions
         # Set up the template for domain files
@@ -372,10 +399,11 @@
         if field_dtypes is None: field_dtypes = {}
         self._field_dtypes = field_dtypes
 
+        unit_base = self._unit_base or {}
         super(TipsyStaticOutput, self).__init__(filename, data_style)
 
     def __repr__(self):
-        return os.path.basename(self.parameter_filename).split(".")[0]
+        return os.path.basename(self.parameter_filename)
 
     def _set_units(self):
         self.units = {}


https://bitbucket.org/yt_analysis/yt-3.0/commits/b977da78640e/
Changeset:   b977da78640e
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-30 19:56:24
Summary:     For the case when we have multiple fluids, we need to call _get_field_info for
generating the field.
Affected #:  1 file

diff -r d1ab7a9f1bd8372ab793566750e78b0110b6bfdd -r b977da78640e958de7897fc1aa4535440504f3a8 yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -228,17 +228,18 @@
     def _generate_fluid_field(self, field):
         # First we check the validator
         ftype, fname = field
+        finfo = self.pf._get_field_info(ftype, fname)
         if self._current_chunk is None or \
            self._current_chunk.chunk_type != "spatial":
             gen_obj = self
         else:
             gen_obj = self._current_chunk.objs[0]
         try:
-            self.pf.field_info[fname].check_available(gen_obj)
+            finfo.check_available(gen_obj)
         except NeedsGridType as ngt_exception:
             rv = self._generate_spatial_fluid(field, ngt_exception.ghost_zones)
         else:
-            rv = self.pf.field_info[fname](gen_obj)
+            rv = finfo(gen_obj)
         return rv
 
     def _generate_spatial_fluid(self, field, ngz):


https://bitbucket.org/yt_analysis/yt-3.0/commits/c04157024e47/
Changeset:   c04157024e47
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-30 19:56:48
Summary:     Adding on another field type, "deposit"
Affected #:  1 file

diff -r b977da78640e958de7897fc1aa4535440504f3a8 -r c04157024e47cf52b28130e5d0359e5a3feb9152 yt/data_objects/static_output.py
--- a/yt/data_objects/static_output.py
+++ b/yt/data_objects/static_output.py
@@ -55,7 +55,7 @@
 class StaticOutput(object):
 
     default_fluid_type = "gas"
-    fluid_types = ("gas",)
+    fluid_types = ("gas","deposit")
     particle_types = ("all",)
     geometry = "cartesian"
     coordinates = None


https://bitbucket.org/yt_analysis/yt-3.0/commits/79eeeec29e2c/
Changeset:   79eeeec29e2c
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-30 19:57:30
Summary:     Adding in some particle deposit fields for Gadget and Tipsy.

This also adds on Mass for Gadget, which will grab from Masarr if needed.
Affected #:  1 file

diff -r c04157024e47cf52b28130e5d0359e5a3feb9152 -r 79eeeec29e2cb793b570c3df12544e19cb1987e9 yt/frontends/sph/fields.py
--- a/yt/frontends/sph/fields.py
+++ b/yt/frontends/sph/fields.py
@@ -54,3 +54,49 @@
 KnownTipsyFields = FieldInfoContainer()
 add_tipsy_field = KnownTipsyFields.add_field
 
+def _particle_functions(ptype, coord_name, mass_name, registry):
+    def particle_count(field, data):
+        pos = data[ptype, coord_name]
+        d = data.deposit(pos, method = "count")
+        return d
+    registry.add_field(("deposit", "%s_count" % ptype),
+             function = particle_count,
+             validators = [ValidateSpatial()],
+             projection_conversion = '1')
+
+    def particle_density(field, data):
+        pos = data[ptype, coord_name]
+        d = data.deposit(pos, [data[ptype, mass_name]], method = "sum")
+        d /= data["CellVolume"]
+        return d
+
+    registry.add_field(("deposit", "%s_density" % ptype),
+             function = particle_density,
+             validators = [ValidateSpatial()],
+             units = r"\mathrm{g}/\mathrm{cm}^{3}",
+             projection_conversion = 'cm')
+
+for ptype in ["Gas", "DarkMatter", "Stars"]:
+    _particle_functions(ptype, "Coordinates", "Mass", TipsyFieldInfo)
+   
+# GADGET
+# ======
+
+# Among other things we need to set up Coordinates
+
+_gadget_ptypes = ("Gas", "Halo", "Disk", "Bulge", "Stars", "Bndry")
+
+def _gadget_particle_fields(ptype):
+    def _Mass(field, data):
+        pind = _gadget_ptypes.index(ptype)
+        if data.pf["Massarr"][pind] == 0.0:
+            return data[ptype, "Masses"]
+        mass = np.ones(data[ptype, "Coordinates"].shape[0], dtype="float64")
+        mass *= data.pf["Massarr"][pind]
+        return mass
+    GadgetFieldInfo.add_field((ptype, "Mass"), function=_Mass,
+                              particle_type = True)
+
+for ptype in _gadget_ptypes:
+    _gadget_particle_fields(ptype)
+    _particle_functions(ptype, "Coordinates", "Mass", GadgetFieldInfo)


https://bitbucket.org/yt_analysis/yt-3.0/commits/50470049dd08/
Changeset:   50470049dd08
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-30 20:02:09
Summary:     Removing Tipsy's _set_units.
Affected #:  1 file

diff -r 79eeeec29e2cb793b570c3df12544e19cb1987e9 -r 50470049dd08944284627e0f1231495534a7e2b1 yt/frontends/sph/data_structures.py
--- a/yt/frontends/sph/data_structures.py
+++ b/yt/frontends/sph/data_structures.py
@@ -405,13 +405,6 @@
     def __repr__(self):
         return os.path.basename(self.parameter_filename)
 
-    def _set_units(self):
-        self.units = {}
-        self.time_units = {}
-        self.conversion_factors = {}
-        DW = self.domain_right_edge - self.domain_left_edge
-        self.units["unitary"] = 1.0 / DW.max()
-
     def _parse_parameter_file(self):
 
         # The entries in this header are capitalized and named to match Table 4


https://bitbucket.org/yt_analysis/yt-3.0/commits/c003ed58ae1d/
Changeset:   c003ed58ae1d
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-30 20:21:43
Summary:     Adding cosmology_parameters to Tipsy.  Fix unit ratio for Gadget and Tipsy.
Affected #:  1 file

diff -r 50470049dd08944284627e0f1231495534a7e2b1 -r c003ed58ae1d4146faa96f83320adb009c51d79b yt/frontends/sph/data_structures.py
--- a/yt/frontends/sph/data_structures.py
+++ b/yt/frontends/sph/data_structures.py
@@ -257,7 +257,8 @@
         for unit_registry in [mpch, sec_conversion]:
             for unit in sorted(unit_base):
                 if unit in unit_registry:
-                    base = unit_registry[unit] / unit_registry['mpc'] 
+                    ratio = (unit_registry[unit] / unit_registry['mpc'] )
+                    base = unit_base[unit] * ratio
                     break
             if base is None: continue
             for unit in unit_registry:
@@ -381,7 +382,8 @@
                  field_dtypes = None,
                  domain_left_edge = None,
                  domain_right_edge = None,
-                 unit_base = None):
+                 unit_base = None,
+                 cosmology_parameters = None):
         self.endian = endian
         self._root_dimensions = root_dimensions
         # Set up the template for domain files
@@ -399,7 +401,8 @@
         if field_dtypes is None: field_dtypes = {}
         self._field_dtypes = field_dtypes
 
-        unit_base = self._unit_base or {}
+        self._unit_base = unit_base or {}
+        self._cosmology_parameters = cosmology_parameters
         super(TipsyStaticOutput, self).__init__(filename, data_style)
 
     def __repr__(self):
@@ -434,10 +437,16 @@
 
         self.cosmological_simulation = 1
 
-        self.current_redshift = 0.0
-        self.omega_lambda = 0.0
-        self.omega_matter = 0.0
-        self.hubble_constant = 0.0
+        cosm = self._cosmology_parameters or {}
+        dcosm = dict(current_redshift = 0.0,
+                     omega_lambda = 0.0,
+                     omega_matter = 0.0,
+                     hubble_constant = 1.0)
+        for param in ['current_redshift', 'omega_lambda',
+                      'omega_matter', 'hubble_constant']:
+            pval = cosm.get(param, dcosm[param])
+            setattr(self, param, pval)
+
         self.parameters = hvals
 
         self.domain_template = self.parameter_filename


https://bitbucket.org/yt_analysis/yt-3.0/commits/50851ef46600/
Changeset:   50851ef46600
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-24 18:00:17
Summary:     Merging from mainline development.
Affected #:  15 files

diff -r b8521d5e0e89939669e98c352ddc933f9d40eb89 -r 50851ef466000f8b511d6e3295857f4ddb90f612 yt/analysis_modules/absorption_spectrum/absorption_line.py
--- a/yt/analysis_modules/absorption_spectrum/absorption_line.py
+++ b/yt/analysis_modules/absorption_spectrum/absorption_line.py
@@ -24,6 +24,13 @@
 """
 
 import numpy as np
+from yt.utilities.physical_constants import \
+    charge_proton_cgs, \
+    cm_per_km, \
+    km_per_cm, \
+    mass_electron_cgs, \
+    speed_of_light_cgs
+
 
 def voigt(a,u):
     """
@@ -167,10 +174,10 @@
     """
 
     ## constants
-    me = 1.6726231e-24 / 1836.        # grams mass electron 
-    e = 4.8032e-10                    # esu 
-    c = 2.99792456e5                  # km/s
-    ccgs = c * 1.e5                   # cm/s 
+    me = mass_electron_cgs              # grams mass electron 
+    e = charge_proton_cgs               # esu 
+    c = speed_of_light_cgs * km_per_cm  # km/s
+    ccgs = speed_of_light_cgs           # cm/s 
 
     ## shift lam0 by deltav
     if deltav is not None:
@@ -181,7 +188,7 @@
         lam1 = lam0
 
     ## conversions
-    vdop = vkms * 1.e5                # in cm/s
+    vdop = vkms * cm_per_km           # in cm/s
     lam0cgs = lam0 / 1.e8             # rest wavelength in cm
     lam1cgs = lam1 / 1.e8             # line wavelength in cm
     nu1 = ccgs / lam1cgs              # line freq in Hz

diff -r b8521d5e0e89939669e98c352ddc933f9d40eb89 -r 50851ef466000f8b511d6e3295857f4ddb90f612 yt/analysis_modules/halo_finding/halo_objects.py
--- a/yt/analysis_modules/halo_finding/halo_objects.py
+++ b/yt/analysis_modules/halo_finding/halo_objects.py
@@ -45,7 +45,10 @@
 from yt.utilities.performance_counters import \
     yt_counters, time_function
 from yt.utilities.math_utils import periodic_dist, get_rotation_matrix
-from yt.utilities.physical_constants import rho_crit_now, mass_sun_cgs
+from yt.utilities.physical_constants import \
+    rho_crit_now, \
+    mass_sun_cgs, \
+    TINY
 
 from .hop.EnzoHop import RunHOP
 from .fof.EnzoFOF import RunFOF
@@ -60,8 +63,6 @@
     ParallelAnalysisInterface, \
     parallel_blocking_call
 
-TINY = 1.e-40
-
 class Halo(object):
     """
     A data source that returns particle information about the members of a
@@ -1428,7 +1429,7 @@
         fglob = path.join(basedir, 'halos_%d.*.bin' % n)
         files = glob.glob(fglob)
         halos = self._get_halos_binary(files)
-        #Jc = 1.98892e33/pf['mpchcm']*1e5
+        #Jc = mass_sun_cgs/ pf['mpchcm'] * 1e5
         Jc = 1.0
         length = 1.0 / pf['mpchcm']
         conv = dict(pos = np.array([length, length, length,

diff -r b8521d5e0e89939669e98c352ddc933f9d40eb89 -r 50851ef466000f8b511d6e3295857f4ddb90f612 yt/analysis_modules/halo_mass_function/halo_mass_function.py
--- a/yt/analysis_modules/halo_mass_function/halo_mass_function.py
+++ b/yt/analysis_modules/halo_mass_function/halo_mass_function.py
@@ -31,6 +31,11 @@
     ParallelDummy, \
     ParallelAnalysisInterface, \
     parallel_blocking_call
+from yt.utilities.physical_constants import \
+    cm_per_mpc, \
+    mass_sun_cgs, \
+    rho_crit_now
+
 
 class HaloMassFcn(ParallelAnalysisInterface):
     """
@@ -259,7 +264,9 @@
         sigma8_unnorm = math.sqrt(self.sigma_squared_of_R(R));
         sigma_normalization = self.sigma8input / sigma8_unnorm;
 
-        rho0 = self.omega_matter0 * 2.78e+11; # in units of h^2 Msolar/Mpc^3
+        # rho0 in units of h^2 Msolar/Mpc^3
+        rho0 = self.omega_matter0 * \
+                rho_crit_now * cm_per_mpc**3 / mass_sun_cgs
 
         # spacing in mass of our sigma calculation
         dm = (float(self.log_mass_max) - self.log_mass_min)/self.num_sigma_bins;
@@ -294,7 +301,9 @@
     def dndm(self):
         
         # constants - set these before calling any functions!
-        rho0 = self.omega_matter0 * 2.78e+11; # in units of h^2 Msolar/Mpc^3
+        # rho0 in units of h^2 Msolar/Mpc^3
+        rho0 = self.omega_matter0 * \
+                rho_crit_now * cm_per_mpc**3 / mass_sun_cgs
         self.delta_c0 = 1.69;  # critical density for turnaround (Press-Schechter)
         
         nofmz_cum = 0.0;  # keep track of cumulative number density

diff -r b8521d5e0e89939669e98c352ddc933f9d40eb89 -r 50851ef466000f8b511d6e3295857f4ddb90f612 yt/analysis_modules/halo_profiler/multi_halo_profiler.py
--- a/yt/analysis_modules/halo_profiler/multi_halo_profiler.py
+++ b/yt/analysis_modules/halo_profiler/multi_halo_profiler.py
@@ -52,6 +52,9 @@
     parallel_blocking_call, \
     parallel_root_only, \
     parallel_objects
+from yt.utilities.physical_constants import \
+    mass_sun_cgs, \
+    rho_crit_now
 from yt.visualization.fixed_resolution import \
     FixedResolutionBuffer
 from yt.visualization.image_writer import write_image
@@ -951,12 +954,11 @@
         if 'ActualOverdensity' in profile.keys():
             return
 
-        rho_crit_now = 1.8788e-29 * self.pf.hubble_constant**2 # g cm^-3
-        Msun2g = 1.989e33
-        rho_crit = rho_crit_now * ((1.0 + self.pf.current_redshift)**3.0)
+        rhocritnow = rho_crit_now * self.pf.hubble_constant**2 # g cm^-3
+        rho_crit = rhocritnow * ((1.0 + self.pf.current_redshift)**3.0)
         if not self.use_critical_density: rho_crit *= self.pf.omega_matter
 
-        profile['ActualOverdensity'] = (Msun2g * profile['TotalMassMsun']) / \
+        profile['ActualOverdensity'] = (mass_sun_cgs * profile['TotalMassMsun']) / \
             profile['CellVolume'] / rho_crit
 
     def _check_for_needed_profile_fields(self):

diff -r b8521d5e0e89939669e98c352ddc933f9d40eb89 -r 50851ef466000f8b511d6e3295857f4ddb90f612 yt/analysis_modules/spectral_integrator/spectral_frequency_integrator.py
--- a/yt/analysis_modules/spectral_integrator/spectral_frequency_integrator.py
+++ b/yt/analysis_modules/spectral_integrator/spectral_frequency_integrator.py
@@ -37,6 +37,9 @@
 from yt.utilities.exceptions import YTException
 from yt.utilities.linear_interpolators import \
     BilinearFieldInterpolator
+from yt.utilities.physical_constants import \
+    erg_per_eV, \
+    keV_per_Hz
 
 xray_data_version = 1
 
@@ -101,7 +104,7 @@
                   np.power(10, np.concatenate([self.log_E[:-1] - 0.5 * E_diff,
                                                [self.log_E[-1] - 0.5 * E_diff[-1],
                                                 self.log_E[-1] + 0.5 * E_diff[-1]]]))
-        self.dnu = 2.41799e17 * np.diff(self.E_bins)
+        self.dnu = keV_per_Hz * np.diff(self.E_bins)
 
     def _get_interpolator(self, data, e_min, e_max):
         r"""Create an interpolator for total emissivity in a 
@@ -311,7 +314,7 @@
     """
 
     my_si = EmissivityIntegrator(filename=filename)
-    energy_erg = np.power(10, my_si.log_E) * 1.60217646e-9
+    energy_erg = np.power(10, my_si.log_E) * erg_per_eV
 
     em_0 = my_si._get_interpolator((my_si.emissivity_primordial[..., :] / energy_erg),
                                    e_min, e_max)

diff -r b8521d5e0e89939669e98c352ddc933f9d40eb89 -r 50851ef466000f8b511d6e3295857f4ddb90f612 yt/analysis_modules/star_analysis/sfr_spectrum.py
--- a/yt/analysis_modules/star_analysis/sfr_spectrum.py
+++ b/yt/analysis_modules/star_analysis/sfr_spectrum.py
@@ -31,9 +31,13 @@
 from yt.utilities.cosmology import \
     Cosmology, \
     EnzoCosmology
+from yt.utilities.physical_constants import \
+    sec_per_year, \
+    speed_of_light_cgs
 
-YEAR = 3.155693e7 # sec / year
-LIGHT = 2.997925e10 # cm / s
+
+YEAR = sec_per_year # sec / year
+LIGHT = speed_of_light_cgs # cm / s
 
 class StarFormationRate(object):
     r"""Calculates the star formation rate for a given population of

diff -r b8521d5e0e89939669e98c352ddc933f9d40eb89 -r 50851ef466000f8b511d6e3295857f4ddb90f612 yt/analysis_modules/sunrise_export/sunrise_exporter.py
--- a/yt/analysis_modules/sunrise_export/sunrise_exporter.py
+++ b/yt/analysis_modules/sunrise_export/sunrise_exporter.py
@@ -35,6 +35,9 @@
 import numpy as np
 from yt.funcs import *
 import yt.utilities.lib as amr_utils
+from yt.utilities.physical_constants import \
+    kpc_per_cm, \
+    sec_per_year
 from yt.data_objects.universal_fields import add_field
 from yt.mods import *
 
@@ -524,7 +527,7 @@
                         for ax in 'xyz']).transpose()
         # Velocity is cm/s, we want it to be kpc/yr
         #vel *= (pf["kpc"]/pf["cm"]) / (365*24*3600.)
-        vel *= 1.02268944e-14 
+        vel *= kpc_per_cm * sec_per_year
     if initial_mass is None:
         #in solar masses
         initial_mass = dd["particle_mass_initial"][idx]*pf['Msun']

diff -r b8521d5e0e89939669e98c352ddc933f9d40eb89 -r 50851ef466000f8b511d6e3295857f4ddb90f612 yt/data_objects/derived_quantities.py
--- a/yt/data_objects/derived_quantities.py
+++ b/yt/data_objects/derived_quantities.py
@@ -36,6 +36,11 @@
 from yt.utilities.parallel_tools.parallel_analysis_interface import \
     ParallelAnalysisInterface, parallel_objects
 from yt.utilities.lib import Octree
+from yt.utilities.physical_constants import \
+    gravitational_constant_cgs, \
+    mass_sun_cgs, \
+    HUGE
+
 
 __CUDA_BLOCK_SIZE = 256
 
@@ -266,8 +271,7 @@
     M = m_enc.sum()
     J = np.sqrt(((j_mag.sum(axis=0))**2.0).sum())/W
     E = np.sqrt(e_term_pre.sum()/W)
-    G = 6.67e-8 # cm^3 g^-1 s^-2
-    spin = J * E / (M*1.989e33*G)
+    spin = J * E / (M * mass_sun_cgs * gravitational_constant_cgs)
     return spin
 add_quantity("BaryonSpinParameter", function=_BaryonSpinParameter,
              combine_function=_combBaryonSpinParameter, n_ret=4)
@@ -351,7 +355,7 @@
     # Gravitational potential energy
     # We only divide once here because we have velocity in cgs, but radius is
     # in code.
-    G = 6.67e-8 / data.convert("cm") # cm^3 g^-1 s^-2
+    G = gravitational_constant_cgs / data.convert("cm") # cm^3 g^-1 s^-2
     # Check for periodicity of the clump.
     two_root = 2. * np.array(data.pf.domain_width) / np.array(data.pf.domain_dimensions)
     domain_period = data.pf.domain_right_edge - data.pf.domain_left_edge
@@ -573,15 +577,15 @@
     mins, maxs = [], []
     for field in fields:
         if data[field].size < 1:
-            mins.append(1e90)
-            maxs.append(-1e90)
+            mins.append(HUGE)
+            maxs.append(-HUGE)
             continue
         if filter is None:
             if non_zero:
                 nz_filter = data[field]>0.0
                 if not nz_filter.any():
-                    mins.append(1e90)
-                    maxs.append(-1e90)
+                    mins.append(HUGE)
+                    maxs.append(-HUGE)
                     continue
             else:
                 nz_filter = None
@@ -596,8 +600,8 @@
                 mins.append(np.nanmin(data[field][nz_filter]))
                 maxs.append(np.nanmax(data[field][nz_filter]))
             else:
-                mins.append(1e90)
-                maxs.append(-1e90)
+                mins.append(HUGE)
+                maxs.append(-HUGE)
     return len(fields), mins, maxs
 def _combExtrema(data, n_fields, mins, maxs):
     mins, maxs = np.atleast_2d(mins, maxs)
@@ -629,7 +633,7 @@
     This function returns the location of the maximum of a set
     of fields.
     """
-    ma, maxi, mx, my, mz = -1e90, -1, -1, -1, -1
+    ma, maxi, mx, my, mz = -HUGE, -1, -1, -1, -1
     if data[field].size > 0:
         maxi = np.argmax(data[field])
         ma = data[field][maxi]
@@ -647,7 +651,7 @@
     This function returns the location of the minimum of a set
     of fields.
     """
-    ma, mini, mx, my, mz = 1e90, -1, -1, -1, -1
+    ma, mini, mx, my, mz = HUGE, -1, -1, -1, -1
     if data[field].size > 0:
         mini = np.argmin(data[field])
         ma = data[field][mini]

diff -r b8521d5e0e89939669e98c352ddc933f9d40eb89 -r 50851ef466000f8b511d6e3295857f4ddb90f612 yt/data_objects/universal_fields.py
--- a/yt/data_objects/universal_fields.py
+++ b/yt/data_objects/universal_fields.py
@@ -48,15 +48,16 @@
     NeedsParameter
 
 from yt.utilities.physical_constants import \
-     mh, \
-     me, \
-     sigma_thompson, \
-     clight, \
-     kboltz, \
-     G, \
-     rho_crit_now, \
-     speed_of_light_cgs, \
-     km_per_cm, keV_per_K
+    mass_sun_cgs, \
+    mh, \
+    me, \
+    sigma_thompson, \
+    clight, \
+    kboltz, \
+    G, \
+    rho_crit_now, \
+    speed_of_light_cgs, \
+    km_per_cm, keV_per_K
 
 from yt.utilities.math_utils import \
     get_sph_r_component, \
@@ -379,7 +380,7 @@
 def _CellMass(field, data):
     return data["Density"] * data["CellVolume"]
 def _convertCellMassMsun(data):
-    return 5.027854e-34 # g^-1
+    return 1.0 / mass_sun_cgs # g^-1
 add_field("CellMass", function=_CellMass, units=r"\rm{g}")
 add_field("CellMassMsun", units=r"M_{\odot}",
           function=_CellMass,
@@ -458,6 +459,7 @@
     # lens to source
     DLS = data.pf.parameters['cosmology_calculator'].AngularDiameterDistance(
         data.pf.current_redshift, data.pf.parameters['lensing_source_redshift'])
+    # TODO: convert 1.5e14 to constants
     return (((DL * DLS) / DS) * (1.5e14 * data.pf.omega_matter * 
                                 (data.pf.hubble_constant / speed_of_light_cgs)**2 *
                                 (1 + data.pf.current_redshift)))
@@ -520,7 +522,7 @@
     return ((data["Density"].astype('float64')**2.0) \
             *data["Temperature"]**0.5)
 def _convertXRayEmissivity(data):
-    return 2.168e60
+    return 2.168e60 #TODO: convert me to constants
 add_field("XRayEmissivity", function=_XRayEmissivity,
           convert_function=_convertXRayEmissivity,
           projection_conversion="1")
@@ -927,8 +929,8 @@
 add_field("MeanMolecularWeight",function=_MeanMolecularWeight,units=r"")
 
 def _JeansMassMsun(field,data):
-    MJ_constant = (((5*kboltz)/(G*mh))**(1.5)) * \
-    (3/(4*3.1415926535897931))**(0.5) / 1.989e33
+    MJ_constant = (((5.0 * kboltz) / (G * mh)) ** (1.5)) * \
+    (3.0 / (4.0 * np.pi)) ** (0.5) / mass_sun_cgs
 
     return (MJ_constant *
             ((data["Temperature"]/data["MeanMolecularWeight"])**(1.5)) *

diff -r b8521d5e0e89939669e98c352ddc933f9d40eb89 -r 50851ef466000f8b511d6e3295857f4ddb90f612 yt/frontends/ramses/data_structures.py
--- a/yt/frontends/ramses/data_structures.py
+++ b/yt/frontends/ramses/data_structures.py
@@ -403,15 +403,21 @@
         self.time_units['1'] = 1
         self.units['1'] = 1.0
         self.units['unitary'] = 1.0 / (self.domain_right_edge - self.domain_left_edge).max()
-        self.conversion_factors["Density"] = self.parameters['unit_d']
+        rho_u = self.parameters['unit_d']
+        self.conversion_factors["Density"] = rho_u
         vel_u = self.parameters['unit_l'] / self.parameters['unit_t']
+        self.conversion_factors["Pressure"] = rho_u*vel_u**2
         self.conversion_factors["x-velocity"] = vel_u
         self.conversion_factors["y-velocity"] = vel_u
         self.conversion_factors["z-velocity"] = vel_u
+        # Necessary to get the length units in, which are needed for Mass
+        self.conversion_factors['mass'] = rho_u * self.parameters['unit_l']**3
 
     def _setup_nounits_units(self):
+        # Note that unit_l *already* converts to proper!
+        unit_l = self.parameters['unit_l']
         for unit in mpc_conversion.keys():
-            self.units[unit] = self.parameters['unit_l'] * mpc_conversion[unit] / mpc_conversion["cm"]
+            self.units[unit] = unit_l * mpc_conversion[unit] / mpc_conversion["cm"]
         for unit in sec_conversion.keys():
             self.time_units[unit] = self.parameters['unit_t'] / sec_conversion[unit]
 
@@ -460,19 +466,18 @@
         self.domain_right_edge = np.ones(3, dtype='float64')
         # This is likely not true, but I am not sure how to otherwise
         # distinguish them.
-        mylog.warning("No current mechanism of distinguishing cosmological simulations in RAMSES!")
+        mylog.warning("RAMSES frontend assumes all simulations are cosmological!")
         self.cosmological_simulation = 1
         self.periodicity = (True, True, True)
         self.current_redshift = (1.0 / rheader["aexp"]) - 1.0
         self.omega_lambda = rheader["omega_l"]
         self.omega_matter = rheader["omega_m"]
-        self.hubble_constant = rheader["H0"]
+        self.hubble_constant = rheader["H0"] / 100.0 # This is H100
         self.max_level = rheader['levelmax'] - rheader['levelmin']
 
     @classmethod
     def _is_valid(self, *args, **kwargs):
         if not os.path.basename(args[0]).startswith("info_"): return False
         fn = args[0].replace("info_", "amr_").replace(".txt", ".out00001")
-        print fn
         return os.path.exists(fn)
 

diff -r b8521d5e0e89939669e98c352ddc933f9d40eb89 -r 50851ef466000f8b511d6e3295857f4ddb90f612 yt/frontends/ramses/fields.py
--- a/yt/frontends/ramses/fields.py
+++ b/yt/frontends/ramses/fields.py
@@ -34,6 +34,9 @@
     ValidateSpatial, \
     ValidateGridType
 import yt.data_objects.universal_fields
+from yt.utilities.physical_constants import \
+    boltzmann_constant_cgs, \
+    mass_hydrogen_cgs
 
 RAMSESFieldInfo = FieldInfoContainer.create_with_fallback(FieldInfo, "RFI")
 add_field = RAMSESFieldInfo.add_field
@@ -73,6 +76,11 @@
 KnownRAMSESFields["Density"]._projected_units = r"\rm{g}/\rm{cm}^2"
 KnownRAMSESFields["Density"]._convert_function=_convertDensity
 
+def _convertPressure(data):
+    return data.convert("Pressure")
+KnownRAMSESFields["Pressure"]._units=r"\rm{dyne}/\rm{cm}^{2}/\mu"
+KnownRAMSESFields["Pressure"]._convert_function=_convertPressure
+
 def _convertVelocity(data):
     return data.convert("x-velocity")
 for ax in ['x','y','z']:
@@ -101,36 +109,27 @@
                   validators = [ValidateDataField(f)],
                   particle_type = True)
 
-def _ParticleMass(field, data):
-    particles = data["particle_mass"].astype('float64') * \
-                just_one(data["CellVolumeCode"].ravel())
-    # Note that we mandate grid-type here, so this is okay
-    return particles
+for ax in 'xyz':
+    KnownRAMSESFields["particle_velocity_%s" % ax]._convert_function = \
+        _convertVelocity
 
 def _convertParticleMass(data):
-    return data.convert("Density")*(data.convert("cm")**3.0)
-def _IOLevelParticleMass(grid):
-    dd = dict(particle_mass = np.ones(1), CellVolumeCode=grid["CellVolumeCode"])
-    cf = (_ParticleMass(None, dd) * _convertParticleMass(grid))[0]
-    return cf
+    return data.convert("mass")
+
+KnownRAMSESFields["particle_mass"]._convert_function = \
+        _convertParticleMass
+KnownRAMSESFields["particle_mass"]._units = r"\mathrm{g}"
+
 def _convertParticleMassMsun(data):
-    return data.convert("Density")*((data.convert("cm")**3.0)/1.989e33)
-def _IOLevelParticleMassMsun(grid):
-    dd = dict(particle_mass = np.ones(1), CellVolumeCode=grid["CellVolumeCode"])
-    cf = (_ParticleMass(None, dd) * _convertParticleMassMsun(grid))[0]
-    return cf
-add_field("ParticleMass",
-          function=_ParticleMass, validators=[ValidateSpatial(0)],
-          particle_type=True, convert_function=_convertParticleMass,
-          particle_convert_function=_IOLevelParticleMass)
+    return 1.0/1.989e33
+add_field("ParticleMass", function=TranslationFunc("particle_mass"), 
+          particle_type=True)
 add_field("ParticleMassMsun",
-          function=_ParticleMass, validators=[ValidateSpatial(0)],
-          particle_type=True, convert_function=_convertParticleMassMsun,
-          particle_convert_function=_IOLevelParticleMassMsun)
+          function=TranslationFunc("particle_mass"), 
+          particle_type=True, convert_function=_convertParticleMassMsun)
 
-
-def _ParticleMass(field, data):
-    particles = data["particle_mass"].astype('float64') * \
-                just_one(data["CellVolumeCode"].ravel())
-    # Note that we mandate grid-type here, so this is okay
-    return particles
+def _Temperature(field, data):
+    rv = data["Pressure"]/data["Density"]
+    rv *= mass_hydrogen_cgs/boltzmann_constant_cgs
+    return rv
+add_field("Temperature", function=_Temperature, units=r"\rm{K}")

diff -r b8521d5e0e89939669e98c352ddc933f9d40eb89 -r 50851ef466000f8b511d6e3295857f4ddb90f612 yt/geometry/object_finding_mixin.py
--- a/yt/geometry/object_finding_mixin.py
+++ b/yt/geometry/object_finding_mixin.py
@@ -32,6 +32,8 @@
 from yt.utilities.lib import \
     MatchPointsToGrids, \
     GridTree
+from yt.utilities.physical_constants import \
+    HUGE
 
 class ObjectFindingMixin(object) :
 
@@ -83,7 +85,7 @@
         Returns (value, center) of location of minimum for a given field
         """
         gI = np.where(self.grid_levels >= 0) # Slow but pedantic
-        minVal = 1e100
+        minVal = HUGE
         for grid in self.grids[gI[0]]:
             mylog.debug("Checking %s (level %s)", grid.id, grid.Level)
             val, coord = grid.find_min(field)

diff -r b8521d5e0e89939669e98c352ddc933f9d40eb89 -r 50851ef466000f8b511d6e3295857f4ddb90f612 yt/utilities/cosmology.py
--- a/yt/utilities/cosmology.py
+++ b/yt/utilities/cosmology.py
@@ -25,10 +25,16 @@
 """
 
 import numpy as np
+from yt.utilities.physical_constants import \
+    gravitational_constant_cgs, \
+    km_per_cm, \
+    pc_per_mpc, \
+    km_per_pc, \
+    speed_of_light_cgs
 
-c_kms = 2.99792458e5 # c in km/s
-G = 6.67259e-8 # cgs
-kmPerMpc = 3.08567758e19
+c_kms = speed_of_light_cgs * km_per_cm # c in km/s
+G = gravitational_constant_cgs
+kmPerMpc = km_per_pc * pc_per_mpc
 
 class Cosmology(object):
     def __init__(self, HubbleConstantNow = 71.0,
@@ -162,6 +168,7 @@
         """
         # Changed 2.52e17 to 2.52e19 because H_0 is in km/s/Mpc, 
         # instead of 100 km/s/Mpc.
+        # TODO: Move me to physical_units
         return 2.52e19 / np.sqrt(self.OmegaMatterNow) / \
             self.HubbleConstantNow / np.power(1 + self.InitialRedshift,1.5)
 

diff -r b8521d5e0e89939669e98c352ddc933f9d40eb89 -r 50851ef466000f8b511d6e3295857f4ddb90f612 yt/utilities/physical_constants.py
--- a/yt/utilities/physical_constants.py
+++ b/yt/utilities/physical_constants.py
@@ -85,3 +85,7 @@
 kboltz = boltzmann_constant_cgs
 hcgs = planck_constant_cgs
 sigma_thompson = cross_section_thompson_cgs
+
+# Miscellaneous
+HUGE = 1.0e90
+TINY = 1.0e-40

diff -r b8521d5e0e89939669e98c352ddc933f9d40eb89 -r 50851ef466000f8b511d6e3295857f4ddb90f612 yt/visualization/volume_rendering/CUDARayCast.py
--- a/yt/visualization/volume_rendering/CUDARayCast.py
+++ b/yt/visualization/volume_rendering/CUDARayCast.py
@@ -29,6 +29,8 @@
 import yt.extensions.HierarchySubset as hs
 import numpy as np
 import h5py, time
+from yt.utilities.physical_constants import \
+    mass_hydrogen_cgs
 
 import matplotlib;matplotlib.use("Agg");import pylab
 
@@ -62,7 +64,7 @@
 
     print "Constructing transfer function."
     if "Data" in fn:
-        mh = np.log10(1.67e-24)
+        mh = np.log10(mass_hydrogen_cgs)
         tf = ColorTransferFunction((7.5+mh, 14.0+mh))
         tf.add_gaussian( 8.25+mh, 0.002, [0.2, 0.2, 0.4, 0.1])
         tf.add_gaussian( 9.75+mh, 0.002, [0.0, 0.0, 0.3, 0.1])


https://bitbucket.org/yt_analysis/yt-3.0/commits/88ca63e13e85/
Changeset:   88ca63e13e85
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-24 19:40:58
Summary:     First pass at Tipsy units module.
Affected #:  1 file

diff -r 50851ef466000f8b511d6e3295857f4ddb90f612 -r 88ca63e13e85702d078927e6dcb8549d1cf23d94 yt/frontends/sph/data_structures.py
--- a/yt/frontends/sph/data_structures.py
+++ b/yt/frontends/sph/data_structures.py
@@ -44,6 +44,10 @@
     OctreeSubset
 from yt.utilities.definitions import \
     mpc_conversion, sec_conversion
+from yt.utilities.physical_constants import \
+    gravitational_constant_cgs, \
+    km_per_pc
+import yt.utilities.physical_constants as pcons
 from .fields import \
     OWLSFieldInfo, \
     KnownOWLSFields, \
@@ -352,6 +356,7 @@
 
     def __init__(self, filename, data_style="tipsy",
                  root_dimensions = 64, endian = ">",
+                 box_size = None, hubble_constant = None,
                  field_dtypes = None,
                  domain_left_edge = None,
                  domain_right_edge = None):
@@ -428,3 +433,26 @@
     def _is_valid(self, *args, **kwargs):
         # We do not allow load() of these files.
         return False
+
+    @classmethod
+    def calculate_tipsy_units(self, hubble_constant, box_size):
+        # box_size in cm, or else in a unit we can convert to cm
+        # hubble_constant is assumed to be in units scaled to 100 km / s / Mpc
+        hubble_hertz = hubble_constant / (km_per_pc * 1e4)
+        if isinstance(box_size, types.TupleType):
+            if not isinstance(box_size[1], types.StringTypes):
+                raise RuntimeError
+            conversion = getattr(pcons, "cm_per_%s" % box_size[1], None)
+            if conversion is None:
+                raise RuntimeError
+            box_size = box_size[0] * conversion
+        print hubble_hertz, box_size
+        units = {}
+        units['length'] = box_size
+        units['density'] = 3.0 * hubble_hertz**2 / \
+                          (8.0 * np.pi * gravitational_constant_cgs)
+        # density is in g/cm^3
+        units['mass'] = units['density'] * units['length']**3.0
+        units['time'] = 1.0 / np.sqrt(gravitational_constant_cgs * units['density'])
+        units['velocity'] = units['length'] / units['time']
+        return units


https://bitbucket.org/yt_analysis/yt-3.0/commits/8e51019f682e/
Changeset:   8e51019f682e
Branch:      yt-3.0
User:        ngoldbaum
Date:        2013-05-24 19:38:18
Summary:     Fixing the incorrect conversion factor from km to parsec.

physical_constants.py edited online with Bitbucket
Affected #:  1 file

diff -r 88ca63e13e85702d078927e6dcb8549d1cf23d94 -r 8e51019f682e67f667788d9a98764ae19bb5d58e yt/utilities/physical_constants.py
--- a/yt/utilities/physical_constants.py
+++ b/yt/utilities/physical_constants.py
@@ -42,7 +42,7 @@
 mpc_per_miles = 5.21552871e-20
 mpc_per_cm    = 3.24077929e-25
 kpc_per_cm    = mpc_per_cm / mpc_per_kpc
-km_per_pc     = 1.3806504e13
+km_per_pc     = 3.08567758e13
 km_per_m      = 1e-3
 km_per_cm     = 1e-5
 pc_per_cm     = 3.24077929e-19


https://bitbucket.org/yt_analysis/yt-3.0/commits/6e369093aeca/
Changeset:   6e369093aeca
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-30 21:22:51
Summary:     Fix up some time units setting for Particle files.

Also have re-implemented a portion of the tipsy units module, which I will now
merge with the one I implemented a week ago.

Added several known tipsy fields.
Affected #:  3 files

diff -r c003ed58ae1d4146faa96f83320adb009c51d79b -r 6e369093aeca7ad1e5be70725939d576eb2c4fe1 yt/frontends/sph/data_structures.py
--- a/yt/frontends/sph/data_structures.py
+++ b/yt/frontends/sph/data_structures.py
@@ -44,6 +44,9 @@
     OctreeSubset
 from yt.utilities.definitions import \
     mpc_conversion, sec_conversion
+from yt.utilities.physical_constants import \
+    G
+from yt.utilities.cosmology import Cosmology
 from .fields import \
     OWLSFieldInfo, \
     KnownOWLSFields, \
@@ -254,15 +257,17 @@
             mpch['%shcm' % unit] = (mpch["%sh" % unit] / 
                     (1 + self.current_redshift))
             mpch['%scm' % unit] = mpch[unit] / (1 + self.current_redshift)
-        for unit_registry in [mpch, sec_conversion]:
+        # ud == unit destination
+        # ur == unit registry
+        for ud, ur in [(self.units, mpch), (self.time_units, sec_conversion)]:
             for unit in sorted(unit_base):
-                if unit in unit_registry:
-                    ratio = (unit_registry[unit] / unit_registry['mpc'] )
+                if unit in ur:
+                    ratio = (ur[unit] / ur['mpc'] )
                     base = unit_base[unit] * ratio
                     break
             if base is None: continue
-            for unit in unit_registry:
-                self.units[unit] = unit_registry[unit] / base
+            for unit in ur:
+                ud[unit] = ur[unit] / base
 
 class GadgetStaticOutput(ParticleStaticOutput):
     _hierarchy_class = ParticleGeometryHandler
@@ -454,6 +459,22 @@
 
         f.close()
 
+    def _set_units(self):
+        super(TipsyStaticOutput, self)._set_units()
+        DW = (self.domain_right_edge - self.domain_left_edge).max()
+        cosmo = Cosmology(self.hubble_constant * 100.0,
+                          self.omega_matter, self.omega_lambda)
+        length_unit = DW * self.units['cm'] # Get it in proper cm
+        density_unit = cosmo.CriticalDensity(self.current_redshift)
+        mass_unit = density_unit * length_unit**3
+        time_unit = 1.0 / np.sqrt(G*density_unit)
+        velocity_unit = length_unit / time_unit
+        self.conversion_factors["velocity"] = velocity_unit
+        self.conversion_factors["mass"] = mass_unit
+        self.conversion_factors["density"] = density_unit
+        for u in sec_conversion:
+            self.time_units[u] = time_unit * sec_conversion[u]
+
     @classmethod
     def _is_valid(self, *args, **kwargs):
         # We do not allow load() of these files.

diff -r c003ed58ae1d4146faa96f83320adb009c51d79b -r 6e369093aeca7ad1e5be70725939d576eb2c4fe1 yt/frontends/sph/fields.py
--- a/yt/frontends/sph/fields.py
+++ b/yt/frontends/sph/fields.py
@@ -33,7 +33,9 @@
     ValidateDataField, \
     ValidateProperty, \
     ValidateSpatial, \
-    ValidateGridType
+    ValidateGridType, \
+    NullFunc, \
+    TranslationFunc
 import yt.data_objects.universal_fields
 
 OWLSFieldInfo = FieldInfoContainer.create_with_fallback(FieldInfo)
@@ -76,8 +78,21 @@
              units = r"\mathrm{g}/\mathrm{cm}^{3}",
              projection_conversion = 'cm')
 
+
+def _get_conv(cf):
+    def _convert(data):
+        return data.convert(cf)
+
 for ptype in ["Gas", "DarkMatter", "Stars"]:
     _particle_functions(ptype, "Coordinates", "Mass", TipsyFieldInfo)
+    KnownTipsyFields.add_field((ptype, "Mass"), function=NullFunc,
+        particle_type = True,
+        convert_function=_get_conv("mass"),
+        units = r"\mathrm{g}")
+    KnownTipsyFields.add_field((ptype, "Velocities"), function=NullFunc,
+        particle_type = True,
+        convert_function=_get_conv("velocity"),
+        units = r"\mathrm{cm}/\mathrm{s}")
    
 # GADGET
 # ======

diff -r c003ed58ae1d4146faa96f83320adb009c51d79b -r 6e369093aeca7ad1e5be70725939d576eb2c4fe1 yt/utilities/cosmology.py
--- a/yt/utilities/cosmology.py
+++ b/yt/utilities/cosmology.py
@@ -109,6 +109,8 @@
         return (self.AngularDiameterDistance(z_i,z_f) / 648. * np.pi)
 
     def CriticalDensity(self,z):
+        return ( (3.0 * (self.HubbleConstantNow / kmPerMpc)**2.0)
+               / (8.0 * np.pi * G) )
         return (3.0 / 8.0 / np.pi * sqr(self.HubbleConstantNow / kmPerMpc) / G *
                 (self.OmegaLambdaNow + ((1 + z)**3.0) * self.OmegaMatterNow))
 


https://bitbucket.org/yt_analysis/yt-3.0/commits/b94173eb9dc1/
Changeset:   b94173eb9dc1
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-30 21:25:10
Summary:     Merging, including the calculate_tipsy_units function
Affected #:  2 files

diff -r 6e369093aeca7ad1e5be70725939d576eb2c4fe1 -r b94173eb9dc11c1bdab3e385fd52838753416443 yt/frontends/sph/data_structures.py
--- a/yt/frontends/sph/data_structures.py
+++ b/yt/frontends/sph/data_structures.py
@@ -45,7 +45,9 @@
 from yt.utilities.definitions import \
     mpc_conversion, sec_conversion
 from yt.utilities.physical_constants import \
-    G
+    G, \
+    gravitational_constant_cgs, \
+    km_per_pc
 from yt.utilities.cosmology import Cosmology
 from .fields import \
     OWLSFieldInfo, \
@@ -479,3 +481,26 @@
     def _is_valid(self, *args, **kwargs):
         # We do not allow load() of these files.
         return False
+
+    @classmethod
+    def calculate_tipsy_units(self, hubble_constant, box_size):
+        # box_size in cm, or else in a unit we can convert to cm
+        # hubble_constant is assumed to be in units scaled to 100 km / s / Mpc
+        hubble_hertz = hubble_constant / (km_per_pc * 1e4)
+        if isinstance(box_size, types.TupleType):
+            if not isinstance(box_size[1], types.StringTypes):
+                raise RuntimeError
+            conversion = getattr(pcons, "cm_per_%s" % box_size[1], None)
+            if conversion is None:
+                raise RuntimeError
+            box_size = box_size[0] * conversion
+        print hubble_hertz, box_size
+        units = {}
+        units['length'] = box_size
+        units['density'] = 3.0 * hubble_hertz**2 / \
+                          (8.0 * np.pi * gravitational_constant_cgs)
+        # density is in g/cm^3
+        units['mass'] = units['density'] * units['length']**3.0
+        units['time'] = 1.0 / np.sqrt(gravitational_constant_cgs * units['density'])
+        units['velocity'] = units['length'] / units['time']
+        return units

diff -r 6e369093aeca7ad1e5be70725939d576eb2c4fe1 -r b94173eb9dc11c1bdab3e385fd52838753416443 yt/utilities/physical_constants.py
--- a/yt/utilities/physical_constants.py
+++ b/yt/utilities/physical_constants.py
@@ -42,7 +42,7 @@
 mpc_per_miles = 5.21552871e-20
 mpc_per_cm    = 3.24077929e-25
 kpc_per_cm    = mpc_per_cm / mpc_per_kpc
-km_per_pc     = 1.3806504e13
+km_per_pc     = 3.08567758e13
 km_per_m      = 1e-3
 km_per_cm     = 1e-5
 pc_per_cm     = 3.24077929e-19


https://bitbucket.org/yt_analysis/yt-3.0/commits/2b801eff5ff8/
Changeset:   2b801eff5ff8
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-30 21:37:23
Summary:     Removed calculate_tipsy_units and fixed /h length units
Affected #:  1 file

diff -r b94173eb9dc11c1bdab3e385fd52838753416443 -r 2b801eff5ff81e00890781251a1a200616058894 yt/frontends/sph/data_structures.py
--- a/yt/frontends/sph/data_structures.py
+++ b/yt/frontends/sph/data_structures.py
@@ -255,7 +255,7 @@
         mpch.update(mpc_conversion)
         unit_base = self._unit_base or {}
         for unit in mpc_conversion:
-            mpch['%sh' % unit] = mpch[unit] / self.hubble_constant
+            mpch['%sh' % unit] = mpch[unit] * self.hubble_constant
             mpch['%shcm' % unit] = (mpch["%sh" % unit] / 
                     (1 + self.current_redshift))
             mpch['%scm' % unit] = mpch[unit] / (1 + self.current_redshift)
@@ -481,26 +481,3 @@
     def _is_valid(self, *args, **kwargs):
         # We do not allow load() of these files.
         return False
-
-    @classmethod
-    def calculate_tipsy_units(self, hubble_constant, box_size):
-        # box_size in cm, or else in a unit we can convert to cm
-        # hubble_constant is assumed to be in units scaled to 100 km / s / Mpc
-        hubble_hertz = hubble_constant / (km_per_pc * 1e4)
-        if isinstance(box_size, types.TupleType):
-            if not isinstance(box_size[1], types.StringTypes):
-                raise RuntimeError
-            conversion = getattr(pcons, "cm_per_%s" % box_size[1], None)
-            if conversion is None:
-                raise RuntimeError
-            box_size = box_size[0] * conversion
-        print hubble_hertz, box_size
-        units = {}
-        units['length'] = box_size
-        units['density'] = 3.0 * hubble_hertz**2 / \
-                          (8.0 * np.pi * gravitational_constant_cgs)
-        # density is in g/cm^3
-        units['mass'] = units['density'] * units['length']**3.0
-        units['time'] = 1.0 / np.sqrt(gravitational_constant_cgs * units['density'])
-        units['velocity'] = units['length'] / units['time']
-        return units


https://bitbucket.org/yt_analysis/yt-3.0/commits/a7f1fe1a3873/
Changeset:   a7f1fe1a3873
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-30 21:43:44
Summary:     Have to return the _convert function
Affected #:  1 file

diff -r 2b801eff5ff81e00890781251a1a200616058894 -r a7f1fe1a38730dbbe55f836fee5dbacb5809f878 yt/frontends/sph/fields.py
--- a/yt/frontends/sph/fields.py
+++ b/yt/frontends/sph/fields.py
@@ -82,6 +82,7 @@
 def _get_conv(cf):
     def _convert(data):
         return data.convert(cf)
+    return _convert
 
 for ptype in ["Gas", "DarkMatter", "Stars"]:
     _particle_functions(ptype, "Coordinates", "Mass", TipsyFieldInfo)


https://bitbucket.org/yt_analysis/yt-3.0/commits/f1ff005e52c7/
Changeset:   f1ff005e52c7
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-30 22:40:12
Summary:     Setting up Gadget units, with a few reasonable defaults.
Affected #:  2 files

diff -r a7f1fe1a38730dbbe55f836fee5dbacb5809f878 -r f1ff005e52c7d447270790dbb5a7c21e421ff189 yt/frontends/sph/data_structures.py
--- a/yt/frontends/sph/data_structures.py
+++ b/yt/frontends/sph/data_structures.py
@@ -300,6 +300,8 @@
         self._root_dimensions = root_dimensions
         # Set up the template for domain files
         self.storage_filename = None
+        if unit_base is not None and "UnitLength_in_cm" in unit_base:
+            unit_base['cm'] = unit_base["UnitLength_in_cm"]
         self._unit_base = unit_base
         super(GadgetStaticOutput, self).__init__(filename, data_style)
 
@@ -352,6 +354,22 @@
 
         f.close()
 
+    def _set_units(self):
+        super(GadgetStaticOutput, self)._set_units()
+        length_unit = self.units['cm']
+        unit_base = self._unit_base or {}
+        velocity_unit = unit_base.get("velocity", 1e5)
+        velocity_unit = unit_base.get("UnitVelocity_in_cm_per_s", velocity_unit)
+        mass_unit = unit_base.get("g", 1.989e43 / self.hubble_constant)
+        mass_unit = unit_base.get("UnitMass_in_g", mass_unit)
+        time_unit = length_unit / velocity_unit
+        self.conversion_factors["velocity"] = velocity_unit
+        self.conversion_factors["mass"] = mass_unit
+        self.conversion_factors["density"] = mass_unit / length_unit**3
+        #import pdb; pdb.set_trace()
+        for u in sec_conversion:
+            self.time_units[u] = time_unit * sec_conversion[u]
+
     @classmethod
     def _is_valid(self, *args, **kwargs):
         # We do not allow load() of these files.

diff -r a7f1fe1a38730dbbe55f836fee5dbacb5809f878 -r f1ff005e52c7d447270790dbb5a7c21e421ff189 yt/frontends/sph/fields.py
--- a/yt/frontends/sph/fields.py
+++ b/yt/frontends/sph/fields.py
@@ -37,6 +37,8 @@
     NullFunc, \
     TranslationFunc
 import yt.data_objects.universal_fields
+from yt.utilities.physical_constants import \
+    mass_sun_cgs
 
 OWLSFieldInfo = FieldInfoContainer.create_with_fallback(FieldInfo)
 add_owls_field = OWLSFieldInfo.add_field
@@ -64,6 +66,7 @@
     registry.add_field(("deposit", "%s_count" % ptype),
              function = particle_count,
              validators = [ValidateSpatial()],
+             display_name = "\\mathrm{%s Count}" % ptype,
              projection_conversion = '1')
 
     def particle_density(field, data):
@@ -75,9 +78,28 @@
     registry.add_field(("deposit", "%s_density" % ptype),
              function = particle_density,
              validators = [ValidateSpatial()],
+             display_name = "\\mathrm{%s Density}" % ptype,
              units = r"\mathrm{g}/\mathrm{cm}^{3}",
+             projected_units = r"\mathrm{g}/\mathrm{cm}^{-2}",
              projection_conversion = 'cm')
 
+    # Now some translation functions.
+
+    registry.add_field((ptype, "ParticleMass"),
+            function = TranslationFunc((ptype, mass_name)),
+            particle_type = True,
+            units = r"\mathrm{g}")
+
+    def _ParticleMassMsun(field, data):
+        return data[ptype, mass_name].copy()
+    def _conv_Msun(data):
+        return 1.0/mass_sun_cgs
+
+    registry.add_field((ptype, "ParticleMassMsun"),
+            function = _ParticleMassMsun,
+            convert_function = _conv_Msun,
+            particle_type = True,
+            units = r"\mathrm{M}_\odot")
 
 def _get_conv(cf):
     def _convert(data):
@@ -85,7 +107,6 @@
     return _convert
 
 for ptype in ["Gas", "DarkMatter", "Stars"]:
-    _particle_functions(ptype, "Coordinates", "Mass", TipsyFieldInfo)
     KnownTipsyFields.add_field((ptype, "Mass"), function=NullFunc,
         particle_type = True,
         convert_function=_get_conv("mass"),
@@ -94,7 +115,10 @@
         particle_type = True,
         convert_function=_get_conv("velocity"),
         units = r"\mathrm{cm}/\mathrm{s}")
-   
+    # Note that we have to do this last so that TranslationFunc operates
+    # correctly.
+    _particle_functions(ptype, "Coordinates", "Mass", TipsyFieldInfo)
+
 # GADGET
 # ======
 
@@ -106,13 +130,23 @@
     def _Mass(field, data):
         pind = _gadget_ptypes.index(ptype)
         if data.pf["Massarr"][pind] == 0.0:
-            return data[ptype, "Masses"]
+            return data[ptype, "Masses"].copy()
         mass = np.ones(data[ptype, "Coordinates"].shape[0], dtype="float64")
-        mass *= data.pf["Massarr"][pind]
+        # Note that this is an alias, which is why we need to apply conversion
+        # here.  Otherwise we'd have an asymmetry.
+        mass *= data.pf["Massarr"][pind] * data.convert("mass")
         return mass
     GadgetFieldInfo.add_field((ptype, "Mass"), function=_Mass,
                               particle_type = True)
 
 for ptype in _gadget_ptypes:
     _gadget_particle_fields(ptype)
+    KnownGadgetFields.add_field((ptype, "Masses"), function=NullFunc,
+        particle_type = True,
+        convert_function=_get_conv("mass"),
+        units = r"\mathrm{g}")
+    KnownGadgetFields.add_field((ptype, "Velocities"), function=NullFunc,
+        particle_type = True,
+        convert_function=_get_conv("velocity"),
+        units = r"\mathrm{cm}/\mathrm{s}")
     _particle_functions(ptype, "Coordinates", "Mass", GadgetFieldInfo)


https://bitbucket.org/yt_analysis/yt-3.0/commits/469b511ff712/
Changeset:   469b511ff712
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-31 00:28:11
Summary:     Adding an "all" mass field for Gadget.

This also includes a fix for getting the most recently used field info, field
detection for tuple-based selection, and a slight improvement to the speed of
IO for particle masses.  A more generic solution is needed for the "all"
particle type, which should probably get pushed into the particle IO handler at
a higher level.
Affected #:  5 files

diff -r f1ff005e52c7d447270790dbb5a7c21e421ff189 -r 469b511ff71298d9fb0019ca08428a1b0bf5651c yt/data_objects/field_info_container.py
--- a/yt/data_objects/field_info_container.py
+++ b/yt/data_objects/field_info_container.py
@@ -265,15 +265,22 @@
                 + 1e-4*np.random.random((nd * nd * nd)))
 
     def __missing__(self, item):
-        FI = getattr(self.pf, "field_info", FieldInfo)
-        if FI.has_key(item) and FI[item]._function.func_name != 'NullFunc':
+        if hasattr(self.pf, "field_info") and isinstance(item, tuple):
+            finfo = self.pf._get_field_info(*item)
+        else:
+            FI = getattr(self.pf, "field_info", FieldInfo)
+            if item in FI:
+                finfo = FI[item]
+            else:
+                finfo = None
+        if finfo is not None and finfo._function.func_name != 'NullFunc':
             try:
-                vv = FI[item](self)
+                vv = finfo(self)
             except NeedsGridType as exc:
                 ngz = exc.ghost_zones
                 nfd = FieldDetector(self.nd + ngz * 2)
                 nfd._num_ghost_zones = ngz
-                vv = FI[item](nfd)
+                vv = finfo(nfd)
                 if ngz > 0: vv = vv[ngz:-ngz, ngz:-ngz, ngz:-ngz]
                 for i in nfd.requested:
                     if i not in self.requested: self.requested.append(i)

diff -r f1ff005e52c7d447270790dbb5a7c21e421ff189 -r 469b511ff71298d9fb0019ca08428a1b0bf5651c yt/data_objects/static_output.py
--- a/yt/data_objects/static_output.py
+++ b/yt/data_objects/static_output.py
@@ -255,12 +255,14 @@
         if ftype == "unknown" and self._last_freq[0] != None:
             ftype = self._last_freq[0]
         field = (ftype, fname)
-        if field == self._last_freq or fname == self._last_freq[1]:
+        if field == self._last_freq:
             return self._last_finfo
         if field in self.field_info:
             self._last_freq = field
             self._last_finfo = self.field_info[(ftype, fname)]
             return self._last_finfo
+        if fname == self._last_freq[1]:
+            return self._last_finfo
         if fname in self.field_info:
             self._last_freq = field
             self._last_finfo = self.field_info[fname]

diff -r f1ff005e52c7d447270790dbb5a7c21e421ff189 -r 469b511ff71298d9fb0019ca08428a1b0bf5651c yt/frontends/sph/data_structures.py
--- a/yt/frontends/sph/data_structures.py
+++ b/yt/frontends/sph/data_structures.py
@@ -124,6 +124,7 @@
         self.field_list = pfl
         pf = self.parameter_file
         pf.particle_types = tuple(set(pt for pt, pf in pfl))
+        pf.particle_types += ('all',)
     
     def _setup_classes(self):
         dd = self._get_data_reader_dict()

diff -r f1ff005e52c7d447270790dbb5a7c21e421ff189 -r 469b511ff71298d9fb0019ca08428a1b0bf5651c yt/frontends/sph/fields.py
--- a/yt/frontends/sph/fields.py
+++ b/yt/frontends/sph/fields.py
@@ -126,12 +126,12 @@
 
 _gadget_ptypes = ("Gas", "Halo", "Disk", "Bulge", "Stars", "Bndry")
 
-def _gadget_particle_fields(ptype):
+def _gadget_particle_fields(_ptype):
     def _Mass(field, data):
         pind = _gadget_ptypes.index(ptype)
         if data.pf["Massarr"][pind] == 0.0:
             return data[ptype, "Masses"].copy()
-        mass = np.ones(data[ptype, "Coordinates"].shape[0], dtype="float64")
+        mass = np.ones(data[ptype, "ParticleIDs"].shape[0], dtype="float64")
         # Note that this is an alias, which is why we need to apply conversion
         # here.  Otherwise we'd have an asymmetry.
         mass *= data.pf["Massarr"][pind] * data.convert("mass")
@@ -139,6 +139,16 @@
     GadgetFieldInfo.add_field((ptype, "Mass"), function=_Mass,
                               particle_type = True)
 
+def _AllGadgetMass(field, data):
+    v = []
+    for ptype in data.pf.particle_types:
+        if ptype == "all": continue
+        v.append(data[ptype, "Mass"].copy())
+    masses = np.concatenate(v)
+    return masses
+GadgetFieldInfo.add_field(("all", "Mass"), function=_AllGadgetMass,
+        particle_type = True, units = r"\mathrm{g}")
+
 for ptype in _gadget_ptypes:
     _gadget_particle_fields(ptype)
     KnownGadgetFields.add_field((ptype, "Masses"), function=NullFunc,
@@ -150,3 +160,5 @@
         convert_function=_get_conv("velocity"),
         units = r"\mathrm{cm}/\mathrm{s}")
     _particle_functions(ptype, "Coordinates", "Mass", GadgetFieldInfo)
+#_gadget_particle_fields("all")
+_particle_functions("all", "Coordinates", "Mass", GadgetFieldInfo)

diff -r f1ff005e52c7d447270790dbb5a7c21e421ff189 -r 469b511ff71298d9fb0019ca08428a1b0bf5651c yt/frontends/sph/io.py
--- a/yt/frontends/sph/io.py
+++ b/yt/frontends/sph/io.py
@@ -163,12 +163,32 @@
         rv = {}
         # We first need a set of masks for each particle type
         ptf = defaultdict(list)
+        ptall = []
         psize = defaultdict(lambda: 0)
         chunks = list(chunks)
+        pf = chunks[0].objs[0].domain.pf
+        aptypes = [ptype for ptype in pf.particle_types if ptype != "all"]
         ptypes = set()
         for ftype, fname in fields:
-            ptf[ftype].append(fname)
-            ptypes.add(ftype)
+            if ftype == "all":
+                # We simply read everything and concatenate them. 
+                ptall += [(ptype, fname) for ptype in aptypes]
+            else:
+                ptf[ftype].append(fname)
+                ptypes.add(ftype)
+        if len(ptall) > 0:
+            fv = self._read_particle_selection(chunks, selector, ptall)
+            # Now we have a dict of the return values, and we need to
+            # concatenate
+            fields = set(fname for ftype, fname in fv)
+            for field in fields:
+                v = []
+                for ptype in aptypes:
+                    va = fv.pop((ptype, field), None)
+                    if va is None: continue
+                    v.append(va)
+                rv["all", field] = np.concatenate(v, axis=0)
+        if len(ptf) == 0: return rv
         ptypes = list(ptypes)
         ptypes.sort(key = lambda a: self._ptypes.index(a))
         for chunk in chunks:


https://bitbucket.org/yt_analysis/yt-3.0/commits/baf520758359/
Changeset:   baf520758359
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-31 00:33:47
Summary:     Adding "all" fields for other Gadget fields.

This will ultimately need to be streamlined so that new columns can be added to
Gadget outputs.
Affected #:  1 file

diff -r 469b511ff71298d9fb0019ca08428a1b0bf5651c -r baf520758359c5ff1237964815625e4276ac9afc yt/frontends/sph/fields.py
--- a/yt/frontends/sph/fields.py
+++ b/yt/frontends/sph/fields.py
@@ -139,15 +139,22 @@
     GadgetFieldInfo.add_field((ptype, "Mass"), function=_Mass,
                               particle_type = True)
 
-def _AllGadgetMass(field, data):
-    v = []
-    for ptype in data.pf.particle_types:
-        if ptype == "all": continue
-        v.append(data[ptype, "Mass"].copy())
-    masses = np.concatenate(v)
-    return masses
-GadgetFieldInfo.add_field(("all", "Mass"), function=_AllGadgetMass,
-        particle_type = True, units = r"\mathrm{g}")
+def _field_concat(fname):
+    def _AllFields(field, data):
+        v = []
+        for ptype in data.pf.particle_types:
+            if ptype == "all": continue
+            v.append(data[ptype, fname].copy())
+        rv = np.concatenate(v, axis=0)
+        return rv
+    return _AllFields
+
+for fname in ["Coordinates", "Velocities", "ParticleIDs",
+              # Note: Mass, not Masses
+              "Mass"]:
+    func = _field_concat(fname)
+    GadgetFieldInfo.add_field(("all", fname), function=func,
+            particle_type = True)
 
 for ptype in _gadget_ptypes:
     _gadget_particle_fields(ptype)


https://bitbucket.org/yt_analysis/yt-3.0/commits/379df93d70a7/
Changeset:   379df93d70a7
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-31 00:57:42
Summary:     We were missing the crucial check of whether or not a field was a particle
field during detection.  I have also removed the IO-level particle field
concatenation; this is actually much simpler to do higher up, although that
comes at something of a higher cost when field dependencies are not
pre-calculated.  (Fortunately they are, so this should not hit the disk more
frequently.)
Affected #:  4 files

diff -r baf520758359c5ff1237964815625e4276ac9afc -r 379df93d70a7e2b7e462ed5122c6dcbcc65e1ecd yt/data_objects/field_info_container.py
--- a/yt/data_objects/field_info_container.py
+++ b/yt/data_objects/field_info_container.py
@@ -291,6 +291,10 @@
                 if not self.flat: self[item] = vv
                 else: self[item] = vv.ravel()
                 return self[item]
+        elif finfo is not None and finfo.particle_type:
+            self[item] = np.ones(self.NumberOfParticles)
+            self.requested.append(item)
+            return self[item]
         self.requested.append(item)
         return defaultdict.__missing__(self, item)
 

diff -r baf520758359c5ff1237964815625e4276ac9afc -r 379df93d70a7e2b7e462ed5122c6dcbcc65e1ecd yt/frontends/sph/data_structures.py
--- a/yt/frontends/sph/data_structures.py
+++ b/yt/frontends/sph/data_structures.py
@@ -367,7 +367,6 @@
         self.conversion_factors["velocity"] = velocity_unit
         self.conversion_factors["mass"] = mass_unit
         self.conversion_factors["density"] = mass_unit / length_unit**3
-        #import pdb; pdb.set_trace()
         for u in sec_conversion:
             self.time_units[u] = time_unit * sec_conversion[u]
 

diff -r baf520758359c5ff1237964815625e4276ac9afc -r 379df93d70a7e2b7e462ed5122c6dcbcc65e1ecd yt/frontends/sph/fields.py
--- a/yt/frontends/sph/fields.py
+++ b/yt/frontends/sph/fields.py
@@ -126,7 +126,7 @@
 
 _gadget_ptypes = ("Gas", "Halo", "Disk", "Bulge", "Stars", "Bndry")
 
-def _gadget_particle_fields(_ptype):
+def _gadget_particle_fields(ptype):
     def _Mass(field, data):
         pind = _gadget_ptypes.index(ptype)
         if data.pf["Massarr"][pind] == 0.0:
@@ -157,11 +157,11 @@
             particle_type = True)
 
 for ptype in _gadget_ptypes:
-    _gadget_particle_fields(ptype)
     KnownGadgetFields.add_field((ptype, "Masses"), function=NullFunc,
         particle_type = True,
         convert_function=_get_conv("mass"),
         units = r"\mathrm{g}")
+    _gadget_particle_fields(ptype)
     KnownGadgetFields.add_field((ptype, "Velocities"), function=NullFunc,
         particle_type = True,
         convert_function=_get_conv("velocity"),

diff -r baf520758359c5ff1237964815625e4276ac9afc -r 379df93d70a7e2b7e462ed5122c6dcbcc65e1ecd yt/frontends/sph/io.py
--- a/yt/frontends/sph/io.py
+++ b/yt/frontends/sph/io.py
@@ -167,28 +167,10 @@
         psize = defaultdict(lambda: 0)
         chunks = list(chunks)
         pf = chunks[0].objs[0].domain.pf
-        aptypes = [ptype for ptype in pf.particle_types if ptype != "all"]
         ptypes = set()
         for ftype, fname in fields:
-            if ftype == "all":
-                # We simply read everything and concatenate them. 
-                ptall += [(ptype, fname) for ptype in aptypes]
-            else:
-                ptf[ftype].append(fname)
-                ptypes.add(ftype)
-        if len(ptall) > 0:
-            fv = self._read_particle_selection(chunks, selector, ptall)
-            # Now we have a dict of the return values, and we need to
-            # concatenate
-            fields = set(fname for ftype, fname in fv)
-            for field in fields:
-                v = []
-                for ptype in aptypes:
-                    va = fv.pop((ptype, field), None)
-                    if va is None: continue
-                    v.append(va)
-                rv["all", field] = np.concatenate(v, axis=0)
-        if len(ptf) == 0: return rv
+            ptf[ftype].append(fname)
+            ptypes.add(ftype)
         ptypes = list(ptypes)
         ptypes.sort(key = lambda a: self._ptypes.index(a))
         for chunk in chunks:


https://bitbucket.org/yt_analysis/yt-3.0/commits/6e84de91f77b/
Changeset:   6e84de91f77b
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-31 16:32:02
Summary:     Adding translations for particle_position and particle_velocity.

The field detection logic is getting more convoluted, and this speaks to really
needing to address vector fields.  However, with this change I can now run HOP
on a Gadget dataset.  That being said, it also over-reads data, since we're not
yet batching particle fields or preloading in the halo finder.  So for each
component, it reads xyz individually, which requires reading Coordinates again.
Affected #:  2 files

diff -r 379df93d70a7e2b7e462ed5122c6dcbcc65e1ecd -r 6e84de91f77bf2c190a8e2f7c2317138881c1abc yt/data_objects/field_info_container.py
--- a/yt/data_objects/field_info_container.py
+++ b/yt/data_objects/field_info_container.py
@@ -292,7 +292,13 @@
                 else: self[item] = vv.ravel()
                 return self[item]
         elif finfo is not None and finfo.particle_type:
-            self[item] = np.ones(self.NumberOfParticles)
+            if item == "Coordinates" or item[1] == "Coordinates" or \
+               item == "Velocities" or item[1] == "Velocities":
+                # A vector
+                self[item] = np.ones((self.NumberOfParticles, 3))
+            else:
+                # Not a vector
+                self[item] = np.ones(self.NumberOfParticles)
             self.requested.append(item)
             return self[item]
         self.requested.append(item)

diff -r 379df93d70a7e2b7e462ed5122c6dcbcc65e1ecd -r 6e84de91f77bf2c190a8e2f7c2317138881c1abc yt/frontends/sph/fields.py
--- a/yt/frontends/sph/fields.py
+++ b/yt/frontends/sph/fields.py
@@ -69,6 +69,19 @@
              display_name = "\\mathrm{%s Count}" % ptype,
              projection_conversion = '1')
 
+    def particle_mass(field, data):
+        pos = data[ptype, coord_name]
+        d = data.deposit(pos, [data[ptype, mass_name]], method = "sum")
+        return d
+
+    registry.add_field(("deposit", "%s_mass" % ptype),
+             function = particle_mass,
+             validators = [ValidateSpatial()],
+             display_name = "\\mathrm{%s Mass}" % ptype,
+             units = r"\mathrm{g}",
+             projected_units = r"\mathrm{g}\/\mathrm{cm}",
+             projection_conversion = 'cm')
+
     def particle_density(field, data):
         pos = data[ptype, coord_name]
         d = data.deposit(pos, [data[ptype, mass_name]], method = "sum")
@@ -101,6 +114,28 @@
             particle_type = True,
             units = r"\mathrm{M}_\odot")
 
+    # For 'all', which is a special field, we skip adding a few types.
+    
+    if ptype == "all": return
+
+    # Now we have to set up the various velocity and coordinate things.  In the
+    # future, we'll actually invert this and use the 3-component items
+    # elsewhere, and stop using these.
+    
+    # Note that we pass in _ptype here so that it's defined inside the closure.
+    def _get_coord_funcs(axi, _ptype):
+        def _particle_velocity(field, data):
+            return data[_ptype, "Velocities"][:,axi]
+        def _particle_position(field, data):
+            return data[_ptype, "Coordinates"][:,axi]
+        return _particle_velocity, _particle_position
+    for axi, ax in enumerate("xyz"):
+        v, p = _get_coord_funcs(axi, ptype)
+        registry.add_field((ptype, "particle_velocity_%s" % ax),
+            particle_type = True, function = v)
+        registry.add_field((ptype, "particle_position_%s" % ax),
+            particle_type = True, function = p)
+    
 def _get_conv(cf):
     def _convert(data):
         return data.convert(cf)
@@ -156,6 +191,7 @@
     GadgetFieldInfo.add_field(("all", fname), function=func,
             particle_type = True)
 
+
 for ptype in _gadget_ptypes:
     KnownGadgetFields.add_field((ptype, "Masses"), function=NullFunc,
         particle_type = True,
@@ -167,5 +203,28 @@
         convert_function=_get_conv("velocity"),
         units = r"\mathrm{cm}/\mathrm{s}")
     _particle_functions(ptype, "Coordinates", "Mass", GadgetFieldInfo)
+    KnownGadgetFields.add_field((ptype, "Coordinates"), function=NullFunc,
+        particle_type = True)
 #_gadget_particle_fields("all")
 _particle_functions("all", "Coordinates", "Mass", GadgetFieldInfo)
+
+# Now we have to manually apply the splits for "all", since we don't want to
+# use the splits defined above.
+
+def _field_concat_slice(fname, axi):
+    def _AllFields(field, data):
+        v = []
+        for ptype in data.pf.particle_types:
+            if ptype == "all": continue
+            v.append(data[ptype, fname][:,axi])
+        rv = np.concatenate(v, axis=0)
+        return rv
+    return _AllFields
+
+for iname, oname in [("Coordinates", "particle_position_"),
+                     ("Velocities", "particle_velocity_")]:
+    for axi, ax in enumerate("xyz"):
+        func = _field_concat_slice(iname, axi)
+        GadgetFieldInfo.add_field(("all", oname + ax), function=func,
+                particle_type = True)
+


https://bitbucket.org/yt_analysis/yt-3.0/commits/d1648a800a1d/
Changeset:   d1648a800a1d
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-31 17:29:21
Summary:     Adding guessing for "all" to _get_field_info.  Fixing weighting-by-tuples in filename creation for PlotWindow.
Affected #:  2 files

diff -r 6e84de91f77bf2c190a8e2f7c2317138881c1abc -r d1648a800a1dcc457ee62c23b4f68e5555f03ef0 yt/data_objects/static_output.py
--- a/yt/data_objects/static_output.py
+++ b/yt/data_objects/static_output.py
@@ -252,8 +252,10 @@
     _last_freq = (None, None)
     _last_finfo = None
     def _get_field_info(self, ftype, fname):
+        guessing_type = False
         if ftype == "unknown" and self._last_freq[0] != None:
             ftype = self._last_freq[0]
+            guessing_type = True
         field = (ftype, fname)
         if field == self._last_freq:
             return self._last_finfo
@@ -267,6 +269,12 @@
             self._last_freq = field
             self._last_finfo = self.field_info[fname]
             return self._last_finfo
+        # We also should check "all" for particles, which can show up if you're
+        # mixing deposition/gas fields with particle fields.
+        if guessing_type and ("all", fname) in self.field_info:
+            self._last_freq = ("all", fname)
+            self._last_finfo = self.field_info["all", fname]
+            return self._last_finfo
         raise YTFieldNotFound((ftype, fname), self)
 
 def _reconstruct_pf(*args, **kwargs):

diff -r 6e84de91f77bf2c190a8e2f7c2317138881c1abc -r d1648a800a1dcc457ee62c23b4f68e5555f03ef0 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -1069,6 +1069,8 @@
                 # for cutting planes
                 n = "%s_%s_%s" % (name, type, k)
             if weight:
+                if isinstance(weight, tuple):
+                    weight = weight[1]
                 n += "_%s" % (weight)
             names.append(v.save(n,mpl_kwargs))
         return names


https://bitbucket.org/yt_analysis/yt-3.0/commits/2adf4b12e727/
Changeset:   2adf4b12e727
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-31 20:07:27
Summary:     Re-enabling MIP projections.
Affected #:  2 files

diff -r d1648a800a1dcc457ee62c23b4f68e5555f03ef0 -r 2adf4b12e72793f95e86b148374695c04d15fc83 yt/data_objects/construction_data_containers.py
--- a/yt/data_objects/construction_data_containers.py
+++ b/yt/data_objects/construction_data_containers.py
@@ -228,10 +228,8 @@
         self.proj_style = style
         if style == "mip":
             self.func = np.max
-            op = "max"
         elif style == "integrate":
             self.func = np.sum # for the future
-            op = "sum"
         else:
             raise NotImplementedError(style)
         self.weight_field = weight_field
@@ -299,7 +297,7 @@
         # TODO: Add the combine operation
         ox = self.pf.domain_left_edge[x_dict[self.axis]]
         oy = self.pf.domain_left_edge[y_dict[self.axis]]
-        px, py, pdx, pdy, nvals, nwvals = tree.get_all(False)
+        px, py, pdx, pdy, nvals, nwvals = tree.get_all(False, merge_style)
         nvals = self.comm.mpi_allreduce(nvals, op=op)
         nwvals = self.comm.mpi_allreduce(nwvals, op=op)
         np.multiply(px, self.pf.domain_width[x_dict[self.axis]], px)

diff -r d1648a800a1dcc457ee62c23b4f68e5555f03ef0 -r 2adf4b12e72793f95e86b148374695c04d15fc83 yt/utilities/lib/QuadTree.pyx
--- a/yt/utilities/lib/QuadTree.pyx
+++ b/yt/utilities/lib/QuadTree.pyx
@@ -342,10 +342,11 @@
 
     @cython.boundscheck(False)
     @cython.wraparound(False)
-    def get_all(self, int count_only = 0):
+    def get_all(self, int count_only = 0, int style = 1):
         cdef int i, j, vi
         cdef int total = 0
         vals = []
+        self.merged = style
         for i in range(self.top_grid_dims[0]):
             for j in range(self.top_grid_dims[1]):
                 total += self.count(self.root_nodes[i][j])


https://bitbucket.org/yt_analysis/yt-3.0/commits/27d0013f48e8/
Changeset:   27d0013f48e8
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-31 20:28:56
Summary:     Fixing "unitary" for SPH.
Affected #:  1 file

diff -r 2adf4b12e72793f95e86b148374695c04d15fc83 -r 27d0013f48e8e98983603ca3351c575289cfbbad yt/frontends/sph/data_structures.py
--- a/yt/frontends/sph/data_structures.py
+++ b/yt/frontends/sph/data_structures.py
@@ -248,8 +248,8 @@
         self.time_units = {}
         self.conversion_factors = {}
         self.units['1'] = 1.0
-        self.units['unitary'] = (self.domain_right_edge -
-                                 self.domain_left_edge).max()
+        DW = self.domain_right_edge - self.domain_left_edge
+        self.units["unitary"] = 1.0 / DW.max()
         # Check 
         base = None
         mpch = {}


https://bitbucket.org/yt_analysis/yt-3.0/commits/c4405c868b90/
Changeset:   c4405c868b90
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-31 20:54:09
Summary:     Re-enable .shape on data objects to enable Ones working on patch datasets being
projected.
Affected #:  1 file

diff -r 27d0013f48e8e98983603ca3351c575289cfbbad -r c4405c868b90c264de30896a8eabeda8613a94d5 yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -539,11 +539,11 @@
         old_size, self.size = self.size, chunk.data_size
         old_chunk, self._current_chunk = self._current_chunk, chunk
         old_locked, self._locked = self._locked, False
-        #self.shape = (self.size,)
+        self.shape = (self.size,)
         yield
         self.field_data = old_field_data
         self.size = old_size
-        #self.shape = (old_size,)
+        self.shape = (old_size,)
         self._current_chunk = old_chunk
         self._locked = old_locked
 


https://bitbucket.org/yt_analysis/yt-3.0/commits/af89e30c12b5/
Changeset:   af89e30c12b5
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-31 20:54:52
Summary:     Allow 0-particle octs in different domains to be flagged as not needing
refinement.  This ensures all oct children eventually survive, and that
volume is correctly set globally for the particles on the mesh.
Affected #:  1 file

diff -r c4405c868b90c264de30896a8eabeda8613a94d5 -r af89e30c12b57346e4cbef691ff60ef1530ec084 yt/geometry/oct_container.pyx
--- a/yt/geometry/oct_container.pyx
+++ b/yt/geometry/oct_container.pyx
@@ -1138,6 +1138,8 @@
         #True if not in domain
         if cur.children[0][0][0] != NULL:
             return 0
+        elif cur.sd.np == 0:
+            return 0
         elif cur.sd.np >= self.n_ref:
             return 1
         elif cur.domain >= 0 and cur.domain != domain_id:
@@ -1154,6 +1156,7 @@
             for j in range(2):
                 for k in range(2):
                     noct = self.allocate_oct()
+                    noct.domain = o.domain
                     noct.level = o.level + 1
                     noct.pos[0] = (o.pos[0] << 1) + i
                     noct.pos[1] = (o.pos[1] << 1) + j


https://bitbucket.org/yt_analysis/yt-3.0/commits/e77960d08012/
Changeset:   e77960d08012
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-31 21:43:08
Summary:     Fixing periodicity checks for halo center of mass.  (mirrored in 75a6021)
Affected #:  1 file

diff -r af89e30c12b57346e4cbef691ff60ef1530ec084 -r e77960d08012bc074717c8d9309697897ad33960 yt/analysis_modules/halo_finding/halo_objects.py
--- a/yt/analysis_modules/halo_finding/halo_objects.py
+++ b/yt/analysis_modules/halo_finding/halo_objects.py
@@ -144,10 +144,10 @@
             return self.CoM
         pm = self["ParticleMassMsun"]
         c = {}
-        c[0] = self["particle_position_x"]
-        c[1] = self["particle_position_y"]
-        c[2] = self["particle_position_z"]
-        c_vec = np.zeros(3)
+        # We shift into a box where the origin is the left edge
+        c[0] = self["particle_position_x"] - self.pf.domain_left_edge[0]
+        c[1] = self["particle_position_y"] - self.pf.domain_left_edge[1]
+        c[2] = self["particle_position_z"] - self.pf.domain_left_edge[2]
         com = []
         for i in range(3):
             # A halo is likely periodic around a boundary if the distance 
@@ -160,13 +160,12 @@
                 com.append(c[i])
                 continue
             # Now we want to flip around only those close to the left boundary.
-            d_left = c[i] - self.pf.domain_left_edge[i]
-            sel = (d_left <= (self.pf.domain_width[i]/2))
+            sel = (c[i] <= (self.pf.domain_width[i]/2))
             c[i][sel] += self.pf.domain_width[i]
             com.append(c[i])
         com = np.array(com)
         c = (com * pm).sum(axis=1) / pm.sum()
-        return c%self.pf.domain_width
+        return c % self.pf.domain_width + self.pf.domain_left_edge
 
     def maximum_density(self):
         r"""Return the HOP-identified maximum density. Not applicable to


https://bitbucket.org/yt_analysis/yt-3.0/commits/c62e4f9ae6f8/
Changeset:   c62e4f9ae6f8
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-31 21:43:28
Summary:     Adding fields for Tipsy to match those in Gadget.  HOP now runs.
Affected #:  1 file

diff -r e77960d08012bc074717c8d9309697897ad33960 -r c62e4f9ae6f8e4397f0662439d0f0889936b5c42 yt/frontends/sph/fields.py
--- a/yt/frontends/sph/fields.py
+++ b/yt/frontends/sph/fields.py
@@ -135,12 +135,37 @@
             particle_type = True, function = v)
         registry.add_field((ptype, "particle_position_%s" % ax),
             particle_type = True, function = p)
-    
+
+# Here are helper functions for things like vector fields and so on.
+
 def _get_conv(cf):
     def _convert(data):
         return data.convert(cf)
     return _convert
 
+def _field_concat(fname):
+    def _AllFields(field, data):
+        v = []
+        for ptype in data.pf.particle_types:
+            if ptype == "all": continue
+            v.append(data[ptype, fname].copy())
+        rv = np.concatenate(v, axis=0)
+        return rv
+    return _AllFields
+
+def _field_concat_slice(fname, axi):
+    def _AllFields(field, data):
+        v = []
+        for ptype in data.pf.particle_types:
+            if ptype == "all": continue
+            v.append(data[ptype, fname][:,axi])
+        rv = np.concatenate(v, axis=0)
+        return rv
+    return _AllFields
+
+# TIPSY
+# =====
+
 for ptype in ["Gas", "DarkMatter", "Stars"]:
     KnownTipsyFields.add_field((ptype, "Mass"), function=NullFunc,
         particle_type = True,
@@ -153,6 +178,20 @@
     # Note that we have to do this last so that TranslationFunc operates
     # correctly.
     _particle_functions(ptype, "Coordinates", "Mass", TipsyFieldInfo)
+_particle_functions("all", "Coordinates", "Mass", TipsyFieldInfo)
+
+for fname in ["Coordinates", "Velocities", "ParticleIDs", "Mass",
+              "Epsilon", "Phi"]:
+    func = _field_concat(fname)
+    TipsyFieldInfo.add_field(("all", fname), function=func,
+            particle_type = True)
+
+for iname, oname in [("Coordinates", "particle_position_"),
+                     ("Velocities", "particle_velocity_")]:
+    for axi, ax in enumerate("xyz"):
+        func = _field_concat_slice(iname, axi)
+        TipsyFieldInfo.add_field(("all", oname + ax), function=func,
+                particle_type = True)
 
 # GADGET
 # ======
@@ -161,6 +200,8 @@
 
 _gadget_ptypes = ("Gas", "Halo", "Disk", "Bulge", "Stars", "Bndry")
 
+# This has to be done manually for Gadget, because some of the particles will
+# have uniform mass
 def _gadget_particle_fields(ptype):
     def _Mass(field, data):
         pind = _gadget_ptypes.index(ptype)
@@ -174,16 +215,6 @@
     GadgetFieldInfo.add_field((ptype, "Mass"), function=_Mass,
                               particle_type = True)
 
-def _field_concat(fname):
-    def _AllFields(field, data):
-        v = []
-        for ptype in data.pf.particle_types:
-            if ptype == "all": continue
-            v.append(data[ptype, fname].copy())
-        rv = np.concatenate(v, axis=0)
-        return rv
-    return _AllFields
-
 for fname in ["Coordinates", "Velocities", "ParticleIDs",
               # Note: Mass, not Masses
               "Mass"]:
@@ -191,7 +222,6 @@
     GadgetFieldInfo.add_field(("all", fname), function=func,
             particle_type = True)
 
-
 for ptype in _gadget_ptypes:
     KnownGadgetFields.add_field((ptype, "Masses"), function=NullFunc,
         particle_type = True,
@@ -205,22 +235,11 @@
     _particle_functions(ptype, "Coordinates", "Mass", GadgetFieldInfo)
     KnownGadgetFields.add_field((ptype, "Coordinates"), function=NullFunc,
         particle_type = True)
-#_gadget_particle_fields("all")
 _particle_functions("all", "Coordinates", "Mass", GadgetFieldInfo)
 
 # Now we have to manually apply the splits for "all", since we don't want to
 # use the splits defined above.
 
-def _field_concat_slice(fname, axi):
-    def _AllFields(field, data):
-        v = []
-        for ptype in data.pf.particle_types:
-            if ptype == "all": continue
-            v.append(data[ptype, fname][:,axi])
-        rv = np.concatenate(v, axis=0)
-        return rv
-    return _AllFields
-
 for iname, oname in [("Coordinates", "particle_position_"),
                      ("Velocities", "particle_velocity_")]:
     for axi, ax in enumerate("xyz"):


https://bitbucket.org/yt_analysis/yt-3.0/commits/0b21630b2c16/
Changeset:   0b21630b2c16
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-05-31 22:31:16
Summary:     This fixes a test failure.  Note that this once again touches .shape, which
*will* need to go away, but also reinforces that shape will need to be removed
carefully.
Affected #:  1 file

diff -r c62e4f9ae6f8e4397f0662439d0f0889936b5c42 -r 0b21630b2c160f55d856f2d43a37881fa020897b yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -539,11 +539,13 @@
         old_size, self.size = self.size, chunk.data_size
         old_chunk, self._current_chunk = self._current_chunk, chunk
         old_locked, self._locked = self._locked, False
-        self.shape = (self.size,)
+        if not self._spatial:
+            self.shape = (self.size,)
         yield
         self.field_data = old_field_data
         self.size = old_size
-        self.shape = (old_size,)
+        if not self._spatial:
+            self.shape = (old_size,)
         self._current_chunk = old_chunk
         self._locked = old_locked
 


https://bitbucket.org/yt_analysis/yt-3.0/commits/75692f91b4b8/
Changeset:   75692f91b4b8
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-06-02 22:00:48
Summary:     Changing hand-coded Msun to use physical_constants.py.
Affected #:  1 file

diff -r 0b21630b2c160f55d856f2d43a37881fa020897b -r 75692f91b4b85f5dc13cf9ba61b9deb94ed8cc14 yt/frontends/sph/data_structures.py
--- a/yt/frontends/sph/data_structures.py
+++ b/yt/frontends/sph/data_structures.py
@@ -47,7 +47,8 @@
 from yt.utilities.physical_constants import \
     G, \
     gravitational_constant_cgs, \
-    km_per_pc
+    km_per_pc, \
+    mass_sun_cgs
 from yt.utilities.cosmology import Cosmology
 from .fields import \
     OWLSFieldInfo, \
@@ -361,7 +362,8 @@
         unit_base = self._unit_base or {}
         velocity_unit = unit_base.get("velocity", 1e5)
         velocity_unit = unit_base.get("UnitVelocity_in_cm_per_s", velocity_unit)
-        mass_unit = unit_base.get("g", 1.989e43 / self.hubble_constant)
+        msun10 = mass_sun_cgs * 1e10
+        mass_unit = unit_base.get("g", msun10 / self.hubble_constant)
         mass_unit = unit_base.get("UnitMass_in_g", mass_unit)
         time_unit = length_unit / velocity_unit
         self.conversion_factors["velocity"] = velocity_unit


https://bitbucket.org/yt_analysis/yt-3.0/commits/b4ce5d2b3d4d/
Changeset:   b4ce5d2b3d4d
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-06-02 22:07:28
Summary:     Reverting a change to cosmology.py.
Affected #:  1 file

diff -r 75692f91b4b85f5dc13cf9ba61b9deb94ed8cc14 -r b4ce5d2b3d4d040a1d5d9dd292b1288c54887c95 yt/utilities/cosmology.py
--- a/yt/utilities/cosmology.py
+++ b/yt/utilities/cosmology.py
@@ -109,8 +109,6 @@
         return (self.AngularDiameterDistance(z_i,z_f) / 648. * np.pi)
 
     def CriticalDensity(self,z):
-        return ( (3.0 * (self.HubbleConstantNow / kmPerMpc)**2.0)
-               / (8.0 * np.pi * G) )
         return (3.0 / 8.0 / np.pi * sqr(self.HubbleConstantNow / kmPerMpc) / G *
                 (self.OmegaLambdaNow + ((1 + z)**3.0) * self.OmegaMatterNow))
 


https://bitbucket.org/yt_analysis/yt-3.0/commits/8b1db060b7dc/
Changeset:   8b1db060b7dc
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-06-02 23:07:07
Summary:     I think this addresses the suggestions for how to figure out units.

It's not entirely clear to me that this does the right thing, but it *does*
change it so that the "UnitLength_in_cm" is comoving.  But note that this may
lead to confusion if someone were to assume that passing unit_base['cm'] sets
the comoving centimeters unit.
Affected #:  1 file

diff -r b4ce5d2b3d4d040a1d5d9dd292b1288c54887c95 -r 8b1db060b7dc5a6538bc4f8c17776d6a15f2735d yt/frontends/sph/data_structures.py
--- a/yt/frontends/sph/data_structures.py
+++ b/yt/frontends/sph/data_structures.py
@@ -303,7 +303,9 @@
         # Set up the template for domain files
         self.storage_filename = None
         if unit_base is not None and "UnitLength_in_cm" in unit_base:
-            unit_base['cm'] = unit_base["UnitLength_in_cm"]
+            # We assume this is comoving, because in the absence of comoving
+            # integration the redshift will be zero.
+            unit_base['cmcm'] = unit_base["UnitLength_in_cm"]
         self._unit_base = unit_base
         super(GadgetStaticOutput, self).__init__(filename, data_style)
 
@@ -342,6 +344,17 @@
         self.omega_lambda = hvals["OmegaLambda"]
         self.omega_matter = hvals["Omega0"]
         self.hubble_constant = hvals["HubbleParam"]
+        # According to the Gadget manual, OmegaLambda will be zero for
+        # non-cosmological datasets.  However, it may be the case that
+        # individuals are running cosmological simulations *without* Lambda, in
+        # which case we may be doing something incorrect here.
+        # It may be possible to deduce whether ComovingIntegration is on
+        # somehow, but opinions on this vary.
+        if self.omega_lambda == 0.0:
+            mylog.info("Omega Lambda is 0.0, so we are turning off Cosmology.")
+            self.hubble_constant = 1.0 # So that scaling comes out correct
+            self.cosmological_simulation = 0
+            self.current_redshift = 0.0
         self.parameters = hvals
 
         prefix = self.parameter_filename.split(".", 1)[0]
@@ -362,8 +375,9 @@
         unit_base = self._unit_base or {}
         velocity_unit = unit_base.get("velocity", 1e5)
         velocity_unit = unit_base.get("UnitVelocity_in_cm_per_s", velocity_unit)
-        msun10 = mass_sun_cgs * 1e10
-        mass_unit = unit_base.get("g", msun10 / self.hubble_constant)
+        # We set hubble_constant = 1.0 for non-cosmology
+        msun10 = mass_sun_cgs * 1e10 / self.hubble_constant
+        mass_unit = unit_base.get("g", msun10)
         mass_unit = unit_base.get("UnitMass_in_g", mass_unit)
         time_unit = length_unit / velocity_unit
         self.conversion_factors["velocity"] = velocity_unit


https://bitbucket.org/yt_analysis/yt-3.0/commits/ada7c2c608f1/
Changeset:   ada7c2c608f1
Branch:      yt-3.0
User:        MatthewTurk
Date:        2013-06-02 23:35:02
Summary:     "Time" is different for ComovingIntegration.  So we attempt to handle it
differently.

Note also that this disables all unit conversions for time, as typically these
are not used very often and furthermore I am not 100% sure the correct way to
set them up.  Once I have some simulations with star particles, and
FormationTime fields for them, we can re-investigate this, but it seems to me
that if Time is set the same way as FormationTime, this will be a non-trivial
problem to address as it will not be a linear scaling for conversions.
Affected #:  1 file

diff -r 8b1db060b7dc5a6538bc4f8c17776d6a15f2735d -r ada7c2c608f1bb724bfa274539a0321b76df503c yt/frontends/sph/data_structures.py
--- a/yt/frontends/sph/data_structures.py
+++ b/yt/frontends/sph/data_structures.py
@@ -330,8 +330,6 @@
             int(os.stat(self.parameter_filename)[stat.ST_CTIME])
         # Set standard values
 
-        # This may not be correct.
-        self.current_time = hvals["Time"] * sec_conversion["Gyr"]
 
         self.domain_left_edge = np.zeros(3, "float64")
         self.domain_right_edge = np.ones(3, "float64") * hvals["BoxSize"]
@@ -355,6 +353,18 @@
             self.hubble_constant = 1.0 # So that scaling comes out correct
             self.cosmological_simulation = 0
             self.current_redshift = 0.0
+            # This may not be correct.
+            self.current_time = hvals["Time"] * sec_conversion["Gyr"]
+        else:
+            # Now we calculate our time based on the cosmology, because in
+            # ComovingIntegration hvals["Time"] will in fact be the expansion
+            # factor, not the actual integration time, so we re-calculate
+            # global time from our Cosmology.
+            cosmo = Cosmology(self.hubble_constant * 100.0,
+                        self.omega_matter, self.omega_lambda)
+            self.current_time = cosmo.UniverseAge(self.current_redshift)
+            mylog.info("Calculating time from %0.3e to be %0.3e seconds",
+                       hvals["Time"], self.current_time)
         self.parameters = hvals
 
         prefix = self.parameter_filename.split(".", 1)[0]
@@ -379,12 +389,15 @@
         msun10 = mass_sun_cgs * 1e10 / self.hubble_constant
         mass_unit = unit_base.get("g", msun10)
         mass_unit = unit_base.get("UnitMass_in_g", mass_unit)
-        time_unit = length_unit / velocity_unit
         self.conversion_factors["velocity"] = velocity_unit
         self.conversion_factors["mass"] = mass_unit
         self.conversion_factors["density"] = mass_unit / length_unit**3
-        for u in sec_conversion:
-            self.time_units[u] = time_unit * sec_conversion[u]
+        # Currently, setting time_units is disabled.  The current_time is
+        # accurately set, but until a time that we can confirm how
+        # FormationTime for stars is set I am disabling these.
+        #time_unit = length_unit / velocity_unit
+        #for u in sec_conversion:
+        #    self.time_units[u] = time_unit / sec_conversion[u]
 
     @classmethod
     def _is_valid(self, *args, **kwargs):

Repository URL: https://bitbucket.org/yt_analysis/yt-3.0/

--

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