Exemplo n.º 1
0
def test_moc_contains():
    order = 4
    size = 20
    healpix_arr = np.random.randint(0, 12 * 4**order, size)
    all_healpix_arr = np.arange(12 * 4**order)
    healpix_outside_arr = np.setdiff1d(all_healpix_arr, healpix_arr)

    moc = MOC.from_json(json_moc={str(order): list(healpix_arr)})

    #viz = Vizier(columns=['*', '_RAJ2000', '_DEJ2000'])
    #viz.ROW_LIMIT = -1
    #table = viz.get_catalogs('I/293/npm2cros')[0]

    hp = HEALPix(nside=(1 << order), order='nested', frame=ICRS())
    lon, lat = hp.healpix_to_lonlat(healpix_arr)
    lon_out, lat_out = hp.healpix_to_lonlat(healpix_outside_arr)

    should_be_inside_arr = moc.contains(ra=lon, dec=lat)
    assert should_be_inside_arr.all()
    should_be_outside_arr = moc.contains(ra=lon_out, dec=lat_out)
    assert not should_be_outside_arr.any()

    # test keep_inside field
    should_be_outside_arr = moc.contains(ra=lon, dec=lat, keep_inside=False)
    assert not should_be_outside_arr.any()
    should_be_inside_arr = moc.contains(ra=lon_out,
                                        dec=lat_out,
                                        keep_inside=False)
    assert should_be_inside_arr.all()
Exemplo n.º 2
0
    def DarkMap(self, nside, whichprofile, rs, rb, gamma, xmax, dx):

        #bvalues, lvalues, pixarea = self.toGcoordinate(nside)
        pixarea = hp.nside2pixarea(nside)
        npix = hp.nside2npix(nside)

        HP = HEALPix(nside=nside, order='ring')

        theta, phi = hp.pix2ang(nside, range(npix))

        bvalues = np.array(
            [HP.healpix_to_lonlat([i])[1][0].value for i in range(len(theta))])
        lvalues = np.array(
            [HP.healpix_to_lonlat([i])[0][0].value for i in range(len(phi))])

        mappa_ary = np.array([
            self.integratedDM(whichprofile, rs, rb, gamma, bvalues[p],
                              lvalues[p], xmax, dx) for p in range(npix)
        ])

        # Multiply by area of pixel to add sr unit
        mappa_ary *= pixarea

        return hp.ud_grade(
            np.array(mappa_ary), 128, power=-2
        )  # See https://healpy.readthedocs.io/en/latest/generated/healpy.pixelfunc.ud_grade.html
def decomposition_IT20(sp_mass, sp_am_unit_vector):
    """
    Perform disc/spheroid decomposition of simulated galaxies based on the method introduced in Irodotou and Thomas 2020 (hereafter IT20)
    (https://ui.adsabs.harvard.edu/abs/2020arXiv200908483I/abstract).
    This function takes as arguments the mass and angular momentum of stellar particles and returns two masks that contain disc and spheroid particles
    and the disc-to-total stellar mass ratio of the galaxy.

    # Step (i) in Section 2.2 Decomposition of IT20 #
    :param sp_mass: list of stellar particles's (sp) masses.
    :param sp_am_unit_vector: list of stellar particles's (sp) normalised angular momenta (am) unit vectors.
    :return: disc_mask_IT20, spheroid_mask_IT20, disc_fraction_IT20
    """

    # Step (ii) in Section 2.2 Decomposition of IT20 #
    # Calculate the azimuth (alpha) and elevation (delta) angle of the angular momentum of all stellar particles #
    alpha = np.degrees(np.arctan2(sp_am_unit_vector[:, 1], sp_am_unit_vector[:, 0]))  # In degrees.
    delta = np.degrees(np.arcsin(sp_am_unit_vector[:, 2]))  # In degrees.

    # Step (ii) in Section 2.2 Decomposition of IT20 #
    # Generate the pixelisation of the angular momentum map #
    nside = 2 ** 4  # Define the resolution of the grid (number of divisions along the side of a base-resolution grid cell).
    hp = HEALPix(nside=nside)  # Initialise the HEALPix pixelisation class.
    indices = hp.lonlat_to_healpix(alpha * u.deg, delta * u.deg)  # Create a list of HEALPix indices from particles's alpha and delta.
    densities = np.bincount(indices, minlength=hp.npix)  # Count number of data points in each HEALPix grid cell.

    # Step (iii) in Section 2.2 Decomposition of IT20 #
    # Smooth the angular momentum map with a top-hat filter of angular radius 30 degrees #
    smoothed_densities = np.zeros(hp.npix)
    # Loop over all grid cells #
    for i in range(hp.npix):
        mask = hlp.query_disc(nside, hlp.pix2vec(nside, i), np.pi / 6.0)  # Do a 30 degree cone search around each grid cell.
        smoothed_densities[i] = np.mean(densities[mask])  # Average the densities of the ones inside and assign this value to the grid cell.

    # Step (iii) in Section 2.2 Decomposition of IT20 #
    # Find the location of the density maximum #
    index_densest = np.argmax(smoothed_densities)
    alpha_densest = (hp.healpix_to_lonlat([index_densest])[0].value + np.pi) % (2 * np.pi) - np.pi  # In radians.
    delta_densest = (hp.healpix_to_lonlat([index_densest])[1].value + np.pi / 2) % (2 * np.pi) - np.pi / 2  # In radians.

    # Step (iv) in Section 2.2 Decomposition of IT20 #
    # Calculate the angular separation of each stellar particle from the centre of the densest grid cell #
    Delta_theta = np.arccos(np.sin(delta_densest) * np.sin(np.radians(delta)) + np.cos(delta_densest) * np.cos(np.radians(delta)) * np.cos(
        alpha_densest - np.radians(alpha)))  # In radians.

    # Step (v) in Section 2.2 Decomposition of IT20 #
    # Calculate the disc mass fraction as the mass within 30 degrees from the densest grid cell #
    disc_mask_IT20, = np.where(Delta_theta < (np.pi / 6.0))
    spheroid_mask_IT20, = np.where(Delta_theta >= (np.pi / 6.0))
    disc_fraction_IT20 = np.sum(sp_mass[disc_mask_IT20]) / np.sum(sp_mass)

    # Step (vi) in Section 2.2 Decomposition of IT20 #
    # Normalise the disc fractions #
    chi = 0.5 * (1 - np.cos(np.pi / 6))
    disc_fraction_IT20 = np.divide(1, 1 - chi) * (disc_fraction_IT20 - chi)

    return disc_mask_IT20, spheroid_mask_IT20, disc_fraction_IT20
Exemplo n.º 4
0
def test_moc_contains():
    order = 4
    size = 20
    healpix_arr = np.random.randint(0, 12*4**order, size)
    all_healpix_arr = np.arange(12*4**order)
    healpix_outside_arr = np.setdiff1d(all_healpix_arr, healpix_arr)

    moc = MOC.from_json(json_moc={str(order): list(healpix_arr)})

    hp = HEALPix(nside=(1 << order), order='nested', frame=ICRS())
    lon, lat = hp.healpix_to_lonlat(healpix_arr)
    lon_out, lat_out = hp.healpix_to_lonlat(healpix_outside_arr)

    should_be_inside_arr = moc.contains(ra=lon, dec=lat)
    assert should_be_inside_arr.all()
    should_be_outside_arr = moc.contains(ra=lon_out, dec=lat_out)
    assert not should_be_outside_arr.any()

    # test keep_inside field
    should_be_outside_arr = moc.contains(ra=lon, dec=lat, keep_inside=False)
    assert not should_be_outside_arr.any()
    should_be_inside_arr = moc.contains(ra=lon_out, dec=lat_out, keep_inside=False)
    assert should_be_inside_arr.all()
Exemplo n.º 5
0
while True:
    one_point_map = draw_map(nside, albedo_mean, albedo_std,
                             whitenoise_relative_amp, length_scale)
    if min(one_point_map) > 0 and max(one_point_map) < 1:
        break
bright_spot = 1
for i in range(0, one_point_map.size):
    if i == bright_spot:
        one_point_map[i] = 1.00
    else:
        one_point_map[i] = 0.00

# Parameters
p_rotation = 1
p_orbit = 365.256363
lat, lng = map.healpix_to_lonlat([bright_spot])
w_rot = 2 * np.pi / p_rotation
w_orb = 2 * np.pi / p_orbit
inclination = np.pi / 2
obliquity = 0
sol_phase = 1
p_rotation = 2 * np.pi / w_rot
p_orb = 2 * np.pi / w_orb
times = np.linspace(start=0.0, stop=1.0, num=1400)
measurement_std = 0.001

# DO NOT CHANGE THIS.
phi_orb = abs(5 * (np.pi / 3) + sol_phase)
phi_rot = abs(2 * np.pi - sol_phase)

# NUMERIC
Exemplo n.º 6
0
def image_to_healpix(data,
                     wcs_in,
                     coord_system_out,
                     nside,
                     order='bilinear',
                     nested=False):
    """
    Convert image in a normal WCS projection to HEALPIX format.

    Parameters
    ----------
    data : `numpy.ndarray`
        Input data array to reproject
    wcs_in : `~astropy.wcs.WCS`
        The WCS of the input array
    coord_system_out : str or `~astropy.coordinates.BaseCoordinateFrame`
        The target coordinate system for the HEALPIX projection, as an Astropy
        coordinate frame or corresponding string alias (e.g. ``'icrs'`` or
        ``'galactic'``)
    order : int or str, optional
        The order of the interpolation (if ``mode`` is set to
        ``'interpolation'``). This can be either one of the following strings:

            * 'nearest-neighbor'
            * 'bilinear'
            * 'biquadratic'
            * 'bicubic'

        or an integer. A value of ``0`` indicates nearest neighbor
        interpolation.
    nested : bool
        The order of the healpix_data, either nested or ring.  Stored in
        FITS headers in the ORDERING keyword.

    Returns
    -------
    reprojected_data : `numpy.ndarray`
        A HEALPIX array of values
    footprint : `~numpy.ndarray`
        Footprint of the input array in the output array. Values of 0 indicate
        no coverage or valid values in the input image, while values of 1
        indicate valid values.
    """
    from scipy.ndimage import map_coordinates

    hp = HEALPix(nside=nside, order='nested' if nested else 'ring')

    npix = hp.npix

    # Look up lon, lat of pixels in output system and convert colatitude theta
    # and longitude phi to longitude and latitude.
    lon_out, lat_out = hp.healpix_to_lonlat(np.arange(npix))

    lon_out = lon_out.to(u.deg).value
    lat_out = lat_out.to(u.deg).value

    # Convert between celestial coordinates
    coord_system_out = parse_coord_system(coord_system_out)
    with np.errstate(invalid='ignore'):
        lon_in, lat_in = convert_world_coordinates(
            lon_out, lat_out, (coord_system_out, u.deg, u.deg), wcs_in)

    # Look up pixels in input system
    yinds, xinds = wcs_in.wcs_world2pix(lon_in, lat_in, 0)

    # Interpolate

    if isinstance(order, six.string_types):
        order = ORDER[order]

    healpix_data = map_coordinates(data, [xinds, yinds],
                                   order=order,
                                   mode='constant',
                                   cval=np.nan)

    return healpix_data, (~np.isnan(healpix_data)).astype(float)
Exemplo n.º 7
0
                             whitenoise_relative_amp, length_scale)
    if min(simulated_map) > 0 and max(simulated_map) < 1:
        break
#
# # simulating a map that's all black everywhere except for one bright spot
#
for i in range(0, simulated_map.size):
    if i == 100:
        simulated_map[i] = 1.00
    else:
        simulated_map[i] = 0.000
hp.mollview(simulated_map, title='albedo', cmap='gist_gray')

# obtaining the lon and lat of this point
map = HEALPix(nside=nside, order='nested')
pt_lng, pt_lat = map.healpix_to_lonlat([100])
print("lng")
print(pt_lng)
print("lat")
print(pt_lat)

# Set orbital properties
p_rotation = 23.934
p_orbit = 365.256363 * 24.0
phi_orb = np.pi
# inclination = np.pi/2
# obliquity = 90. * np.pi/180.0
obliquity = np.pi / 4
inclination = np.pi / 2
phi_rot = np.pi
Exemplo n.º 8
0
    if min(one_point_map) > 0 and max(one_point_map) <1:
        break
bright_spot = 12
for i in range(0, one_point_map.size):
    if i == bright_spot:
        one_point_map[i] = 1.00
    else:
        one_point_map[i] = 0.00
map = HEALPix(nside=nside, order='ring')

#Inputs
p_rotation = 1
p_orbit = 365.256363
times = np.linspace(start=0.0, stop=10.0, num=1400)
measurement_std = 0.001
lat, lng = map.healpix_to_lonlat([bright_spot])
a = Angle((np.pi/2)*u.rad)
colat = a-lat
w_rot = 2*np.pi/p_rotation
w_orb = 2*np.pi/p_orbit
inclination = 0
obliquity = 0
sol_phase = np.pi/6
# p_rotation = 2*np.pi/w_rot
# p_orb = 2*np.pi/w_orb
phi_orb = abs(1*(np.pi/2) + sol_phase)       # Unknown parameter 1
phi_rot = abs(1*(np.pi/2) - sol_phase)       # Unknown parameter 2

# Numeric lightcurve
truth = IlluminationMapPosterior(times, np.zeros_like(times),
                                 measurement_std, nside=nside)
Exemplo n.º 9
0
def generate_positions(
    min_positions: int,
    mount_model: MountModel,
    mount: TelescopeMount,
    min_altitude: Angle = 0.0 * u.deg,
    meridian_side: Optional[MeridianSide] = None,
) -> List[Position]:
    """Generate a list of equally spaced positions on the sky to search.

    The list of positions generated will be a subset of pixels generated by the HEALPix algorithm,
    which is a method of pixelization of a sphere where each "pixel" has equal area. In the
    context of mount alignment we not so much concerned with the equal area property, but we do
    want positions that are roughly evenly distributed over the sphere, and HEALPix does a
    reasonable job of this as well. The full set of HEALPix pixels is filtered to exclude pixels
    that are below a minimum altitude threshold and (optionally) those that are on the opposite
    side of the meridian. HEALPix is oriented with the top approximately at local zenith. Since
    these positions are used prior to alignment the mount may not point to the actual azimuth
    of each coordinate but this is not important.

    Args:
        min_positions: Minimum number of positions. The actual number of positions returned may be
            larger than requested.
        min_altitude: Restrict positions to be above this altitude.
        meridian_side: If specified, restricts positions to only be on this side of the meridian,
            where meridian is defined as the great circle passing through local zenith and the
            mount pole.

    Returns:
        A list of Position objects to use for alignment.
    """
    level = 0
    while True:
        healpix = HEALPix(nside=2**level)
        positions = []
        for i in range(healpix.npix):

            # interpret each HEALPix as a topocentric (AzAlt) coordinate
            (az, alt) = healpix.healpix_to_lonlat(i)

            # skip points on wrong side of mount meridian
            if az > 180 * u.deg:  # west of meridian
                if meridian_side == MeridianSide.EAST:
                    continue
                side = MeridianSide.WEST
            if az <= 180 * u.deg:  # east of meridian
                if meridian_side == MeridianSide.WEST:
                    continue
                side = MeridianSide.EAST

            # skip points below min altitude threshold
            if alt < min_altitude:
                continue

            position_topo = SkyCoord(az, alt, frame='altaz')
            encoder_positions = mount_model.topocentric_to_encoders(
                position_topo, side)
            positions.append(
                Position(
                    encoder_positions=encoder_positions,
                    mount=mount,
                ))

        if len(positions) >= min_positions:
            break

        # not enough positions -- try again with a higher level HEALPix
        level += 1

    return positions
Exemplo n.º 10
0
def image_to_healpix(data, wcs_in, coord_system_out,
                     nside, order='bilinear', nested=False):
    """
    Convert image in a normal WCS projection to HEALPIX format.

    Parameters
    ----------
    data : `numpy.ndarray`
        Input data array to reproject
    wcs_in : `~astropy.wcs.WCS`
        The WCS of the input array
    coord_system_out : str or `~astropy.coordinates.BaseCoordinateFrame`
        The target coordinate system for the HEALPIX projection, as an Astropy
        coordinate frame or corresponding string alias (e.g. ``'icrs'`` or
        ``'galactic'``)
    order : int or str, optional
        The order of the interpolation (if ``mode`` is set to
        ``'interpolation'``). This can be either one of the following strings:

            * 'nearest-neighbor'
            * 'bilinear'
            * 'biquadratic'
            * 'bicubic'

        or an integer. A value of ``0`` indicates nearest neighbor
        interpolation.
    nested : bool
        The order of the healpix_data, either nested or ring.  Stored in
        FITS headers in the ORDERING keyword.

    Returns
    -------
    reprojected_data : `numpy.ndarray`
        A HEALPIX array of values
    footprint : `~numpy.ndarray`
        Footprint of the input array in the output array. Values of 0 indicate
        no coverage or valid values in the input image, while values of 1
        indicate valid values.
    """
    from scipy.ndimage import map_coordinates

    hp = HEALPix(nside=nside, order='nested' if nested else 'ring')

    npix = hp.npix

    # Look up lon, lat of pixels in output system and convert colatitude theta
    # and longitude phi to longitude and latitude.
    lon_out, lat_out = hp.healpix_to_lonlat(np.arange(npix))

    lon_out = lon_out.to(u.deg).value
    lat_out = lat_out.to(u.deg).value

    # Convert between celestial coordinates
    coord_system_out = parse_coord_system(coord_system_out)
    with np.errstate(invalid='ignore'):
        lon_in, lat_in = convert_world_coordinates(lon_out, lat_out, (coord_system_out, u.deg, u.deg), wcs_in)

    # Look up pixels in input system
    yinds, xinds = wcs_in.wcs_world2pix(lon_in, lat_in, 0)

    # Interpolate

    if isinstance(order, six.string_types):
        order = ORDER[order]

    healpix_data = map_coordinates(data, [xinds, yinds],
                                   order=order,
                                   mode='constant', cval=np.nan)

    return healpix_data, (~np.isnan(healpix_data)).astype(float)