def __init__(self, ds, normal, fields, center='c', width=(1.0, 'unitary'),
              weight_field=None, image_res=512, depth_res=256,
              north_vector=None, depth=(1.0,"unitary"), no_ghost=False, method='integrate'):
     fields = ensure_list(fields)
     center, dcenter = ds.coordinates.sanitize_center(center, 4)
     buf = {}
     width = ds.coordinates.sanitize_width(normal, width, depth)
     wd = tuple(el.in_units('code_length').v for el in width)
     if not iterable(image_res):
         image_res = (image_res, image_res)
     res = (image_res[0], image_res[1], depth_res)
     for field in fields:
         buf[field] = off_axis_projection(ds, center, normal, wd, res, field,
                                          no_ghost=no_ghost, north_vector=north_vector,
                                          method=method, weight=weight_field).swapaxes(0, 1)
     center = ds.arr([0.0] * 2, 'code_length')
     w, not_an_frb = construct_image(ds, normal, buf, center, width=width, image_res=image_res)
     super(FITSOffAxisProjection, self).__init__(buf, fields=fields, wcs=w)
Example #2
0
 def __init__(self,
              ds,
              normal,
              fields,
              center='c',
              width=(1.0, 'unitary'),
              weight_field=None,
              image_res=512,
              depth_res=256,
              north_vector=None,
              depth=(1.0, "unitary"),
              no_ghost=False,
              method='integrate'):
     fields = ensure_list(fields)
     center, dcenter = ds.coordinates.sanitize_center(center, 4)
     buf = {}
     width = ds.coordinates.sanitize_width(normal, width, depth)
     wd = tuple(el.in_units('code_length').v for el in width)
     if not iterable(image_res):
         image_res = (image_res, image_res)
     res = (image_res[0], image_res[1], depth_res)
     for field in fields:
         buf[field] = off_axis_projection(ds,
                                          center,
                                          normal,
                                          wd,
                                          res,
                                          field,
                                          no_ghost=no_ghost,
                                          north_vector=north_vector,
                                          method=method,
                                          weight=weight_field).swapaxes(
                                              0, 1)
     center = ds.arr([0.0] * 2, 'code_length')
     w, not_an_frb = construct_image(ds,
                                     normal,
                                     buf,
                                     center,
                                     width=width,
                                     image_res=image_res)
     super(FITSOffAxisProjection, self).__init__(buf, fields=fields, wcs=w)
Example #3
0
    def __init__(self,
                 ds,
                 normal,
                 field,
                 velocity_bounds,
                 center="c",
                 width=(1.0, "unitary"),
                 dims=100,
                 thermal_broad=False,
                 atomic_weight=56.,
                 depth=(1.0, "unitary"),
                 depth_res=256,
                 method="integrate",
                 weight_field=None,
                 no_shifting=False,
                 north_vector=None,
                 no_ghost=True):
        r""" Initialize a PPVCube object.

        Parameters
        ----------
        ds : dataset
            The dataset.
        normal : array_like or string
            The normal vector along with to make the projections. If an array, it
            will be normalized. If a string, it will be assumed to be along one of the
            principal axes of the domain ("x", "y", or "z").
        field : string
            The field to project.
        velocity_bounds : tuple
            A 4-tuple of (vmin, vmax, nbins, units) for the velocity bounds to
            integrate over. 
        center : A sequence of floats, a string, or a tuple.
            The coordinate of the center of the image. If set to 'c', 'center' or
            left blank, the plot is centered on the middle of the domain. If set to
            'max' or 'm', the center will be located at the maximum of the
            ('gas', 'density') field. Centering on the max or min of a specific
            field is supported by providing a tuple such as ("min","temperature") or
            ("max","dark_matter_density"). Units can be specified by passing in *center*
            as a tuple containing a coordinate and string unit name or by passing
            in a YTArray. If a list or unitless array is supplied, code units are
            assumed.
        width : float, tuple, or YTQuantity.
            The width of the projection. A float will assume the width is in code units.
            A (value, unit) tuple or YTQuantity allows for the units of the width to be
            specified. Implies width = height, e.g. the aspect ratio of the PPVCube's 
            spatial dimensions is 1.
        dims : integer, optional
            The spatial resolution of the cube. Implies nx = ny, e.g. the 
            aspect ratio of the PPVCube's spatial dimensions is 1.
        thermal_broad : boolean, optional
            Whether or not to broaden the line using the gas temperature. Default: False.
        atomic_weight : float, optional
            Set this value to the atomic weight of the particle that is emitting the line
            if *thermal_broad* is True. Defaults to 56 (Fe).
        depth : A tuple or a float, optional
            A tuple containing the depth to project through and the string
            key of the unit: (width, 'unit').  If set to a float, code units
            are assumed. Only for off-axis cubes.
        depth_res : integer, optional
            The resolution of integration along the line of sight for off-axis cubes. Default: 256
        method : string, optional
            Set the projection method to be used.
            "integrate" : line of sight integration over the line element.
            "sum" : straight summation over the line of sight.
        weight_field : string, optional
            The name of the weighting field.  Set to None for no weight.
        no_shifting : boolean, optional
            If set, no shifting due to velocity will occur but only thermal broadening.
            Should not be set when *thermal_broad* is False, otherwise nothing happens!
        north_vector : a sequence of floats
            A vector defining the 'up' direction. This option sets the orientation of 
            the plane of projection. If not set, an arbitrary grid-aligned north_vector 
            is chosen. Ignored in the case of on-axis cubes.
        no_ghost: bool, optional
            Optimization option for off-axis cases. If True, homogenized bricks will
            extrapolate out from grid instead of interpolating from
            ghost zones that have to first be calculated.  This can
            lead to large speed improvements, but at a loss of
            accuracy/smoothness in resulting image.  The effects are
            less notable when the transfer function is smooth and
            broad. Default: True

        Examples
        --------
        >>> i = 60*np.pi/180.
        >>> L = [0.0,np.sin(i),np.cos(i)]
        >>> cube = PPVCube(ds, L, "density", (-5.,4.,100,"km/s"), width=(10.,"kpc"))
        """

        self.ds = ds
        self.field = field
        self.width = width
        self.particle_mass = atomic_weight * mh
        self.thermal_broad = thermal_broad
        self.no_shifting = no_shifting

        if not isinstance(normal, string_types):
            width = ds.coordinates.sanitize_width(normal, width, depth)
            width = tuple(el.in_units('code_length').v for el in width)

        if no_shifting and not thermal_broad:
            raise RuntimeError(
                "no_shifting cannot be True when thermal_broad is False!")

        self.center = ds.coordinates.sanitize_center(center, normal)[0]

        self.nx = dims
        self.ny = dims
        self.nv = velocity_bounds[2]

        if method not in ["integrate", "sum"]:
            raise RuntimeError("Only the 'integrate' and 'sum' projection +"
                               "methods are supported in PPVCube.")

        dd = ds.all_data()
        fd = dd._determine_fields(field)[0]
        self.field_units = ds._get_field_info(fd).units

        self.vbins = ds.arr(
            np.linspace(velocity_bounds[0], velocity_bounds[1],
                        velocity_bounds[2] + 1), velocity_bounds[3])

        self._vbins = self.vbins.copy()
        self.vmid = 0.5 * (self.vbins[1:] + self.vbins[:-1])
        self.vmid_cgs = self.vmid.in_cgs().v
        self.dv = self.vbins[1] - self.vbins[0]
        self.dv_cgs = self.dv.in_cgs().v

        self.current_v = 0.0

        _vlos = create_vlos(normal, self.no_shifting)
        self.ds.add_field(("gas", "v_los"), function=_vlos, units="cm/s")

        _intensity = self._create_intensity()
        self.ds.add_field(("gas", "intensity"),
                          function=_intensity,
                          units=self.field_units)

        if method == "integrate" and weight_field is None:
            self.proj_units = str(ds.quan(1.0, self.field_units + "*cm").units)
        elif method == "sum":
            self.proj_units = self.field_units

        storage = {}
        pbar = get_pbar("Generating cube.", self.nv)
        for sto, i in parallel_objects(range(self.nv), storage=storage):
            self.current_v = self.vmid_cgs[i]
            if isinstance(normal, string_types):
                prj = ds.proj("intensity",
                              ds.coordinates.axis_id[normal],
                              method=method,
                              weight_field=weight_field)
                buf = prj.to_frb(width, self.nx,
                                 center=self.center)["intensity"]
            else:
                buf = off_axis_projection(ds,
                                          self.center,
                                          normal,
                                          width, (self.nx, self.ny, depth_res),
                                          "intensity",
                                          north_vector=north_vector,
                                          no_ghost=no_ghost,
                                          method=method,
                                          weight=weight_field).swapaxes(0, 1)
            sto.result_id = i
            sto.result = buf
            pbar.update(i)
        pbar.finish()

        self.data = ds.arr(np.zeros((self.nx, self.ny, self.nv)),
                           self.proj_units)
        if is_root():
            for i, buf in sorted(storage.items()):
                self.data[:, :, i] = buf.transpose()

        self.axis_type = "velocity"

        # Now fix the width
        if iterable(self.width):
            self.width = ds.quan(self.width[0], self.width[1])
        elif not isinstance(self.width, YTQuantity):
            self.width = ds.quan(self.width, "code_length")

        self.ds.field_info.pop(("gas", "intensity"))
        self.ds.field_info.pop(("gas", "v_los"))
    def __init__(self, ds, normal, field, velocity_bounds, center="c", 
                 width=(1.0,"unitary"), dims=100, thermal_broad=False,
                 atomic_weight=56., depth=(1.0,"unitary"), depth_res=256,
                 method="integrate", weight_field=None, no_shifting=False,
                 north_vector=None, no_ghost=True):
        r""" Initialize a PPVCube object.

        Parameters
        ----------
        ds : dataset
            The dataset.
        normal : array_like or string
            The normal vector along with to make the projections. If an array, it
            will be normalized. If a string, it will be assumed to be along one of the
            principal axes of the domain ("x", "y", or "z").
        field : string
            The field to project.
        velocity_bounds : tuple
            A 4-tuple of (vmin, vmax, nbins, units) for the velocity bounds to
            integrate over. 
        center : A sequence of floats, a string, or a tuple.
            The coordinate of the center of the image. If set to 'c', 'center' or
            left blank, the plot is centered on the middle of the domain. If set to
            'max' or 'm', the center will be located at the maximum of the
            ('gas', 'density') field. Centering on the max or min of a specific
            field is supported by providing a tuple such as ("min","temperature") or
            ("max","dark_matter_density"). Units can be specified by passing in *center*
            as a tuple containing a coordinate and string unit name or by passing
            in a YTArray. If a list or unitless array is supplied, code units are
            assumed.
        width : float, tuple, or YTQuantity.
            The width of the projection. A float will assume the width is in code units.
            A (value, unit) tuple or YTQuantity allows for the units of the width to be
            specified. Implies width = height, e.g. the aspect ratio of the PPVCube's 
            spatial dimensions is 1.
        dims : integer, optional
            The spatial resolution of the cube. Implies nx = ny, e.g. the 
            aspect ratio of the PPVCube's spatial dimensions is 1.
        thermal_broad : boolean, optional
            Whether or not to broaden the line using the gas temperature. Default: False.
        atomic_weight : float, optional
            Set this value to the atomic weight of the particle that is emitting the line
            if *thermal_broad* is True. Defaults to 56 (Fe).
        depth : A tuple or a float, optional
            A tuple containing the depth to project through and the string
            key of the unit: (width, 'unit').  If set to a float, code units
            are assumed. Only for off-axis cubes.
        depth_res : integer, optional
            The resolution of integration along the line of sight for off-axis cubes. Default: 256
        method : string, optional
            Set the projection method to be used.
            "integrate" : line of sight integration over the line element.
            "sum" : straight summation over the line of sight.
        weight_field : string, optional
            The name of the weighting field.  Set to None for no weight.
        no_shifting : boolean, optional
            If set, no shifting due to velocity will occur but only thermal broadening.
            Should not be set when *thermal_broad* is False, otherwise nothing happens!
        north_vector : a sequence of floats
            A vector defining the 'up' direction. This option sets the orientation of 
            the plane of projection. If not set, an arbitrary grid-aligned north_vector 
            is chosen. Ignored in the case of on-axis cubes.
        no_ghost: bool, optional
            Optimization option for off-axis cases. If True, homogenized bricks will
            extrapolate out from grid instead of interpolating from
            ghost zones that have to first be calculated.  This can
            lead to large speed improvements, but at a loss of
            accuracy/smoothness in resulting image.  The effects are
            less notable when the transfer function is smooth and
            broad. Default: True

        Examples
        --------
        >>> i = 60*np.pi/180.
        >>> L = [0.0,np.sin(i),np.cos(i)]
        >>> cube = PPVCube(ds, L, "density", (-5.,4.,100,"km/s"), width=(10.,"kpc"))
        """

        self.ds = ds
        self.field = field
        self.width = width
        self.particle_mass = atomic_weight*mh
        self.thermal_broad = thermal_broad
        self.no_shifting = no_shifting

        if not isinstance(normal, string_types):
            width = ds.coordinates.sanitize_width(normal, width, depth)
            width = tuple(el.in_units('code_length').v for el in width)

        if no_shifting and not thermal_broad:
            raise RuntimeError("no_shifting cannot be True when thermal_broad is False!")

        self.center = ds.coordinates.sanitize_center(center, normal)[0]

        self.nx = dims
        self.ny = dims
        self.nv = velocity_bounds[2]

        if method not in ["integrate","sum"]:
            raise RuntimeError("Only the 'integrate' and 'sum' projection +"
                               "methods are supported in PPVCube.")

        dd = ds.all_data()
        fd = dd._determine_fields(field)[0]
        self.field_units = ds._get_field_info(fd).units

        self.vbins = ds.arr(np.linspace(velocity_bounds[0],
                                        velocity_bounds[1],
                                        velocity_bounds[2]+1), velocity_bounds[3])

        self._vbins = self.vbins.copy()
        self.vmid = 0.5*(self.vbins[1:]+self.vbins[:-1])
        self.vmid_cgs = self.vmid.in_cgs().v
        self.dv = self.vbins[1]-self.vbins[0]
        self.dv_cgs = self.dv.in_cgs().v

        self.current_v = 0.0

        _vlos = create_vlos(normal, self.no_shifting)
        self.ds.add_field(("gas","v_los"), function=_vlos, units="cm/s")

        _intensity = self._create_intensity()
        self.ds.add_field(("gas","intensity"), function=_intensity, units=self.field_units)

        if method == "integrate" and weight_field is None:
            self.proj_units = str(ds.quan(1.0, self.field_units+"*cm").units)
        elif method == "sum":
            self.proj_units = self.field_units

        storage = {}
        pbar = get_pbar("Generating cube.", self.nv)
        for sto, i in parallel_objects(range(self.nv), storage=storage):
            self.current_v = self.vmid_cgs[i]
            if isinstance(normal, string_types):
                prj = ds.proj("intensity", ds.coordinates.axis_id[normal], method=method,
                              weight_field=weight_field)
                buf = prj.to_frb(width, self.nx, center=self.center)["intensity"]
            else:
                buf = off_axis_projection(ds, self.center, normal, width,
                                          (self.nx, self.ny, depth_res), "intensity",
                                          north_vector=north_vector, no_ghost=no_ghost,
                                          method=method, weight=weight_field).swapaxes(0,1)
            sto.result_id = i
            sto.result = buf
            pbar.update(i)
        pbar.finish()

        self.data = ds.arr(np.zeros((self.nx,self.ny,self.nv)), self.proj_units)
        if is_root():
            for i, buf in sorted(storage.items()):
                self.data[:,:,i] = buf.transpose()

        self.axis_type = "velocity"

        # Now fix the width
        if iterable(self.width):
            self.width = ds.quan(self.width[0], self.width[1])
        elif not isinstance(self.width, YTQuantity):
            self.width = ds.quan(self.width, "code_length")

        self.ds.field_info.pop(("gas","intensity"))
        self.ds.field_info.pop(("gas","v_los"))
Example #5
0
def test_fits_image():
    tmpdir = tempfile.mkdtemp()
    curdir = os.getcwd()
    os.chdir(tmpdir)

    fields = ("density", "temperature")
    units = (
        'g/cm**3',
        'K',
    )
    ds = fake_random_ds(64,
                        fields=fields,
                        units=units,
                        nprocs=16,
                        length_unit=100.0)

    prj = ds.proj("density", 2)
    prj_frb = prj.to_frb((0.5, "unitary"), 128)

    fid1 = FITSImageData(prj_frb,
                         fields=["density", "temperature"],
                         units="cm")
    fits_prj = FITSProjection(ds,
                              "z", ["density", "temperature"],
                              image_res=128,
                              width=(0.5, "unitary"))

    yield assert_equal, fid1.get_data("density"), fits_prj.get_data("density")
    yield assert_equal, fid1.get_data("temperature"), fits_prj.get_data(
        "temperature")

    fid1.writeto("fid1.fits", clobber=True)
    new_fid1 = FITSImageData.from_file("fid1.fits")

    yield assert_equal, fid1.get_data("density"), new_fid1.get_data("density")
    yield assert_equal, fid1.get_data("temperature"), new_fid1.get_data(
        "temperature")

    ds2 = load("fid1.fits")
    ds2.index

    assert ("fits", "density") in ds2.field_list
    assert ("fits", "temperature") in ds2.field_list

    dw_cm = ds2.domain_width.in_units("cm")

    assert dw_cm[0].v == 50.
    assert dw_cm[1].v == 50.

    slc = ds.slice(2, 0.5)
    slc_frb = slc.to_frb((0.5, "unitary"), 128)

    fid2 = FITSImageData(slc_frb,
                         fields=["density", "temperature"],
                         units="cm")
    fits_slc = FITSSlice(ds,
                         "z", ["density", "temperature"],
                         image_res=128,
                         width=(0.5, "unitary"))

    yield assert_equal, fid2.get_data("density"), fits_slc.get_data("density")
    yield assert_equal, fid2.get_data("temperature"), fits_slc.get_data(
        "temperature")

    dens_img = fid2.pop("density")
    temp_img = fid2.pop("temperature")

    # This already has some assertions in it, so we don't need to do anything
    # with it other can just make one
    fid_comb = FITSImageData.from_images([dens_img, temp_img])

    cut = ds.cutting([0.1, 0.2, -0.9], [0.5, 0.42, 0.6])
    cut_frb = cut.to_frb((0.5, "unitary"), 128)

    fid3 = FITSImageData(cut_frb,
                         fields=["density", "temperature"],
                         units="cm")
    fits_cut = FITSOffAxisSlice(ds, [0.1, 0.2, -0.9],
                                ["density", "temperature"],
                                image_res=128,
                                center=[0.5, 0.42, 0.6],
                                width=(0.5, "unitary"))

    yield assert_equal, fid3.get_data("density"), fits_cut.get_data("density")
    yield assert_equal, fid3.get_data("temperature"), fits_cut.get_data(
        "temperature")

    fid3.create_sky_wcs([30., 45.], (1.0, "arcsec/kpc"))
    fid3.writeto("fid3.fits", clobber=True)
    new_fid3 = FITSImageData.from_file("fid3.fits")
    assert_same_wcs(fid3.wcs, new_fid3.wcs)
    assert new_fid3.wcs.wcs.cunit[0] == "deg"
    assert new_fid3.wcs.wcs.cunit[1] == "deg"
    assert new_fid3.wcs.wcs.ctype[0] == "RA---TAN"
    assert new_fid3.wcs.wcs.ctype[1] == "DEC--TAN"

    buf = off_axis_projection(ds, ds.domain_center, [0.1, 0.2, -0.9], 0.5, 128,
                              "density").swapaxes(0, 1)
    fid4 = FITSImageData(buf, fields="density", width=100.0)
    fits_oap = FITSOffAxisProjection(ds, [0.1, 0.2, -0.9],
                                     "density",
                                     width=(0.5, "unitary"),
                                     image_res=128,
                                     depth_res=128,
                                     depth=(0.5, "unitary"))

    yield assert_equal, fid4.get_data("density"), fits_oap.get_data("density")

    cvg = ds.covering_grid(ds.index.max_level, [0.25, 0.25, 0.25],
                           [32, 32, 32],
                           fields=["density", "temperature"])
    fid5 = FITSImageData(cvg, fields=["density", "temperature"])
    assert fid5.dimensionality == 3

    fid5.update_header("density", "time", 0.1)
    fid5.update_header("all", "units", "cgs")

    assert fid5["density"].header["time"] == 0.1
    assert fid5["temperature"].header["units"] == "cgs"
    assert fid5["density"].header["units"] == "cgs"

    os.chdir(curdir)
    shutil.rmtree(tmpdir)
def test_fits_image():
    tmpdir = tempfile.mkdtemp()
    curdir = os.getcwd()
    os.chdir(tmpdir)

    fields = ("density", "temperature")
    units = ('g/cm**3', 'K',)
    ds = fake_random_ds(64, fields=fields, units=units, nprocs=16,
                        length_unit=100.0)

    prj = ds.proj("density", 2)
    prj_frb = prj.to_frb((0.5, "unitary"), 128)

    fid1 = FITSImageData(prj_frb, fields=["density","temperature"], units="cm")
    fits_prj = FITSProjection(ds, "z", ["density","temperature"], image_res=128,
                              width=(0.5,"unitary"))

    yield assert_equal, fid1.get_data("density"), fits_prj.get_data("density")
    yield assert_equal, fid1.get_data("temperature"), fits_prj.get_data("temperature")

    fid1.writeto("fid1.fits", clobber=True)
    new_fid1 = FITSImageData.from_file("fid1.fits")

    yield assert_equal, fid1.get_data("density"), new_fid1.get_data("density")
    yield assert_equal, fid1.get_data("temperature"), new_fid1.get_data("temperature")

    ds2 = load("fid1.fits")
    ds2.index

    assert ("fits","density") in ds2.field_list
    assert ("fits","temperature") in ds2.field_list

    dw_cm = ds2.domain_width.in_units("cm")

    assert dw_cm[0].v == 50.
    assert dw_cm[1].v == 50.

    slc = ds.slice(2, 0.5)
    slc_frb = slc.to_frb((0.5, "unitary"), 128)

    fid2 = FITSImageData(slc_frb, fields=["density","temperature"], units="cm")
    fits_slc = FITSSlice(ds, "z", ["density","temperature"], image_res=128,
                         width=(0.5,"unitary"))

    yield assert_equal, fid2.get_data("density"), fits_slc.get_data("density")
    yield assert_equal, fid2.get_data("temperature"), fits_slc.get_data("temperature")

    dens_img = fid2.pop("density")
    temp_img = fid2.pop("temperature")

    # This already has some assertions in it, so we don't need to do anything
    # with it other can just make one
    fid_comb = FITSImageData.from_images([dens_img, temp_img])

    cut = ds.cutting([0.1, 0.2, -0.9], [0.5, 0.42, 0.6])
    cut_frb = cut.to_frb((0.5, "unitary"), 128)

    fid3 = FITSImageData(cut_frb, fields=["density","temperature"], units="cm")
    fits_cut = FITSOffAxisSlice(ds, [0.1, 0.2, -0.9], ["density","temperature"],
                                image_res=128, center=[0.5, 0.42, 0.6],
                                width=(0.5,"unitary"))

    yield assert_equal, fid3.get_data("density"), fits_cut.get_data("density")
    yield assert_equal, fid3.get_data("temperature"), fits_cut.get_data("temperature")

    fid3.create_sky_wcs([30.,45.], (1.0,"arcsec/kpc"))
    fid3.writeto("fid3.fits", clobber=True)
    new_fid3 = FITSImageData.from_file("fid3.fits")
    assert_same_wcs(fid3.wcs, new_fid3.wcs)
    assert new_fid3.wcs.wcs.cunit[0] == "deg"
    assert new_fid3.wcs.wcs.cunit[1] == "deg"
    assert new_fid3.wcs.wcs.ctype[0] == "RA---TAN"
    assert new_fid3.wcs.wcs.ctype[1] == "DEC--TAN"

    buf = off_axis_projection(ds, ds.domain_center, [0.1, 0.2, -0.9],
                              0.5, 128, "density").swapaxes(0, 1)
    fid4 = FITSImageData(buf, fields="density", width=100.0)
    fits_oap = FITSOffAxisProjection(ds, [0.1, 0.2, -0.9], "density",
                                     width=(0.5,"unitary"), image_res=128,
                                     depth_res=128, depth=(0.5,"unitary"))

    yield assert_equal, fid4.get_data("density"), fits_oap.get_data("density")

    cvg = ds.covering_grid(ds.index.max_level, [0.25,0.25,0.25],
                           [32, 32, 32], fields=["density","temperature"])
    fid5 = FITSImageData(cvg, fields=["density","temperature"])
    assert fid5.dimensionality == 3

    fid5.update_header("density", "time", 0.1)
    fid5.update_header("all", "units", "cgs")

    assert fid5["density"].header["time"] == 0.1
    assert fid5["temperature"].header["units"] == "cgs"
    assert fid5["density"].header["units"] == "cgs"

    os.chdir(curdir)
    shutil.rmtree(tmpdir)
Example #7
0
    def __init__(self,
                 ds,
                 normal,
                 field,
                 width=(1.0, "unitary"),
                 dims=(100, 100, 100),
                 velocity_bounds=None):
        r""" Initialize a PPVCube object.

        Parameters
        ----------
        ds : dataset
            The dataset.
        normal : array_like
            The normal vector along with to make the projections.
        field : string
            The field to project.
        width : float or tuple, optional
            The width of the projection in length units. Specify a float
            for code_length units or a tuple (value, units).
        dims : tuple, optional
            A 3-tuple of dimensions (nx,ny,nv) for the cube.
        velocity_bounds : tuple, optional
            A 3-tuple of (vmin, vmax, units) for the velocity bounds to
            integrate over. If None, the largest velocity of the
            dataset will be used, e.g. velocity_bounds = (-v.max(), v.max())

        Examples
        --------
        >>> i = 60*np.pi/180.
        >>> L = [0.0,np.sin(i),np.cos(i)]
        >>> cube = PPVCube(ds, L, "density", width=(10.,"kpc"),
        ...                velocity_bounds=(-5.,4.,"km/s"))
        """
        self.ds = ds
        self.field = field
        self.width = width

        self.nx = dims[0]
        self.ny = dims[1]
        self.nv = dims[2]

        normal = np.array(normal)
        normal /= np.sqrt(np.dot(normal, normal))
        vecs = np.identity(3)
        t = np.cross(normal, vecs).sum(axis=1)
        ax = t.argmax()
        north = np.cross(normal, vecs[ax, :]).ravel()
        orient = Orientation(normal, north_vector=north)

        dd = ds.all_data()

        fd = dd._determine_fields(field)[0]

        self.field_units = ds._get_field_info(fd).units

        if velocity_bounds is None:
            vmin, vmax = dd.quantities.extrema("velocity_magnitude")
            self.v_bnd = -vmax, vmax
        else:
            self.v_bnd = (ds.quan(velocity_bounds[0], velocity_bounds[2]),
                          ds.quan(velocity_bounds[1], velocity_bounds[2]))

        self.vbins = np.linspace(self.v_bnd[0], self.v_bnd[1], num=self.nv + 1)
        self.vmid = 0.5 * (self.vbins[1:] + self.vbins[:-1])
        self.dv = (self.v_bnd[1] - self.v_bnd[0]) / self.nv

        _vlos = create_vlos(orient.unit_vectors[2])
        ds.field_info.add_field(("gas", "v_los"), function=_vlos, units="cm/s")

        self.data = ds.arr(np.zeros((self.nx, self.ny, self.nv)),
                           self.field_units)
        pbar = get_pbar("Generating cube.", self.nv)
        for i in xrange(self.nv):
            _intensity = self._create_intensity(i)
            ds.add_field(("gas", "intensity"),
                         function=_intensity,
                         units=self.field_units)
            prj = off_axis_projection(ds, ds.domain_center, normal, width,
                                      (self.nx, self.ny), "intensity")
            self.data[:, :, i] = prj[:, :]
            ds.field_info.pop(("gas", "intensity"))
            pbar.update(i)

        pbar.finish()
Example #8
0
    def off_axis(self, L, center="c", width=(1, "unitary"), nx=800, source=None):
        r""" Make an off-axis projection of the SZ signal.

        Parameters
        ----------
        L : array_like
            The normal vector of the projection.
        center : A sequence of floats, a string, or a tuple.
            The coordinate of the center of the image. If set to 'c', 'center' or
            left blank, the plot is centered on the middle of the domain. If set to
            'max' or 'm', the center will be located at the maximum of the
            ('gas', 'density') field. Centering on the max or min of a specific
            field is supported by providing a tuple such as ("min","temperature") or
            ("max","dark_matter_density"). Units can be specified by passing in *center*
            as a tuple containing a coordinate and string unit name or by passing
            in a YTArray. If a list or unitless array is supplied, code units are
            assumed.
        width : float, tuple, or YTQuantity.
            The width of the projection. A float will assume the width is in code units.
            A (value, unit) tuple or YTQuantity allows for the units of the width to be specified.
        nx : integer, optional
            The dimensions on a side of the projection image.
        source : yt.data_objects.data_containers.YTSelectionContainer, optional
            If specified, this will be the data source used for selecting regions to project.
            Currently unsupported in yt 2.x.

        Examples
        --------
        >>> L = np.array([0.5, 1.0, 0.75])
        >>> szprj.off_axis(L, center="c", width=(2.0, "Mpc"))
        """
        if iterable(width):
            w = self.ds.quan(width[0], width[1]).in_units("code_length").value
        elif isinstance(width, YTQuantity):
            w = width.in_units("code_length").value
        else:
            w = width
        ctr, dctr = self.ds.coordinates.sanitize_center(center, L)

        if source is not None:
            mylog.error("Source argument is not currently supported for off-axis S-Z projections.")
            raise NotImplementedError

        beta_par = generate_beta_par(L)
        self.ds.add_field(("gas","beta_par"), function=beta_par, units="g/cm**3")
        setup_sunyaev_zeldovich_fields(self.ds)

        dens    = off_axis_projection(self.ds, ctr, L, w, nx, "density")
        Te      = off_axis_projection(self.ds, ctr, L, w, nx, "t_sz")/dens
        bpar    = off_axis_projection(self.ds, ctr, L, w, nx, "beta_par")/dens
        omega1  = off_axis_projection(self.ds, ctr, L, w, nx, "t_squared")/dens
        omega1  = omega1/(Te*Te) - 1.
        if self.high_order:
            bperp2  = off_axis_projection(self.ds, ctr, L, w, nx, "beta_perp_squared")/dens
            sigma1  = off_axis_projection(self.ds, ctr, L, w, nx, "t_beta_par")/dens
            sigma1  = sigma1/Te - bpar
            kappa1  = off_axis_projection(self.ds, ctr, L, w, nx, "beta_par_squared")/dens
            kappa1 -= bpar
        else:
            bperp2 = np.zeros((nx,nx))
            sigma1 = np.zeros((nx,nx))
            kappa1 = np.zeros((nx,nx))
        tau = sigma_thompson*dens*self.mueinv/mh

        self.bounds = np.array([-0.5*w, 0.5*w, -0.5*w, 0.5*w])
        self.dx = w/nx
        self.dy = w/nx
        self.nx = nx

        self._compute_intensity(np.array(tau), np.array(Te), np.array(bpar),
                                np.array(omega1), np.array(sigma1),
                                np.array(kappa1), np.array(bperp2))

        self.ds.field_info.pop(("gas","beta_par"))
Example #9
0
    def off_axis(self,
                 L,
                 center="c",
                 width=(1, "unitary"),
                 nx=800,
                 source=None):
        r""" Make an off-axis projection of the SZ signal.

        Parameters
        ----------
        L : array_like
            The normal vector of the projection.
        center : array_like or string, optional
            The center of the projection.
        width : float or tuple
            The width of the projection.
        nx : integer, optional
            The dimensions on a side of the projection image.
        source : yt.data_objects.api.AMRData, optional
            If specified, this will be the data source used for selecting regions to project.
            Currently unsupported in yt 2.x.

        Examples
        --------
        >>> L = np.array([0.5, 1.0, 0.75])
        >>> szprj.off_axis(L, center="c", width=(2.0, "Mpc"))
        """
        if iterable(width):
            w = self.ds.quan(width[0], width[1]).in_units("code_length").value
        elif isinstance(width, YTQuantity):
            w = width.in_units("code_length").value
        else:
            w = width
        if center == "c":
            ctr = self.ds.domain_center
        elif center == "max":
            v, ctr = self.ds.find_max("density")
        else:
            ctr = center

        if source is not None:
            mylog.error(
                "Source argument is not currently supported for off-axis S-Z projections."
            )
            raise NotImplementedError

        beta_par = generate_beta_par(L)
        self.ds.add_field(("gas", "beta_par"),
                          function=beta_par,
                          units="g/cm**3")
        setup_sunyaev_zeldovich_fields(self.ds)

        dens = off_axis_projection(self.ds, ctr, L, w, nx, "density")
        Te = off_axis_projection(self.ds, ctr, L, w, nx, "t_sz") / dens
        bpar = off_axis_projection(self.ds, ctr, L, w, nx, "beta_par") / dens
        omega1 = off_axis_projection(self.ds, ctr, L, w, nx,
                                     "t_squared") / dens
        omega1 = omega1 / (Te * Te) - 1.
        if self.high_order:
            bperp2 = off_axis_projection(self.ds, ctr, L, w, nx,
                                         "beta_perp_squared") / dens
            sigma1 = off_axis_projection(self.ds, ctr, L, w, nx,
                                         "t_beta_par") / dens
            sigma1 = sigma1 / Te - bpar
            kappa1 = off_axis_projection(self.ds, ctr, L, w, nx,
                                         "beta_par_squared") / dens
            kappa1 -= bpar
        else:
            bperp2 = np.zeros((nx, nx))
            sigma1 = np.zeros((nx, nx))
            kappa1 = np.zeros((nx, nx))
        tau = sigma_thompson * dens * self.mueinv / mh

        self.bounds = np.array([-0.5 * w, 0.5 * w, -0.5 * w, 0.5 * w])
        self.dx = w / nx
        self.dy = w / nx
        self.nx = nx

        self._compute_intensity(np.array(tau), np.array(Te), np.array(bpar),
                                np.array(omega1), np.array(sigma1),
                                np.array(kappa1), np.array(bperp2))

        self.ds.field_info.pop(("gas", "beta_par"))