Exemple #1
0
 def _cone(config, source, nest=True):
     # cone geometry stuff: get corresponding pixels and center vector
     l, b, radius = source.l, source.b, config.radius
     cart = lambda l, b: healpy.dir2vec(l, b, lonlat=True)
     conepix = healpy.query_disc(config.nside,
                                 cart(l, b),
                                 np.radians(radius),
                                 nest=nest)
     center = healpy.dir2vec(l, b, lonlat=True)
     return center, conepix
    def _load_photon_data(self, filename, gti):
        """Read in, process a file generated by binned_data.ConvertFT1.time_record
        
        return DataFrame with times, band id, distance from center
            
        parameters:
            filename : file name
            gti   : GTI object for filtering data

        returns:
            DataFrame with columns:
                band : from input, energy and event type  
                time : Mission Elapsed Time in MJD (double)
                radius : radial distance from input position (deg, float32)
        """       
        l,b,radius = self.l, self.b, self.radius    
        if self.verbose>2:
            print(f'loading file {filename}')  
        with open(filename,'rb') as f:
            d = pickle.load( f ,encoding='latin1')
            tstart = d['tstart']
            if self.mjd_range is not None and MJD(tstart) > self.mjd_range[1]:
                return None
            df = pd.DataFrame(d['timerec'])

        # cartesian vector from l,b for healpy stuff    
        cart = lambda l,b: healpy.dir2vec(l,b, lonlat=True) 

        # use query_disc to get photons within given radius of position
        center = healpy.dir2vec(l,b, lonlat=True) #cart(l,b)
        ipix = healpy.query_disc(self.nside, cart(l,b), np.radians(radius), nest=False)
        incone = np.isin(df.hpindex, ipix)
        
        # times: convert to double, add to start, convert to MJD 
        t = MJD(np.array(df.time[incone],float)+tstart)
        in_gti = gti(t)
        if np.sum(in_gti)==0:
            return None

        # generate  radial distance from center from position 
        hpindex =  df.hpindex[incone][in_gti]           
        ll,bb = healpy.pix2ang(self.nside, hpindex,  nest=False, lonlat=True)
        t2 = np.array(np.sqrt((1.-np.dot(center, cart(ll,bb)))*2), np.float32) 

        out_df = pd.DataFrame(np.rec.fromarrays(
            [df.band[incone][in_gti], t[in_gti], hpindex, np.degrees(t2)], 
            names='band time pixel radius'.split()))

        return out_df
Exemple #3
0
def min_sso_dist(el, azmin, azmax, sso_el1, sso_az1, sso_el2, sso_az2):
    """Return a rough minimum angular distance between the bore sight
    and a solar system object"""
    sso_vec1 = hp.dir2vec(sso_az1, sso_el1, lonlat=True)
    sso_vec2 = hp.dir2vec(sso_az2, sso_el2, lonlat=True)
    az1 = azmin
    az2 = azmax
    if az2 < az1:
        az2 += 360
    n = 100
    az = np.linspace(az1, az2, n)
    el = np.ones(n) * el
    vec = hp.dir2vec(az, el, lonlat=True)
    dist1 = np.degrees(np.arccos(np.dot(sso_vec1, vec)))
    dist2 = np.degrees(np.arccos(np.dot(sso_vec2, vec)))
    return min(np.amin(dist1), np.amin(dist2))
Exemple #4
0
def label_visits(visits, wfd_footprint, nside=64):
    # Set up DD names.
    d = set()
    for p in visits['note'].unique():
        if p.startswith('DD'):
            d.add(define_ddname(p))
    # Define dictionary of proposal tags.
    propTags = {'Other': 0, 'WFD': 1}
    for i, field in enumerate(d):
        propTags[field] = i + 2
    # Identify Healpixels associated with each visit.
    vec = hp.dir2vec(visits['fieldRA'], visits['fieldDec'], lonlat=True)
    vec = vec.swapaxes(0, 1)
    radius = np.radians(1.75)  # fov radius
    #pointings = []
    propId = np.zeros(len(visits), int)
    for i, (v, note) in enumerate(zip(vec, visits['note'])):
        # Identify the healpixels which would be inside this pointing
        pointing_healpix = hp.query_disc(nside, v, radius, inclusive=False)
        # This can be useful for debugging/plotting
        #pointings.append(pointing_healpix)
        # The wfd_footprint consists of values of 0/1 if out/in WFD footprint
        in_wfd = wfd_footprint[pointing_healpix].sum()
        # So in_wfd = the number of healpixels which were in the WFD footprint
        # .. in the # in / total # > limit (0.4) then "yes" it's in WFD
        propId[i] = np.where(in_wfd / len(pointing_healpix) > 0.4,
                             propTags['WFD'], 0)
        # BUT override - if the visit was taken for DD, use that flag instead.
        if note.startswith('DD'):
            propId[i] = propTags[define_ddname(note)]
    return visits, propTags, propId
Exemple #5
0
    def __init__(self, outdir, nside, roi_nside=12, **kwargs):
        self.subdirfun = Band(nside).dir
        disc_info = kwargs.pop('disc_info', ())

        # allow arbitraty disk, rather than just within a ROI active boundary
        if disc_info:
            l, b, r = disc_info
            vec = healpy.dir2vec(l, b, lonlat=True)
            index_list = healpy.query_disc(nside=nside,
                                           vec=vec,
                                           radius=np.radians(r),
                                           nest=False)
            self.pos_list = [self.subdirfun(int(i)) for i in index_list]
        else:
            self.index_table = make_index_table(roi_nside, nside)

        self.skyfuns = kwargs.pop(
            'skyfuns',
            (
                (
                    ResidualTS,
                    'ts',
                    dict(photon_index=2.3),
                ),
                (KdeMap, 'kde', dict()),
            ),
        )
        self.subdirs = [
            os.path.join(outdir, name + '_table_%d' % nside)
            for s, name, kw in self.skyfuns
        ]
        for subdir in self.subdirs:
            if not os.path.exists(subdir): os.makedirs(subdir)
Exemple #6
0
def TopHatSmooth(nside, origMap, radius, average=False):
    pixelList = []
    dsum = 0.0
    newmap = np.zeros(len(origMap))

    # Loop over all pixels
    for ipix in range(0, len(origMap)):
        theta, phi = H.pix2ang(nside, ipix)
        center = H.dir2vec(theta, phi)

        # Grab pixels with given angular radius of ith pixel
        pixelList = H.query_disc(nside, center, radius)

        #Sum up pixels in the angular cap; set value of ith pixel to this sum
        dsum = 0.
        nsum = 0.
        for jpix in pixelList:
            if origMap[jpix] != H.UNSEEN:
                dsum += origMap[jpix]
                nsum += 1.0

        if average and nsum > 0:
            newmap[ipix] = dsum / nsum  # set to average
        else:
            newmap[ipix] = dsum
    return newmap
    def cosdist_vec(self, vec, timestamps, full_output=False):
        """
        Return the cosine of the angular distance between the target
        and pointing direction
        """
        if timestamps[0] > self.time[-1] or timestamps[-1] < self.time[0]:
            raise Exception(
                'There is no overlap in the stored and provided time stamps.')

        tol = 3600.
        ind = np.logical_and(self.time >= timestamps[0] - tol,
                             self.time <= timestamps[-1] + tol)

        planettime = self.time[ind]
        planetglon_temp = self.glon[ind]
        planetglat_temp = self.glat[ind]

        planetglon = np.interp(timestamps, planettime, planetglon_temp)
        planetglat = np.interp(timestamps, planettime, planetglat_temp)

        planetvec = hp.dir2vec(planetglon, planetglat, lonlat=True)
        cosdist = np.sum(vec * planetvec, axis=0)

        if full_output:
            return cosdist, planetvec
        else:
            return cosdist
Exemple #8
0
 def generate_point_set(self) -> Tuple[np.ndarray, np.ndarray]:
     rng = np.random.default_rng(self.seed)
     lon = 360 * rng.random(size=self.resolution) - 180
     uniform = rng.random(size=self.resolution)
     lat = np.arcsin(2 * uniform - 1) * 180 / np.pi
     vec = hp.dir2vec(theta=lon, phi=lat, lonlat=True)
     dir = hp.vec2dir(vec, lonlat=self.lonlat)
     return vec, dir
Exemple #9
0
 def generate_point_set(self) -> Tuple[np.ndarray, np.ndarray]:
     step = np.arange(self.resolution)
     phi = step * self.golden_angle
     phi = Angle(phi * u.rad).wrap_at(2 * np.pi * u.rad)
     theta = np.arccos(1 - (2 * step / self.resolution))
     vec = hp.dir2vec(theta=theta, phi=phi, lonlat=False)
     dir = hp.vec2dir(vec, lonlat=self.lonlat)
     return vec, dir
Exemple #10
0
def get_tiling(lon0, lat0, dlon, dlat):
    rot = hp.rotator.Rotator(rot=(0., -lat0, -lon0), eulertype='Y',
                             deg=True).mat
    x = hp.dir2vec(dlon, dlat, lonlat=True)
    if hasattr(dlon, '__len__') and (len(x.shape) == 1):
        x.shape = (3, 1)
    y = np.einsum('ij,jn', rot, x)
    lonlat = hp.vec2dir(y, lonlat=True)
    return lonlat
Exemple #11
0
def A_wrt_dir(map1, direction, LMAX, LMIN=2, deg=90.):
    """
    get the Cl power asymmetry wrt to the direction specified
    """
    if len(direction) == 2:
        direction = hp.dir2vec(direction[0], direction[1], lonlat=True)

    Clsp, Clsm = get_hem_Cls(map1, direction, LMAX, deg)
    return weightedA(Clsp[LMIN:], Clsm[LMIN:])
Exemple #12
0
def get_tiling(lon0, lat0, dlon, dlat):
    rot = hp.rotator.Rotator(rot=(0., -lat0, -lon0),
                             eulertype='Y',
                             deg=True).mat
    x = hp.dir2vec(dlon, dlat, lonlat=True)
    if hasattr(dlon, '__len__') and (len(x.shape) == 1):
        x.shape = (3,1)
    y = np.einsum('ij,jn', rot, x)
    lonlat = hp.vec2dir(y, lonlat=True)
    return lonlat
Exemple #13
0
 def solid_angle(self):
     sd = self.skydir
     try:
         nside = self.cband.nside()
         npix = len(
             healpy.query_disc(nside,
                               healpy.dir2vec(sd.l(), sd.b(), lonlat=True),
                               self.radius_in_rad))
         return npix * self.pixel_area
     except ValueError:
         return np.pi * self.radius_in_rad**2
Exemple #14
0
def RADECToPatch(nside,
                 RA,
                 DEC=None,
                 nest=False,
                 lonlat=True,
                 invRotMat=np.diag(np.ones(3))):
    if DEC is None:
        DEC = RA[1]
        RA = RA[0]
    uXYZ = hp.dir2vec(RA, DEC, lonlat=lonlat)
    uXYZ = invRotMat.dot(uXYZ)
    patch = hp.vec2pix(nside, uXYZ[0], uXYZ[1], uXYZ[2], nest=nest)
    return patch
Exemple #15
0
def radec_to_vec(ra, dec):

    assert 0 <= ra <= 360
    assert -90 <= dec <= 90

    # Healpix uses the convention -180 - 180 for longitude, instead
    # we get RA between 0 and 360, so we need to wrap
    wrap_angle = 180.0

    lon = np.mod(ra - wrap_angle, 360.0) - (360.0 - wrap_angle)

    vec = hp.dir2vec(lon, dec, lonlat=True)

    return vec
Exemple #16
0
    def initialize(self, force=False):
        if self.setup and not force: return
        self.setup = True
        #set up the spatial model
        self.dmodel = self.source.dmodel[self.band.event_type]
        self.dmodel.load()
        self.energy = self.band.energy
        self.dmodel.setEnergy(self.band.energy)

        roi_index = skymaps.Band(12).index(self.roicenter)
        self._keyword_check(roi_index)
        if getattr(self, 'preconvolved', False):
            #print 'Using preconvolved'
            c = self.roicenter
            cv = healpy.dir2vec(c.l(), c.b(), lonlat=True)
            hplist = healpy.query_disc(self.dmodel.nside, cv,
                                       self.band.radius_in_rad)
            smband = skymaps.Band(self.dmodel.nside)
            assert smband.index(
                self.roicenter
            ) in hplist, 'Problem HEALPix indexing, ROI center not consistent?'

            if self.dmodel.hdulist[1].header.get('TUNIT1', None) == 'photons':
                #must rescale from photons/pixel to density: photons/Mev/Sr
                scale_factor = (self.band.emax -
                                self.band.emin) * smband.pixelArea()
            else:
                scale_factor = 1

            dirs = map(self.dmodel.dirfun, hplist)
            self.evalpoints = lambda dirs: np.array(map(
                self.dmodel, dirs)) * self.corr / scale_factor
            self.ap_average = self.evalpoints(dirs).mean()
            # **** scale by years ****
            self.ap_average *= self.years / 10.

        else:
            self.create_grid()  # will raise exception if no overlap
            grid = self.grid
            inside = grid.dists < self.band.radius_in_rad
            self.ap_average = grid.cvals[inside].mean()
            self.evalpoints = lambda dirs: grid(dirs, grid.cvals)

        self.delta_e = self.band.emax - self.band.emin
        self.factor = self.ap_average * self.band.solid_angle * self.delta_e
        if self.band.has_pixels:
            self.pixel_values = self.evalpoints(
                self.band.wsdl) * self.band.pixel_area * self.delta_e

        self.evaluate()
    def cosdist(self, theta, phi, timestamps):
        """
        Return the cosine of the angular distance between the target
        and pointing direction (theta, phi)
        Inputs are in radians.
        """

        if theta.ptp() > np.pi or phi.ptp() > 4 * np.pi:
            print('WARNING: theta and/or phi have large scatter. '
                  'They are expected to be in radians.')

        vec = hp.dir2vec(theta, phi)
        cosdist = self.cosdist_vec(vec, timestamps)

        return cosdist
Exemple #18
0
    def make_weights(self, ):
        if self.verbose > 0:
            print 'Generating pixels with weights for {} energies'.format(
                len(self.energy_bins))
        # direection of source

        source_dir = self.source.skydir
        source_index = self.roi.sources.selected_source_index

        def weight(band, skydir):
            f = band.fluxes(skydir)  # fluxes for all sources at the position
            return f[source_index] / sum(f)

        # use query_disc to get NEST pixel numbers within given radius of position
        # order them for easier search later
        l, b = source_dir.l(), source_dir.b()
        center = healpy.dir2vec(l, b, lonlat=True)
        pix_nest = np.sort(
            healpy.query_disc(self.nside,
                              center,
                              np.radians(self.radius),
                              nest=True))

        # convert to skydirs using pointlike code, which assumes RING
        bdir = Band(self.nside).dir
        pix_ring = healpy.nest2ring(self.nside, pix_nest)
        pixel_dirs = map(bdir, pix_ring)

        # and get distances
        pixel_dist = np.array(map(source_dir.difference, pixel_dirs))
        if self.verbose > 0:
            print 'Using {} nside={} pixels.  distance range {:.2f} to {:.2f} deg'.format(
                len(pix_nest), self.nside, np.degrees(pixel_dist.min()),
                np.degrees(pixel_dist.max()))

        # now loop over the bands and all pixels
        wt_dict = dict()
        for band in self.roi:  # loop over BandLike objects
            ie = np.searchsorted(self.energy_bins, band.band.energy) - 1

            band_id = 2 * ie + band.band.event_type
            if self.verbose > 1:
                print '{}'.format(band_id),
            wt_dict[band_id] = np.array(
                [weight(band, pd) for pd in pixel_dirs]).astype(np.float32)
        if self.verbose > 1: print

        return pix_nest, wt_dict
        def load_photon_data(table, tstart):
            """For a given month table, select photons in cone, add tstart to times, 
            return DataFrame with band, time, pixel, radius
            """
            allpix = np.array(table.column('nest_index'))
   

            def cone_select(allpix, conepix, shift=None):
                """Fast cone selection using NEST and shift
                """
                if shift is None:
                    return np.isin(allpix, conepix)
                assert self.nest, 'Expect pixels to use NEST indexing'
                a = np.right_shift(allpix, shift)
                c = np.unique(np.right_shift(conepix, shift))
                return np.isin(a,c)

            
            # a selection of all those in an outer cone
            incone = cone_select(allpix, conepix, 13)

            # times: convert to double, add to start, convert to MJD 
            time = MJD(np.array(table['time'],float)[incone]+tstart)
            in_gti = self.gti(time)
            if np.sum(in_gti)==0:
                print(f'WARNING: no photons for month {month}!')

            pixincone = allpix[incone][in_gti]
            
            # distance from center for all accepted photons
            ll,bb = healpy.pix2ang(self.nside, pixincone,  nest=self.nest, lonlat=True)
            cart = lambda l,b: healpy.dir2vec(l,b, lonlat=True) 
            t2 = np.degrees(np.array(np.sqrt((1.-np.dot(center, cart(ll,bb)))*2), np.float32)) 

            # assemble the DataFrame, remove those outside the radius
            out_df = pd.DataFrame(np.rec.fromarrays(
                [np.array(table['band'])[incone][in_gti], time[in_gti], pixincone, t2], 
                names='band time pixel radius'.split()))
            
            # apply final selection for radius and energy range
         
            if band_limits is None: return out_df.query(f'radius<{radius}')
            
            return out_df.query(f'radius<{radius} & {band_limits[0]} < band < {band_limits[1]}')
Exemple #20
0
def hp_in_cap(nside, radecrad, inclusive=True, fact=4):
    """Determine which HEALPixels touch an RA, Dec, radius cap.

    Parameters
    ----------
    nside : :class:`int`
        (NESTED) HEALPixel nside.
    radecrad : :class:`list`, defaults to `None`
        3-entry list of coordinates [ra, dec, radius] forming a cap or
        "circle" on the sky. ra, dec and radius are all in degrees.
    inclusive : :class:`bool`, optional, defaults to ``True``
        see documentation for `healpy.query_disc()`.
    fact : :class:`int`, optional defaults to 4
        see documentation for `healpy.query_disc()`.

    Returns
    -------
    :class:`list`
        A list of HEALPixels at the passed `nside` that touch the cap.

    Notes
    -----
        - Just syntactic sugar around `healpy.query_disc()`.
    """
    ra, dec, radius = radecrad

    # ADM RA/Dec to co-latitude/longitude, everything to radians.
    theta, phi, rad = np.radians(90. - dec), np.radians(ra), np.radians(radius)

    # ADM convert the colatitudes to Cartesian vectors remembering to
    # ADM transpose to pass the array to query_disc in the correct order.
    vec = hp.dir2vec(theta, phi).T

    # ADM determine the pixels that touch the box.
    pixnum = hp.query_disc(nside,
                           vec,
                           rad,
                           inclusive=inclusive,
                           fact=fact,
                           nest=True)

    return pixnum
Exemple #21
0
    def select(self, l, b, radius=5, nside=1024):
        """create DataFrame with times, band id, distance from center
            
        parameters:
            l,b : position in Galactic 
            radius : cone radius, deg
            nside : for healpy

        returns:
            DataFrame with columns:
                band : from input, energy and event type  
                time : Mission Elapsed Time in s. (double)
                delta : distance from input position (deg, float32)
        """
        df = self.df
        cart = lambda l, b: healpy.dir2vec(l, b, lonlat=True)
        # use query_disc to get photons within given radius of position
        center = cart(l, b)
        ipix = healpy.query_disc(nside,
                                 cart(l, b),
                                 np.radians(radius),
                                 nest=False)
        incone = np.isin(self.df.hpindex, ipix)

        # times: convert to double, add to start
        t = np.array(df.time[incone], float) + self.tstart

        # convert position info to just distance from center
        ll, bb = healpy.pix2ang(nside,
                                self.df.hpindex[incone],
                                nest=False,
                                lonlat=True)
        t2 = np.array(np.sqrt((1. - np.dot(center, cart(ll, bb))) * 2),
                      np.float32)

        return pd.DataFrame(
            np.rec.fromarrays(
                [df.band[incone], t, np.degrees(t2)],
                names='band time delta'.split()))
Exemple #22
0
def radii2mask(nside, centers, radii, inclusive=True, fact=4, ordering='ring'):
    """ Gives an array of pixels included in a list of centers and a radius.
    
    Arguments:
        nside (int): Nside of the map.
        centers (tuple of two np.arrays): The theta, phi coordinates of the
            centers.
        radii (np.array of same size as the arrays in centers): The radii, in
            radians, of the circles around the centers that we want to mask.
        inclusive (bool): If False, mask the exact set of pixels whose pixel
            centers lie within the disk; if True, mask all pixels that overlap
            with the disk, perhaps a few more.
        fact (integer): Only used when inclusive=True. The overlapping test
            will be done at the resolution fact*nside.
        ordering (string): 'ring' or 'nested'.

    Returns:
        Array of booleans where the specified circles are masked out.
    """

    centers_vecs = healpy.dir2vec(centers, lonlat=True)

    mask = np.ones(12 * nside**2, dtype=np.bool)

    num = 0
    if ordering == 'ring':
        nest = False
    elif ordering == 'nested':
        nest = True
    for center, radius in zip(centers_vecs.transpose(), radii):
        if radius == 0:
            continue
        mask[healpy.query_disc(nside,
                               center,
                               radius,
                               inclusive=inclusive,
                               fact=fact,
                               nest=nest)] = 0
    return mask
Exemple #23
0
    def initialize(self, force=False):
        if self.setup or force: return
        self.setup = True
        #set up the spatial model
        self.dmodel = self.source.dmodel[self.band.event_type]
        self.dmodel.load()
        self.energy = self.band.energy
        self.dmodel.setEnergy(self.band.energy)

        roi_index = skymaps.Band(12).index(self.roicenter)
        self._keyword_check(roi_index)
        if getattr(self, 'preconvolved', False):
            #print 'Using preconvolved'
            c = self.roicenter
            cv = healpy.dir2vec(c.l(), c.b(), lonlat=True)
            hplist = healpy.query_disc(self.dmodel.nside, cv,
                                       self.band.radius_in_rad)
            assert skymaps.Band(self.dmodel.nside).index(
                self.roicenter) in hplist
            dirs = map(self.dmodel.dirfun, hplist)
            self.evalpoints = lambda dirs: np.array(map(self.dmodel, dirs)
                                                    ) * self.corr
            self.ap_average = self.evalpoints(dirs).mean()

        else:
            self.create_grid()  # will raise exception if no overlap
            grid = self.grid
            inside = grid.dists < self.band.radius_in_rad
            self.ap_average = grid.cvals[inside].mean()
            self.evalpoints = lambda dirs: grid(dirs, grid.cvals)

        self.delta_e = self.band.emax - self.band.emin
        self.factor = self.ap_average * self.band.solid_angle * self.delta_e
        if self.band.has_pixels:
            self.pixel_values = self.evalpoints(
                self.band.wsdl) * self.band.pixel_area * self.delta_e

        self.evaluate()
Exemple #24
0
def radec_to_vec(ra, dec):

    assert 0 <= ra <= 360
    assert -90 <= dec <= 90

    # Healpix uses the convention -180 - 180 for longitude, instead
    # we get RA between 0 and 360, so we need to wrap
    wrap_angle = 180.0

    lon = np.mod(ra - wrap_angle, 360.0) - (360.0 - wrap_angle)

    vec = hp.dir2vec(lon, dec, lonlat=True)

    return vec


# def pixid_to_radec(nside, pixid, nest=False):
#
#     theta, phi = hp.pix2ang(nside, pixid, nest=nest, lonlat=False)
#
#     ra = np.rad2deg(phi)
#     dec = np.rad2deg(0.5 * np.pi - theta)
#
#     return ra, dec
Exemple #25
0
def hp_in_box(nside, radecbox, inclusive=True, fact=4):
    """Determine which HEALPixels touch an RA, Dec box.

    Parameters
    ----------
    nside : :class:`int`
        (NESTED) HEALPixel nside.
    radecbox : :class:`list`
        4-entry list of coordinates [ramin, ramax, decmin, decmax]
        forming the edges of a box in RA/Dec (degrees).
    inclusive : :class:`bool`, optional, defaults to ``True``
        see documentation for `healpy.query_polygon()`.
    fact : :class:`int`, optional defaults to 4
        see documentation for `healpy.query_polygon()`.

    Returns
    -------
    :class:`list`
        HEALPixels at the passed `nside` that touch the RA/Dec box.

    Notes
    -----
        - Uses `healpy.query_polygon()` to retrieve the RA geodesics
          and then :func:`hp_in_dec_range()` to limit by Dec.
        - When the RA range exceeds 180o, `healpy.query_polygon()`
          defines the range as that with the smallest area (i.e the box
          can wrap-around in RA). To avoid any ambiguity, this function
          will only limit by the passed Decs in such cases.
        - Only strictly correct for Decs from -90+1e-5(o) to 90-1e5(o).
    """
    ramin, ramax, decmin, decmax = radecbox

    # ADM area enclosed isn't well-defined if RA covers more than 180o.
    if np.abs(ramax - ramin) <= 180.:
        # ADM retrieve RA range. The 1e-5 prevents edge effects near poles.
        npole, spole = 90 - 1e-5, -90 + 1e-5
        # ADM convert RA/Dec to co-latitude and longitude in radians.
        rapairs = np.array([ramin, ramin, ramax, ramax])
        decpairs = np.array([spole, npole, npole, spole])
        thetapairs, phipairs = np.radians(90. - decpairs), np.radians(rapairs)

        # ADM convert to Cartesian vectors remembering to transpose
        # ADM to pass the array to query_polygon in the correct order.
        vecs = hp.dir2vec(thetapairs, phipairs).T

        # ADM determine the pixels that touch the RA range.
        pixra = hp.query_polygon(nside,
                                 vecs,
                                 inclusive=inclusive,
                                 fact=fact,
                                 nest=True)
    else:
        log.warning(
            'Max RA ({}) and Min RA ({}) separated by > 180o...'.format(
                ramax, ramin))
        log.warning('...will only limit to passed Declinations'.format(nside))
        pixra = np.arange(hp.nside2npix(nside))

    # ADM determine the pixels that touch the Dec range.
    pixdec = hp_in_dec_range(nside, decmin, decmax, inclusive=inclusive)

    # ADM return the pixels in the box.
    pixnum = list(set(pixra).intersection(set(pixdec)))

    return pixnum
Exemple #26
0
from matplotlib import pyplot  # ***
import numpy as np

fontsize = 20
matplotlib.rcParams.update({'font.size': fontsize})

#%%
"""
STEP 2: Angular distances
"""

# Virgo cluster:::

lon = 283.8
lat = 74.4
vec = hp.dir2vec(lon, phi=lat, lonlat=True)

# Distance from Virgo to Coma:::

lon_c = 235.1
lat_c = 73.0

vec_c = hp.dir2vec(lon_c, phi=lat_c, lonlat=True)

distance = hp.rotator.angdist(vec, vec_c, lonlat=True)
print('Distance: ', distance)

#%%
"""
STEP 3: Rotation
"""
    def _process_data(self, dummy1, dummy2): 
        import pyarrow.parquet as pq

        # cone geometry stuff: get corresponding pixels and center vector
        l,b,radius = self.l, self.b, self.radius  
        cart = lambda l,b: healpy.dir2vec(l,b, lonlat=True) 
        conepix = healpy.query_disc(self.nside, cart(l,b), np.radians(radius), nest=self.nest)
        center = healpy.dir2vec(l,b, lonlat=True)
        
        ebins = self.energy_edges
        ecenters = np.sqrt(ebins[:-1]*ebins[1:]); 
        band_limits = 2*np.searchsorted(ecenters, self.energy_range) if self.energy_range is not None else None
        
        def load_photon_data(table, tstart):
            """For a given month table, select photons in cone, add tstart to times, 
            return DataFrame with band, time, pixel, radius
            """
            allpix = np.array(table.column('nest_index'))
   

            def cone_select(allpix, conepix, shift=None):
                """Fast cone selection using NEST and shift
                """
                if shift is None:
                    return np.isin(allpix, conepix)
                assert self.nest, 'Expect pixels to use NEST indexing'
                a = np.right_shift(allpix, shift)
                c = np.unique(np.right_shift(conepix, shift))
                return np.isin(a,c)

            
            # a selection of all those in an outer cone
            incone = cone_select(allpix, conepix, 13)

            # times: convert to double, add to start, convert to MJD 
            time = MJD(np.array(table['time'],float)[incone]+tstart)
            in_gti = self.gti(time)
            if np.sum(in_gti)==0:
                print(f'WARNING: no photons for month {month}!')

            pixincone = allpix[incone][in_gti]
            
            # distance from center for all accepted photons
            ll,bb = healpy.pix2ang(self.nside, pixincone,  nest=self.nest, lonlat=True)
            cart = lambda l,b: healpy.dir2vec(l,b, lonlat=True) 
            t2 = np.degrees(np.array(np.sqrt((1.-np.dot(center, cart(ll,bb)))*2), np.float32)) 

            # assemble the DataFrame, remove those outside the radius
            out_df = pd.DataFrame(np.rec.fromarrays(
                [np.array(table['band'])[incone][in_gti], time[in_gti], pixincone, t2], 
                names='band time pixel radius'.split()))
            
            # apply final selection for radius and energy range
         
            if band_limits is None: return out_df.query(f'radius<{radius}')
            
            return out_df.query(f'radius<{radius} & {band_limits[0]} < band < {band_limits[1]}')

        # get the monthly-partitioned dataset and tstart values
        dataset = self.photon_data_source['dataset']
        tstart_dict= self.photon_data_source['tstart_dict']
        months = tstart_dict.keys() 

        if self.verbose>0: 
            print(f'Loading data from {len(months)} months from Arrow dataset {dataset}\n', end='')
       
        dflist=[] 
        for month in months:
            table= pq.read_table(dataset, filters=[f'month == {month}'.split()])
            tstart = tstart_dict[month]
            d = load_photon_data(table, tstart)
            if d is not None:
                dflist.append(d)
                if self.verbose>1: print('.', end='')
            else:
                if self.verbose>1: print('x', end='')
                continue

        assert len(dflist)>0, '\nNo photon data found?'
        df = pd.concat(dflist, ignore_index=True)
        if self.verbose>0:
            emin,emax = self.energy_range or (self.energy_edges[0],self.energy_edges[-1])
            print(f'\n\tSelected {len(df)} photons within {self.radius}'\
                  f' deg of  ({self.l:.2f},{self.b:.2f})')
            print(f'\tEnergies: {emin:.1f}-{emax:.0f} MeV')
            ta,tb = df.iloc[0].time, df.iloc[-1].time
            print(f'\tDates:    {UTC(ta):16} - {UTC(tb)}'\
                f'\n\tMJD  :    {ta:<16.1f} - {tb:<16.1f}')  
        return df  
    for OPENING_ANGLE in [20, 40, 60]:
        hit = hp.ma(np.zeros(hp.nside2npix(NSIDE)))
        for day in range(1, 31):

            # In[6]:
            print(day)

            pointing = pd.read_hdf("zenith_pointing_%s.h5" % LOCATION.lower(), "data")["2015-08-%02d" % day]

            # I can define `z` as the axis of the telescope, `x` as defining the plane of the direction of view and `y` as the vector of polarization sensitivity for a fixed altitiude mount.

            # In[7]:

            vec = hp.dir2vec(
                             np.degrees(pointing.ra_zenith_rad), 
                             np.degrees(pointing.dec_zenith_rad), lonlat=True).T


            # In[8]:

            vec_north = hp.dir2vec(
                             np.degrees(pointing.ra_north_rad), 
                             np.degrees(pointing.dec_north_rad), lonlat=True).T


            # In[9]:

            x = np.array([1,0,0])
            y = np.array([0,1,0])
            z = np.array([0,0,1])
Exemple #29
0
 def qdisk(nside, glon, glat, radius):
     return healpy.query_disc(nside,
                              healpy.dir2vec(glon, glat, lonlat=True),
                              np.radians(radius))
Exemple #30
0
"""
STEP 3: Angles <--> Vec
"""
theta = np.deg2rad(45.) # rad
phi   = np.deg2rad(30.) # rad

vec = hp.ang2vec(theta,phi)
vec
print('(theta,phi) = (',theta,',',phi,') --> (x,y,z)=', vec)

theta_phi = hp.vec2ang(vec)
theta_phi
print('(x,y,z)=', vec,' --> (theta,phi) = (',theta_phi,')')


hp.dir2vec(theta, phi=phi)

#%%
"""
STEP 4: Angles <--> Vec ::OR:: Dir <--> Vec
"""

# vec2dir and dir2vec are very similar to vec2ang and ang2vec
# Which are the difference???

# Create a theta,phi list:
nside = 64
npix = hp.nside2npix(nside)
pixels = np.arange(npix)
theta_phi = hp.pix2ang(nside, pixels)
Exemple #31
0
a2, b2 = (0. - 0.2) / 0.12, (1 - 0.2) / 0.12
a3, b3 = (0 - 10.97) / 3.80, (25. - 10.97) / 3.8
a4, b4 = (0 - 2.84) / 1.3, (8 - 2.84) / 1.3

E = float(sys.argv[1])
lon = float(sys.argv[2])
lat = float(sys.argv[3])
s1 = int(sys.argv[4])
s2 = int(sys.argv[5])
s3 = int(sys.argv[6])

pid = -crp.nucleusId(1, 1)
sun = crp.Vector3d(-8.5, 0, 0) * crp.kpc

E = E * crp.EeV
nhat = hp.dir2vec(lon, lat, lonlat=True)
direc = crp.Vector3d()
direc.setXYZ(nhat[0], nhat[1], nhat[2])

ps = crp.ParticleState(pid, E, sun, direc)
cr = crp.Candidate(ps)
sim = crp.ModuleList()
sim.add(crp.Redshift())
sim.add(crp.PhotoPionProduction(crp.CMB))
sim.add(crp.PhotoPionProduction(crp.IRB))
sim.add(crp.PhotoDisintegration(crp.CMB))
sim.add(crp.PhotoDisintegration(crp.IRB))
sim.add(crp.NuclearDecay())
sim.add(crp.ElectronPairProduction(crp.CMB))
sim.add(crp.ElectronPairProduction(crp.IRB))
np.random.seed(s1)
Exemple #32
0
    def __init__(self,
                 names=['hard', 'flat', 'soft', 'peaked', 'psr'],
                 outdir='.',
                 tname='all',
                 nside=nside,
                 roi_nside=12,
                 fill=np.nan,
                 disc=()):
        """ combine the tables generarated at each ROI

        names : names to give the columns, 
        nside : nside parameter that the table was generated with, default 512 (or 256)
        tname : name of the table, default 'all'
        fill  : scalar, defaul NaN
            Use to fill missing tables, if any (warning issued)
        disc  : tuple of (l,b,r) to specify a disc 
        """
        self.names = names
        folder = '%s_table_%d' % (tname, nside)
        if os.path.exists('%s.zip' % folder):
            z = zipfile.ZipFile('%s.zip' % folder)
            files = sorted(z.namelist())  # skip  folder?
            opener = z.open
        else:
            if not os.path.exists(folder):
                raise Exception('Did not find zip file %s.zip or folder  %s' %
                                (folder, folder))
            opener = open
            files = sorted(glob.glob(os.path.join(outdir, folder, '*.pickle')))
        nf = len(files)
        assert nf > 0, 'no pickle files found in %s' % os.path.join(
            outdir, folder)
        if nf < 1728:
            print 'warning: missing %d files in folder %s_table; will fill with %s' % (
                (1728 - nf), tname, fill)

        mvec = np.zeros((12 * nside**2, len(names)))
        mvec.fill(fill)
        pklist = [pickle.load(opener(f)) for f in files]
        if disc:
            # special for a single disc -- kluge a special inndex_table
            l, b, r = disc
            vec = healpy.dir2vec(l, b, lonlat=True)
            index_table = [
                healpy.query_disc(nside=nside,
                                  vec=vec,
                                  radius=np.radians(r),
                                  nest=False)
            ]
            i12 = [0]
        else:
            index_table = make_index_table(roi_nside, nside)
            i12 = [int(f[-11:-7]) for f in files]

        for index, pk in zip(i12, pklist):
            indeces = index_table[index]
            for i, v in enumerate(pk):
                mvec[indeces[i]] = v
        bad = sum(mvec == fill)
        if np.any(bad) > 0:
            print 'WARNING: %d pixels not filled in table %s' % (bad, tname)
        else:
            print 'Table "{}" Filled with columns {}'.format(tname, names)
        self.mvec = mvec