def test_particle_profiles(): for nproc in [1, 2, 4, 8]: ds = fake_random_ds(32, nprocs=nproc, particles = 32**3) dd = ds.all_data() p1d = Profile1D(dd, "particle_position_x", 128, 0.0, 1.0, False, weight_field = None) p1d.add_fields(["particle_ones"]) assert_equal(p1d["particle_ones"].sum(), 32**3) p1d = create_profile(dd, ["particle_position_x"], ["particle_ones"], weight_field=None, n_bins=128, extrema=extrema_s, logs=logs_s) assert_equal(p1d["particle_ones"].sum(), 32**3) p1d = create_profile(dd, [("all", "particle_position_x")], [("all", "particle_ones")], weight_field=None, n_bins=128, extrema=extrema_t, logs=logs_t) assert_equal(p1d["particle_ones"].sum(), 32**3) p2d = Profile2D(dd, "particle_position_x", 128, 0.0, 1.0, False, "particle_position_y", 128, 0.0, 1.0, False, weight_field = None) p2d.add_fields(["particle_ones"]) assert_equal(p2d["particle_ones"].sum(), 32**3) p3d = Profile3D(dd, "particle_position_x", 128, 0.0, 1.0, False, "particle_position_y", 128, 0.0, 1.0, False, "particle_position_z", 128, 0.0, 1.0, False, weight_field = None) p3d.add_fields(["particle_ones"]) assert_equal(p3d["particle_ones"].sum(), 32**3)
def test_profiles(): ds = fake_random_ds(64, nprocs=8, fields=_fields, units=_units) nv = ds.domain_dimensions.prod() dd = ds.all_data() (rmi, rma), (tmi, tma), (dmi, dma) = dd.quantities["Extrema"]( ["density", "temperature", "dinosaurs"]) rt, tt, dt = dd.quantities["TotalQuantity"]( ["density", "temperature", "dinosaurs"]) e1, e2 = 0.9, 1.1 for nb in [8, 16, 32, 64]: for input_units in ['mks', 'cgs']: for ex in [rmi, rma, tmi, tma, dmi, dma]: getattr(ex, 'convert_to_%s' % input_units)() # We log all the fields or don't log 'em all. No need to do them # individually. for lf in [True, False]: direct_profile = Profile1D(dd, "density", nb, rmi * e1, rma * e2, lf, weight_field=None) direct_profile.add_fields(["ones", "temperature"]) indirect_profile_s = create_profile( dd, "density", ["ones", "temperature"], n_bins=nb, extrema={'density': (rmi * e1, rma * e2)}, logs={'density': lf}, weight_field=None) indirect_profile_t = create_profile( dd, ("gas", "density"), [("index", "ones"), ("gas", "temperature")], n_bins=nb, extrema={'density': (rmi * e1, rma * e2)}, logs={'density': lf}, weight_field=None) for p1d in [ direct_profile, indirect_profile_s, indirect_profile_t ]: assert_equal(p1d["index", "ones"].sum(), nv) assert_rel_equal(tt, p1d["gas", "temperature"].sum(), 7) p2d = Profile2D(dd, "density", nb, rmi * e1, rma * e2, lf, "temperature", nb, tmi * e1, tma * e2, lf, weight_field=None) p2d.add_fields(["ones", "temperature"]) assert_equal(p2d["ones"].sum(), nv) assert_rel_equal(tt, p2d["temperature"].sum(), 7) p3d = Profile3D(dd, "density", nb, rmi * e1, rma * e2, lf, "temperature", nb, tmi * e1, tma * e2, lf, "dinosaurs", nb, dmi * e1, dma * e2, lf, weight_field=None) p3d.add_fields(["ones", "temperature"]) assert_equal(p3d["ones"].sum(), nv) assert_rel_equal(tt, p3d["temperature"].sum(), 7) p1d = Profile1D(dd, "x", nb, 0.0, 1.0, False, weight_field=None) p1d.add_fields("ones") av = nv / nb assert_equal(p1d["ones"], np.ones(nb) * av) # We re-bin ones with a weight now p1d = Profile1D(dd, "x", nb, 0.0, 1.0, False, weight_field="temperature") p1d.add_fields(["ones"]) assert_equal(p1d["ones"], np.ones(nb)) # Verify we can access "ones" after adding a new field # See issue 988 p1d.add_fields(["density"]) assert_equal(p1d["ones"], np.ones(nb)) p2d = Profile2D(dd, "x", nb, 0.0, 1.0, False, "y", nb, 0.0, 1.0, False, weight_field=None) p2d.add_fields("ones") av = nv / nb**2 assert_equal(p2d["ones"], np.ones((nb, nb)) * av) # We re-bin ones with a weight now p2d = Profile2D(dd, "x", nb, 0.0, 1.0, False, "y", nb, 0.0, 1.0, False, weight_field="temperature") p2d.add_fields(["ones"]) assert_equal(p2d["ones"], np.ones((nb, nb))) p3d = Profile3D(dd, "x", nb, 0.0, 1.0, False, "y", nb, 0.0, 1.0, False, "z", nb, 0.0, 1.0, False, weight_field=None) p3d.add_fields("ones") av = nv / nb**3 assert_equal(p3d["ones"], np.ones((nb, nb, nb)) * av) # We re-bin ones with a weight now p3d = Profile3D(dd, "x", nb, 0.0, 1.0, False, "y", nb, 0.0, 1.0, False, "z", nb, 0.0, 1.0, False, weight_field="temperature") p3d.add_fields(["ones"]) assert_equal(p3d["ones"], np.ones((nb, nb, nb))) p2d = create_profile(dd, ('gas', 'density'), ('gas', 'temperature'), weight_field=('gas', 'cell_mass'), extrema={'density': (None, rma * e2)}) assert_equal(p2d.x_bins[0], rmi - np.spacing(rmi)) assert_equal(p2d.x_bins[-1], rma * e2) p2d = create_profile(dd, ('gas', 'density'), ('gas', 'temperature'), weight_field=('gas', 'cell_mass'), extrema={'density': (rmi * e2, None)}) assert_equal(p2d.x_bins[0], rmi * e2) assert_equal(p2d.x_bins[-1], rma + np.spacing(rma))
def test_profiles(): ds = fake_random_ds(64, nprocs=8, fields=_fields, units=_units) nv = ds.domain_dimensions.prod() dd = ds.all_data() (rmi, rma), (tmi, tma), (dmi, dma) = dd.quantities["Extrema"]( ["density", "temperature", "dinosaurs"]) rt, tt, dt = dd.quantities["TotalQuantity"]( ["density", "temperature", "dinosaurs"]) # First we look at the e1, e2 = 0.9, 1.1 for nb in [8, 16, 32, 64]: # We log all the fields or don't log 'em all. No need to do them # individually. for lf in [True, False]: direct_profile = Profile1D(dd, "density", nb, rmi * e1, rma * e2, lf, weight_field=None) direct_profile.add_fields(["ones", "temperature"]) indirect_profile_s = create_profile( dd, "density", ["ones", "temperature"], n_bins=nb, extrema={'density': (rmi * e1, rma * e2)}, logs={'density': lf}, weight_field=None) indirect_profile_t = create_profile( dd, ("gas", "density"), [("index", "ones"), ("gas", "temperature")], n_bins=nb, extrema={'density': (rmi * e1, rma * e2)}, logs={'density': lf}, weight_field=None) for p1d in [ direct_profile, indirect_profile_s, indirect_profile_t ]: yield assert_equal, p1d["index", "ones"].sum(), nv yield assert_rel_equal, tt, p1d["gas", "temperature"].sum(), 7 p2d = Profile2D(dd, "density", nb, rmi * e1, rma * e2, lf, "temperature", nb, tmi * e1, tma * e2, lf, weight_field=None) p2d.add_fields(["ones", "temperature"]) yield assert_equal, p2d["ones"].sum(), nv yield assert_rel_equal, tt, p2d["temperature"].sum(), 7 p3d = Profile3D(dd, "density", nb, rmi * e1, rma * e2, lf, "temperature", nb, tmi * e1, tma * e2, lf, "dinosaurs", nb, dmi * e1, dma * e2, lf, weight_field=None) p3d.add_fields(["ones", "temperature"]) yield assert_equal, p3d["ones"].sum(), nv yield assert_rel_equal, tt, p3d["temperature"].sum(), 7 p1d = Profile1D(dd, "x", nb, 0.0, 1.0, False, weight_field=None) p1d.add_fields("ones") av = nv / nb yield assert_equal, p1d["ones"], np.ones(nb) * av # We re-bin ones with a weight now p1d = Profile1D(dd, "x", nb, 0.0, 1.0, False, weight_field="temperature") p1d.add_fields(["ones"]) yield assert_equal, p1d["ones"], np.ones(nb) # Verify we can access "ones" after adding a new field # See issue 988 p1d.add_fields(["density"]) yield assert_equal, p1d["ones"], np.ones(nb) p2d = Profile2D(dd, "x", nb, 0.0, 1.0, False, "y", nb, 0.0, 1.0, False, weight_field=None) p2d.add_fields("ones") av = nv / nb**2 yield assert_equal, p2d["ones"], np.ones((nb, nb)) * av # We re-bin ones with a weight now p2d = Profile2D(dd, "x", nb, 0.0, 1.0, False, "y", nb, 0.0, 1.0, False, weight_field="temperature") p2d.add_fields(["ones"]) yield assert_equal, p2d["ones"], np.ones((nb, nb)) p3d = Profile3D(dd, "x", nb, 0.0, 1.0, False, "y", nb, 0.0, 1.0, False, "z", nb, 0.0, 1.0, False, weight_field=None) p3d.add_fields("ones") av = nv / nb**3 yield assert_equal, p3d["ones"], np.ones((nb, nb, nb)) * av # We re-bin ones with a weight now p3d = Profile3D(dd, "x", nb, 0.0, 1.0, False, "y", nb, 0.0, 1.0, False, "z", nb, 0.0, 1.0, False, weight_field="temperature") p3d.add_fields(["ones"]) yield assert_equal, p3d["ones"], np.ones((nb, nb, nb))
def profile(halo, x_field, y_fields, x_bins=32, x_range=None, x_log=True, weight_field="cell_mass", accumulation=False, storage="profiles", output_dir="."): r""" Create 1d profiles. Store profile data in a dictionary associated with the halo object. Parameters ---------- halo : Halo object The Halo object to be provided by the HaloCatalog. x_field : string The binning field for the profile. y_fields : string or list of strings The fields to be propython filed. x_bins : int The number of bins in the profile. Default: 32 x_range : (float, float) The range of the x_field. If None, the extrema are used. Default: None x_log : bool Flag for logarithmmic binning. Default: True weight_field : string Weight field for profiling. Default : "cell_mass" accumulation : bool If True, profile data is a cumulative sum. Default : False storage : string Name of the dictionary to store profiles. Default: "profiles" output_dir : string Name of directory where profile data will be written. The full path will be the output_dir of the halo catalog concatenated with this directory. Default : "." """ mylog.info("Calculating 1D profile for halo %d." % halo.quantities["particle_identifier"]) dds = halo.halo_catalog.data_ds if dds is None: raise RuntimeError("Profile callback requires a data ds.") if not hasattr(halo, "data_object"): raise RuntimeError("Profile callback requires a data container.") if halo.data_object is None: mylog.info("Skipping halo %d since data_object is None." % halo.quantities["particle_identifier"]) return if output_dir is None: output_dir = storage output_dir = os.path.join(halo.halo_catalog.output_dir, output_dir) if x_range is None: x_range = list( halo.data_object.quantities.extrema(x_field, non_zero=True)) my_profile = Profile1D(halo.data_object, x_field, x_bins, x_range[0], x_range[1], x_log, weight_field=weight_field) my_profile.add_fields(ensure_list(y_fields)) # temporary fix since profiles do not have units at the moment for field in my_profile.field_data: my_profile.field_data[field] = dds.arr(my_profile[field], dds.field_info[field].units) # accumulate, if necessary if accumulation: used = my_profile.used for field in my_profile.field_data: if weight_field is None: my_profile.field_data[field][used] = \ np.cumsum(my_profile.field_data[field][used]) else: my_weight = my_profile.weight my_profile.field_data[field][used] = \ np.cumsum(my_profile.field_data[field][used] * my_weight[used]) / \ np.cumsum(my_weight[used]) # create storage dictionary prof_store = dict([(field, my_profile[field]) \ for field in my_profile.field_data]) prof_store[my_profile.x_field] = my_profile.x if hasattr(halo, storage): halo_store = getattr(halo, storage) if "used" in halo_store: halo_store["used"] &= my_profile.used else: halo_store = {"used": my_profile.used} setattr(halo, storage, halo_store) halo_store.update(prof_store)