Пример #1
0
def test_sep_against_slalib_dsep():
    """Results from sep should match those from slalib.dsep"""
    # Random positions.
    import random
    import math
    random.seed(12345)
    alpha = [random.uniform(0, 2 * math.pi) for i in range(100)]
    delta = [random.uniform(-math.pi / 2, math.pi / 2) for i in range(100)]

    alpha1 = [random.uniform(0, 2 * math.pi) for i in range(100)]
    delta1 = [random.uniform(-math.pi / 2, math.pi / 2) for i in range(100)]

    # Code used to generate result from pyslalib:
    # s = [slalib.sla_dsep(alpha[i], delta[i], alpha1[i], delta1[i])
    #      for i in range(100)]
    s = [
        2.3488832415605776, 1.1592942993972908, 1.6727782224088137,
        1.9310273037619246, 1.961534390837681, 1.5150119839396818,
        1.8524526916856978, 2.116947088206131, 0.9750943461637399,
        0.8331152895856854, 2.4690444308150243, 0.8640444988019701,
        1.041460475452765, 1.9245098805162162, 2.7727507743449507,
        1.1760229988483686, 1.6418575515189582, 1.0798127458770757,
        2.705734045454533, 2.711202832152844, 2.4387778718976763,
        0.1675761464872016, 0.7614806222975763, 1.7781491597763561,
        2.029672021455121, 2.4349201303097403, 1.2603565818807192,
        2.05499965347367, 0.6224811898002452, 0.8126836325942026,
        0.7539982342941834, 1.6809458707673535, 1.975972151791415,
        0.7115429070168364, 1.8079386355215084, 0.7830659699492306,
        1.233553087948177, 2.08588792306906, 0.2779525335855478,
        1.458433197949138, 1.2964042308707935, 1.117425142370921,
        1.6383665060581982, 0.21787615812753383, 1.6859098755220057,
        1.2253004206853584, 1.472817142187865, 0.6648294675219921,
        2.982945161877018, 0.45704974384275243, 1.1584539180661326,
        2.8484175031722643, 1.0402706684988297, 0.7079258905264588,
        0.7808758533750498, 0.5608700573233222, 1.8505539643075692,
        2.494182944528214, 0.8296145526473544, 2.2901089789186297,
        1.7477923358131886, 2.1499080375112816, 1.1529753011873909,
        1.807265859808323, 2.5770854449349865, 1.172037115203078,
        2.7438561146081937, 0.2216663532818151, 1.4502352305471127,
        2.2334298247493645, 1.9946613229884687, 1.1362010677143621,
        0.9530063759328101, 0.6782653608813761, 0.9421358945224116,
        1.970340302154089, 0.31583484463019296, 0.5945806070431309,
        1.9894690263497685, 0.5114702873070847, 3.059530134272125,
        0.09988794964432562, 2.1732721685109437, 2.054896439114964,
        1.0130957019858804, 1.6899941268950893, 1.4002698103226345,
        1.3736478209061835, 1.7281316524003778, 1.7041224372124824,
        2.7245561902753233, 1.676900403298997, 0.5940433957880709,
        2.4371934329915814, 2.189360172634095, 1.127368860507556,
        0.49285131033236657, 2.6159861791852204, 0.878592556336548,
        2.875063431097953
    ]

    s1 = [
        sep(a1, b1, a2, b2)
        for a1, b1, a2, b2 in zip(alpha, delta, alpha1, delta1)
    ]
    d = [i - j for i, j in zip(s, s1)]

    assert abs(min(d)) <= 1e-8
    assert abs(max(d)) <= 1e-8
Пример #2
0
def getSeparation(x1: float, y1: float, x2: float, y2: float, z: float,
                  mode: str) -> float:
    """Returns angular separation between two angles on a unit sphere.

    :param x1:
    :param y1:
    :param x2:
    :param y2:
    :param z: depth, in mm
    :param mode: whether coordinates are passed in mm or degrees
    :return: angle in degrees
    """
    if mode == 'fromCartesian':
        lon1 = cmath.polar(complex(x1, z))[1] - math.pi / 2
        lat1 = cmath.polar(complex(y1, z))[1] - math.pi / 2
        lon2 = cmath.polar(complex(x2, z))[1] - math.pi / 2
        lat2 = cmath.polar(complex(y2, z))[1] - math.pi / 2

        sep = angles.sep(lon1, lat1, lon2, lat2)
    elif mode == 'fromPolar':
        sep = angles.sep(math.radians(x1), math.radians(y1), math.radians(x2),
                         math.radians(y2))

    return math.degrees(sep)
Пример #3
0
    def convolve(self, x, y, z, inweight):
        """
        convolve a measurement onto a range of grid coordinates
        """
        nwidth = int(4.1 * self.FWHM * self.dpi)

        ix = self.ii(x)
        jy = self.jj(y)
        x0 = angles.d2r(x)  # convert to radians
        if x0 < self.xminrad:
            x0 = x0 + (2. * np.pi)
        elif x0 > self.xmaxrad:
            x0 = x0 - (2. * np.pi)
        y0 = angles.d2r(y)

        for iii in range(-nwidth, nwidth):
            iix = ix + iii
            if iix < 0:
                iix = self.img_width + iix
            elif iix >= self.img_width:
                iix = iix - self.img_width
            xx = self.xx(iix)
            rx = angles.d2r(xx)  # convert to radians

            for jjj in range(-nwidth, nwidth):
                jjy = jy + jjj
                if jjy < 0:
                    jjy = self.img_height + jjy
                elif jjy >= self.img_height:
                    jjy = jjy - self.img_height
                yy = self.yy(jjy)
                ry = angles.d2r(yy)  # conver to radians

                if ry < self.yminrad:
                    ry = ry + (2. * np.pi)
                elif ry > self.ymaxrad:
                    ry = ry - (2. * np.pi)

                # finally get angular separation in degrees
                r = angles.r2d(angles.sep(x0, y0, rx, ry))
                #                if r > 4.*self.FWHM:  # round convolving function
                if r > 3. * self.FWHM:  # round convolving function
                    continue

                # add the colvolved measurement to the grid.
                self.xy(iix, jjy, z, r, inweight)
        return
Пример #4
0
    def friend(ob1, ob2):

        # determines the friendship between two clumps
        flag = "NO"  # Initial assumption = NO
        """ Projected Sky Separation """

        # calculates the angular separation between two centroids of the clumps
        t1 = (cat['ra'][ob1], cat['dec'][ob1])
        t2 = (cat['ra'][ob2], cat['dec'][ob2])
        angrad = sep(d2r(t1[0]), d2r(t1[1]), d2r(t2[0]), d2r(t2[1]))
        angarcmin = (angrad * 180 * 60) / float(np.pi)
        """ Redshift check"""

        # checks redshift consistency of the two clumps.
        # If their redshift difference is consistent with zero then yes.

        # What todo : Old Method
        # z1, z2 = gcat[gindex[id1]]['Z'], gcat[gindex[id2]]['Z']   # corresponding member redshifts
        # m1, m2 = np.mean(z1), np.mean(z2)                         # mean redshifts of the clumps
        # var1, var2 = (0.061**2) * np.sum((1+z1)**2), (0.061**2) * np.sum((1+z2)**2)  # variances
        # er1, er2 = np.sqrt(var1 / float(len(z1))), np.sqrt(var2 / float(len(z2)))    # errors

        id1, id2 = cat['id'][ob1], cat['id'][
            ob2]  # clump ids (actually dog ids)
        res1 = gfit_to_pdf(id1, gindex)
        res2 = gfit_to_pdf(id2, gindex)

        m1, m2 = abs(res1[0]), abs(res2[0])
        er1, er2 = abs(res1[1]), abs(res2[1])

        if m1 > m2:
            d = m1 - m2  # difference of the mean
        else:
            d = m2 - m1

        d_er = np.sqrt(er1**2 + er2**2)  # error on the difference.
        low, high = d - d_er, d + d_er  # minimum and maximum difference.
        """ Decision """

        if angarcmin < aperture:
            if low <= 0 <= high:
                flag = "YES"
        # friend if angular separation is less than the aperture radius
        # and if their 0 belongs to the range [min_diff, max_diff].

        return flag
Пример #5
0
        print "Telescope Az, El: ", rs.telaz, rs.telel

# convert to MHz
    yv = rs.ydataA * scalefactor
    if doFlag:
        hv = interpolate.lines( linelist, linewidth, xv, yv) # interpolate rfi
        spectra[nRead, : ] = hv
    else:
        spectra[nRead, : ] = yv
    # now record the coordinates to compare distances.
    azs[nRead] = rs.telaz
    els[nRead] = rs.telel
    ras[nRead] = rs.ra
    decs[nRead] = rs.dec
#    print rs.ra, rs.dec
    aTheta = angles.sep(angles.d2r(rs.ra), angles.d2r(rs.dec), ra0, dec0)
    thetas[nRead] = aTheta
    # keep track of minimum angular distance
    if aTheta < minTheta:
        minTheta = aTheta
        iTheta = nRead

    if aTheta < onTheta:
        if nOn == 0:
            onSpectra = copy.deepcopy( rs)
        else:
            onSpectra.ydataA = onSpectra.ydataA + rs.ydataA
        nOn = nOn + 1
        nRead = nRead + 1

    if aTheta > offThetaA and aTheta < offThetaB:
Пример #6
0
    def azel_to_antenna_angles(self, pdat, cont_track_method= None):
        """
        From a table of az/el pointings, compute a new table that minimises the
        amount of movements while keeping the off-pointing within the antenna
        beamwidth

        Note: this method does *not* interpolate, it just uses nearest neighbour
              so pdat must be at sufficient time resolution.


        Also transform antenna pointing vectors in such a way that the antenna will track continously  throughout
        the pass. We do this by checking if the antenna ever needs to enter both the NE and NW quarters, and
        if so, depending on the antenna rotator capabilities we can use one of 2 methods to achieve a continous
        (up to 3 quadrant) track.
          * flipover:         We move the antenna in the 90 -- 180 degree extended elevation range
          * extended_azimuth: We move the antenna in the 360 -- 540 degree extended azimuth range

        4 quadrant tracking is not currently supported. If the trajectory enters 4 quadrants, or if the antenna
        capabilities do not meet the requirements for flipover or extended_azimuth, then the antenna will be commanded
        in the "normal" 0-360 az and 0-90 el range and there may be discontinuities.

        args:
           pdat (DataFrame): must have at least an az and el column.
           cont_track_method (str): Try to force a continous tracking method. If omited a method will be chosen
                             based on antenna capabilities.
        """

        if not isinstance(pdat, DataFrame):
            raise Error("pdat must be a DataFrame, got {}".format(type(pdat)))

        if 'az'not in pdat.columns or 'el' not in pdat.columns:
            raise Error("pdat must have at least an az and el column")


        #
        # Transform antenna pointing vectors in such a way that the antenna will track continously  throughout
        # the pass. We do this by checking if the antenna ever needs to enter both the NE and NW quarters, and
        # if so, depending on the antenna rotator capabilities we can use one of 2 methods to achieve a continous
        # (up to 3 quadrant) track.
        #   * flipover: We move the antenna in the 90 -- 180 degree extended elevation range
        #   * extended_azimuth: We move the antenna in the 360 -- 540 degree extended azimuth range
        #
        # 4 quadrant tracking is not currently supported. If the trajectory enters 4 quadrants, or if the antenna
        # capabilities do not meet the requirements for flipover or continue, then the antenna will be commanded
        # in the "normal" 0-360 az and 0-90 el range and there may be discontinuities.
        #

        if cont_track_method is None:
            # TODO (maybe one day): Enable 4 quadrant continous tracking by utilising extended range (360->450 deg)
            if self.MAX_AZ >= 540:
                cont_track_method = 'extended_azimuth'
            elif self.MAX_EL >= 180:
                cont_track_method = 'flipover'
            else:
                cont_track_method = 'none'

        # Compute quadrants the trajectory passes through
        quadrants = set([('N' if p.az < 90 or p.az > 270 else 'S') + ('E' if p.az < 180 else 'W') for _, p in pdat.iterrows()])

        # Note NE and NW in quadrants and len(q) <=3 implies that SW and SE cant both be passed through and so the below
        # works. It would *not* work if the track crossed the SW-SE boundary.
        if len(quadrants) <= 3 and 'NE' in quadrants and 'NW' in quadrants and cont_track_method == 'flipover':
            # Make sure antenna tracks continously when crossing NE->NW boundary by flipping antenna over
            # i.e by applying elevation angles between 180 -> 90, and adjusting azimuth appropriately.
            log.info('Antenna track crosses between NE and NW quadrant. Using "flipover" method for continous tracking')
            pdat = pdat.copy()
            pdat.az -= 180
            pdat.loc[pdat.az < 0, 'az'] += 360
            pdat.el = 180 - pdat.el
        elif len(quadrants) <= 3 and 'NE' in quadrants and 'NW' in quadrants and cont_track_method == 'extended_azimuth':
            # Make sure antenna tracks continously when crossing NE-->NW boundary by using the 180-->540 azimuth
            # range instead of 0 --> 360
            #
            log.info('Antenna track crosses between NE and NW quadrant. Using "extended_azimuth" method for continous tracking')
            pdat = pdat.copy()
            pdat.loc[pdat.az < 180, 'az'] += 360
        else:
            if len(quadrants) > 3:
                log.warning("4 Quadrant continous tracking is not currently supported.")

            az = pdat.az
            el = pdat.el


        ant_p = DataFrame(columns=pdat.columns)
        ant_p = ant_p.append(pdat.iloc[0])


        R2D = 180.0/pi
        D2R = pi/180.0

        for k,r in pdat.iterrows():
            s = angles.sep(ant_p.iloc[-1].az*D2R, ant_p.iloc[-1].el*D2R, r.az*D2R, r.el*D2R)*R2D

            if (s >= self.BEAMWIDTH/2.2): #<--- half beamwdith less 10% margin
                ant_p = ant_p.append(r)

        if len(ant_p) > 1:
            t = ant_p.index[:-1:2]
            ant_p = ant_p.iloc[1::2]
            ant_p.index =t
        elif len(ant_p) == 0:
            raise Error("Failed to compute any antenna points")

        return ant_p
Пример #7
0
def sep_tuple(t1,
              t2):  # distances between two coordinates, stored in two tuples
    # works fine, but will not use
    angrad = sep(d2r(t1[0]), d2r(t1[1]), d2r(t2[0]), d2r(t2[1]))
    angarcmin = (angrad * 180 * 60) / float(np.pi)  # in arcmin
    return angarcmin
Пример #8
0
def test_sep_against_slalib_dsep():
    """Results from sep should match those from slalib.dsep"""
    # Random positions.
    import random
    import math
    random.seed(12345)
    alpha = [random.uniform(0, 2 * math.pi) for i in range(100)]
    delta = [random.uniform(-math.pi / 2, math.pi / 2)
             for i in range(100)]

    alpha1 = [random.uniform(0, 2 * math.pi) for i in range(100)]
    delta1 = [random.uniform(-math.pi / 2, math.pi / 2)
              for i in range(100)]

    # Code used to generate result from pyslalib:
    # s = [slalib.sla_dsep(alpha[i], delta[i], alpha1[i], delta1[i])
    #      for i in range(100)]
    s = [2.3488832415605776,
         1.1592942993972908,
         1.6727782224088137,
         1.9310273037619246,
         1.961534390837681,
         1.5150119839396818,
         1.8524526916856978,
         2.116947088206131,
         0.9750943461637399,
         0.8331152895856854,
         2.4690444308150243,
         0.8640444988019701,
         1.041460475452765,
         1.9245098805162162,
         2.7727507743449507,
         1.1760229988483686,
         1.6418575515189582,
         1.0798127458770757,
         2.705734045454533,
         2.711202832152844,
         2.4387778718976763,
         0.1675761464872016,
         0.7614806222975763,
         1.7781491597763561,
         2.029672021455121,
         2.4349201303097403,
         1.2603565818807192,
         2.05499965347367,
         0.6224811898002452,
         0.8126836325942026,
         0.7539982342941834,
         1.6809458707673535,
         1.975972151791415,
         0.7115429070168364,
         1.8079386355215084,
         0.7830659699492306,
         1.233553087948177,
         2.08588792306906,
         0.2779525335855478,
         1.458433197949138,
         1.2964042308707935,
         1.117425142370921,
         1.6383665060581982,
         0.21787615812753383,
         1.6859098755220057,
         1.2253004206853584,
         1.472817142187865,
         0.6648294675219921,
         2.982945161877018,
         0.45704974384275243,
         1.1584539180661326,
         2.8484175031722643,
         1.0402706684988297,
         0.7079258905264588,
         0.7808758533750498,
         0.5608700573233222,
         1.8505539643075692,
         2.494182944528214,
         0.8296145526473544,
         2.2901089789186297,
         1.7477923358131886,
         2.1499080375112816,
         1.1529753011873909,
         1.807265859808323,
         2.5770854449349865,
         1.172037115203078,
         2.7438561146081937,
         0.2216663532818151,
         1.4502352305471127,
         2.2334298247493645,
         1.9946613229884687,
         1.1362010677143621,
         0.9530063759328101,
         0.6782653608813761,
         0.9421358945224116,
         1.970340302154089,
         0.31583484463019296,
         0.5945806070431309,
         1.9894690263497685,
         0.5114702873070847,
         3.059530134272125,
         0.09988794964432562,
         2.1732721685109437,
         2.054896439114964,
         1.0130957019858804,
         1.6899941268950893,
         1.4002698103226345,
         1.3736478209061835,
         1.7281316524003778,
         1.7041224372124824,
         2.7245561902753233,
         1.676900403298997,
         0.5940433957880709,
         2.4371934329915814,
         2.189360172634095,
         1.127368860507556,
         0.49285131033236657,
         2.6159861791852204,
         0.878592556336548,
         2.875063431097953]

    s1 = [sep(a1, b1, a2, b2) for a1, b1, a2, b2 in zip(alpha, delta, alpha1, delta1)]
    d = [i - j for i, j in zip(s, s1)]

    assert abs(min(d)) <= 1e-8
    assert abs(max(d)) <= 1e-8