Ejemplo n.º 1
0
    def __init__(self, geo_in, mask_in, C, zs, z_fine):
        """geo_in,mask_in:    Geo objects"""
        self.geo_in = geo_in
        self.mask_in = mask_in
        assert (self.geo_in.angular_area() - self.mask_in.angular_area()) >= 0.

        Geo.__init__(self, zs, C, z_fine)
        l_max = np.min([geo_in._l_max, mask_in._l_max])
        self.expand_alm_table(l_max)
Ejemplo n.º 2
0
    def __init__(self, geo_in, C, zs, z_fine, angles, n_double):
        """geo_in    Geo object"""
        self.geo_in = geo_in
        self.angles = angles
        self.n_double = n_double

        Geo.__init__(self, zs, C, z_fine)
        l_max = geo_in._l_max
        self.expand_alm_table(l_max)
Ejemplo n.º 3
0
 def __init__(self, zs, C, z_fine):
     """create an analytic geo of the full sky
             inputs:
                 zs: the tomographic z bins
                 C: a CosmoPie object
                 z_fine: the resolution z slices
                 l_max: the maximum l to compute the alm table to
                 res_healpix: 4 to 9, healpix resolution to use
     """
     self.C = C
     self.z_fine = z_fine
     Geo.__init__(self, zs, C, z_fine)
Ejemplo n.º 4
0
    def __init__(self,zs,pixels,C,z_fine,l_max,hard_l_max=np.inf):
        """pixelated geomtery
            inputs:
                zs: tomographic z bins
                pixels: pixels in format np.array([(theta,phi,area)]), area in steradians
                C: CosmoPie object
                z_fine: the fine z slices
                hard_l_max: absolute maximum possible l to resolve
        """
        self.pixels = pixels
        self.hard_l_max = hard_l_max


        Geo.__init__(self,zs,C,z_fine)

        self._l_max = 0
        self.alm_table[(0,0)] = np.sum(self.pixels[:,2])/np.sqrt(4.*np.pi)
        self.expand_alm_table(l_max)
Ejemplo n.º 5
0
    def __init__(self, zs, thetas, phis, theta_in, phi_in, C, z_fine, l_max,
                 poly_params):
        """     inputs:
                    zs: the tomographic z bins
                    thetas,phis: an array of theta values for the edges in radians, last value should be first for closure, edges will be clockwise
                    theta_in,phi_in: a theta and phi known to be outside, needed for finding intersect for now
                    C: a CosmoPie object
                    z_fine: the resolution z slices
                    l_max: the maximum l to compute the alm table to
                    poly_params: a dict of parameters
        """

        self.poly_params = poly_params
        self.n_double = poly_params['n_double']
        self.l_max = l_max

        #maximum alm already available, only a00 available at start
        self._l_max = 0
        self.n_v = thetas.size - 1

        self.bounding_theta = thetas - np.pi / 2.  #to radec
        self.bounding_phi = np.pi - phis
        self.bounding_xyz = np.asarray(
            sgv.radec_to_vector(self.bounding_phi,
                                self.bounding_theta,
                                degrees=False)).T
        self.theta_in = theta_in
        self.phi_in = phi_in
        self.thetas_orig = thetas
        self.phis_orig = phis

        #this gets correct internal angles with specified vertex order (copied from spherical_polygon clas)
        angle_body = gca.angle(self.bounding_xyz[:-2],
                               self.bounding_xyz[1:-1],
                               self.bounding_xyz[2:],
                               degrees=False)
        angle_end = gca.angle(self.bounding_xyz[-2],
                              self.bounding_xyz[0],
                              self.bounding_xyz[1],
                              degrees=False)
        self.internal_angles = 2. * np.pi - np.hstack([angle_body, angle_end])

        Geo.__init__(self, zs, C, z_fine)

        self.sp_poly = get_poly(thetas, phis, theta_in, phi_in)
        print("PolygonGeo: area calculated by SphericalPolygon: " +
              str(self.sp_poly.area()))
        print("PolygonGeo: area calculated by PolygonGeo: " +
              str(self.angular_area()) + " sr or " +
              str(self.angular_area() * (180. / np.pi)**2) + " deg^2")

        self.alm_table = {(0, 0): self.angular_area() / np.sqrt(4. * np.pi)}

        self.z_hats = np.zeros((self.n_v, 3))
        self.y_hats = np.zeros_like(self.z_hats)
        self.xps = np.zeros_like(self.z_hats)

        self.betas = np.zeros(self.n_v)
        self.theta_alphas = np.zeros(self.n_v)
        self.omega_alphas = np.zeros(self.n_v)
        self.gamma_alphas = np.zeros(self.n_v)

        for itr1 in range(0, self.n_v):
            itr2 = itr1 + 1
            pa1 = self.bounding_xyz[itr1]  #vertex 1
            pa2 = self.bounding_xyz[itr2]  #vertex 2
            cos_beta12 = np.dot(pa2, pa1)  #cos of angle between pa1 and pa2
            cross_12 = np.cross(pa2, pa1)
            sin_beta12 = np.linalg.norm(cross_12)  #magnitude of cross product
            self.betas[itr1] = np.arctan2(
                sin_beta12, cos_beta12)  #angle between pa1 and pa2
            #angle should be in quadrant expected by arccos because angle should be <pi
            beta_alt = np.arccos(cos_beta12)

            assert np.isclose(sin_beta12, np.sin(self.betas[itr1]))
            assert np.isclose(sin_beta12**2 + cos_beta12**2, 1.)
            assert np.isclose(beta_alt, self.betas[itr1])

            #define z_hat if possible
            if np.isclose(self.betas[itr1], 0.):
                print(
                    "PolygonGeo: side length 0, directions unconstrained, picking directions arbitrarily"
                )
                #z_hat is not uniquely defined here so arbitrarily pick one orthogonal to pa1
                arbitrary = np.zeros(3)
                if not np.isclose(np.abs(pa1[0]), 1.):
                    arbitrary[0] = 1.
                elif not np.isclose(np.abs(pa1[1]), 1.):
                    arbitrary[1] = 1.
                else:
                    arbitrary[2] = 1.
                cross_12 = np.cross(arbitrary, pa1)
                self.z_hats[itr1] = cross_12 / np.linalg.norm(cross_12)
            elif np.isclose(self.betas[itr1], np.pi):
                raise RuntimeError(
                    "PolygonGeo: Spherical polygons with sides of length pi are not uniquely determined"
                )
            else:
                self.z_hats[
                    itr1] = cross_12 / sin_beta12  #direction of cross product

            #three euler rotation angles
            if not (np.isclose(self.z_hats[itr1, 1], 0.)
                    and np.isclose(self.z_hats[itr1, 0], 0.)):
                self.theta_alphas[itr1] = -np.arccos(self.z_hats[itr1, 2])
                y1 = np.cross(self.z_hats[itr1], pa1)
                self.y_hats[itr1] = y1
                assert np.allclose(
                    pa1 * np.cos(self.betas[itr1]) -
                    y1 * np.sin(self.betas[itr1]), pa2)
                assert np.allclose(np.cross(pa1, y1), self.z_hats[itr1])
                self.xps[itr1] = np.array([
                    self.z_hats[itr1][1] * pa1[0] -
                    self.z_hats[itr1][0] * pa1[1],
                    self.z_hats[itr1][1] * y1[0] -
                    self.z_hats[itr1][0] * y1[1], 0.
                ])

                self.gamma_alphas[itr1] = np.arctan2(-self.z_hats[itr1, 0],
                                                     self.z_hats[itr1, 1])
                gamma_alpha2 = np.arctan2(self.z_hats[itr1, 1],
                                          self.z_hats[itr1, 0]) - np.pi / 2.
                assert np.isclose(np.mod(self.gamma_alphas[itr1] + 0.000001,
                                         2. * np.pi),
                                  np.mod(gamma_alpha2 + 0.000001, 2. * np.pi),
                                  atol=1.e-5)
                self.omega_alphas[itr1] = -np.arctan2(self.xps[itr1, 1],
                                                      self.xps[itr1, 0])
            else:
                self.omega_alphas[itr1] = 0.
                self.gamma_alphas[itr1] = np.arctan2(pa1[1], pa1[0])
                #need to handle the case where z||z_hat separately (so don't divide by 0)
                if self.z_hats[itr1, 2] < 0:
                    print("PolygonGeo: setting theta_alpha to pi at " +
                          str(itr1))
                    self.theta_alphas[itr1] = np.pi
                else:
                    print("PolygonGeo: setting theta_alpha to 0 at " +
                          str(itr1))
                    self.theta_alphas[itr1] = 0.

        self.expand_alm_table(l_max)
        print("PolygonGeo: finished initialization")
Ejemplo n.º 6
0
    def __init__(self,
                 geos,
                 masks,
                 C=None,
                 zs=None,
                 z_fine=None,
                 l_max=None,
                 poly_params=None):
        """geo,masks:    an array of PolygonGeo objects"""
        self.geos = geos
        self.masks = masks
        self.n_g = geos.size
        self.n_m = masks.size
        if zs is None:
            zs = geos[0].zs
        if z_fine is None:
            z_fine = geos[0].z_fine
        if C is None:
            C = geos[0].C
        if l_max is None:
            l_max = geos[0].l_max
        if poly_params is None:
            poly_params = geos[0].poly_params

        self.polys_pos = np.zeros(self.n_g, dtype=object)
        self.polys_mask = np.zeros(self.n_m, dtype=object)

        for itr in range(0, self.masks.size):
            if not isinstance(masks[itr], PolygonGeo):
                raise ValueError('unsupported type for mask')
            print(masks[itr].angular_area())
        for itr in range(0, self.geos.size):
            if not isinstance(geos[itr], PolygonGeo):
                raise ValueError('unsupported type for geo')
            print(geos[itr].angular_area())

        for itr in range(0, self.masks.size):
            self.polys_mask[itr] = masks[itr].sp_poly

        self.union_pos = self.geos[0].sp_poly
        for itr in range(1, self.n_g):
            self.union_pos = self.union_pos.union(self.polys_pos[itr])

        self.union_xyz = list(self.union_pos.points)
        self.union_in = list(self.union_pos.inside)
        self.n_union = len(self.union_xyz)
        self.union_geos = np.zeros(self.n_union, dtype=object)

        if self.n_g == 1:
            self.union_geos[0] = self.geos[0]
        else:
            for itr in range(0, self.n_union):
                union_ra, union_dec = sgv.vector_to_radec(
                    self.union_xyz[itr][:, 0],
                    self.union_xyz[itr][:, 1],
                    self.union_xyz[itr][:, 2],
                    degrees=False)
                in_ra, in_dec = sgv.vector_to_radec(self.union_in[itr][0],
                                                    self.union_in[itr][1],
                                                    self.union_in[itr][2],
                                                    degrees=False)
                self.union_geos[itr] = PolygonGeo(zs, union_dec + np.pi / 2.,
                                                  union_ra,
                                                  in_dec + np.pi / 2., in_ra,
                                                  C, z_fine, l_max,
                                                  poly_params)
        if self.n_m > 0:
            #get union of all the masks with the union of the inside, ie the intersection, which is the mask to use
            self.union_mask = self.polys_mask[0]
            for itr1 in range(1, self.n_m):
                self.union_mask = self.union_mask.union(self.polys_mask[itr1])
            #note union_mask can be several disjoint polygons
            #print("mask poly",self.union_mask)
            #print("union pos",self.union_pos)
            self.union_mask = self.union_pos.intersection(self.union_mask)
            self.mask_xyz = list(self.union_mask.points)
            in_point = list(self.union_mask.inside)
            self.n_mask = len(self.mask_xyz)
            self.mask_geos = np.zeros(self.n_mask, dtype=object)
            for itr in range(0, self.n_mask):
                mask_ra, mask_dec = sgv.vector_to_radec(self.mask_xyz[itr][:,
                                                                           0],
                                                        self.mask_xyz[itr][:,
                                                                           1],
                                                        self.mask_xyz[itr][:,
                                                                           2],
                                                        degrees=False)
                in_ra, in_dec = sgv.vector_to_radec(in_point[itr][0],
                                                    in_point[itr][1],
                                                    in_point[itr][2],
                                                    degrees=False)
                self.mask_geos[itr] = PolygonGeo(zs, mask_dec + np.pi / 2.,
                                                 mask_ra, in_dec + np.pi / 2.,
                                                 in_ra, C, z_fine, l_max,
                                                 poly_params)
        else:
            #TODO not right
            self.union_mask = None
            self.mask_geos = None

        #self.sp_poly = self.union_geo

        Geo.__init__(self, zs, C, z_fine)
        self.alm_table = {(0, 0): self.angular_area() / np.sqrt(4. * np.pi)}
        self._l_max = 0
        self.expand_alm_table(l_max)