Exemple #1
0
 def light_travel_time_to_detector(self, det):
     """Return the light travel time from this detector
     Parameters
     ----------
     detector: Detector
         The other detector to determine the light travel time to.
     Returns
     -------
     time: float
         The light travel time in seconds
     """
     return lal.LightTravelTime(self.frDetector, det.frDetector) * 1e-9
Exemple #2
0
def MaxTimeDelayLine(ifos, ra, dec, gpstime=None, n=3):
    """
    Return the n-point SkyPositionTable describing the line perpendicular to
    the line of constant time delay through the given ra and dec for the
    2-tuple ifos.
    """

    # construct sky point
    p = SkyPosition()
    p.longitude = ra
    p.latitude = dec
    p.system = 'equatorial'

    # remove duplicate site references
    ifos = parse_sites(ifos)
    assert len(ifos) == 2, "More than two sites in given list of detectors"

    # get light travel time
    ltt = lal.LightTravelTime(ifos[0], ifos[1])
    # get number of points
    dt = ltt / n

    return TwoSiteSkyGrid(ifos, gpstime, dt=dt, point=p, sky='full')
Exemple #3
0
def ThreeSiteSkyGrid(ifos, gpstime, dt=0.0005, tiling='square', sky='half'):
    """
    Generates a SkyPositionTable for a three-site all-sky grid, covering either
    a hemisphere (sky='half') or full sphere (sky='full'), using either
    'square' or 'hexagonal tiling.
    """

    # remove duplicate site references
    pop = []
    for i, ifo in enumerate(ifos):
        if i == 0: continue
        site = ifo[0]
        if site in [x[0] for x in ifos[0:i]]:
            sys.stderr.write("Duplicate site reference, ignoring %s.\n" % ifo)
            pop.append(i)
    for p in pop[::-1]:
        ifos.pop(p)

    assert len(ifos) == 3

    detectors = []
    T = []
    baseline = []

    # load detectors
    for i, ifo in enumerate(ifos):
        detectors.append(cached_detector.get(prefix_to_name[ifo]))
        # get light travel time and baseline for other detectors to first
        if i >= 1:
            T.append(lal.LightTravelTime(detectors[0], detectors[i]))
            baseline.append(detectors[i].location - detectors[0].location)
            baseline[i - 1] /= np.linalg.norm(baseline[i - 1])

    # get angle between baselines
    angle = np.arccos(np.dot(baseline[0], baseline[1]))

    #
    # construct tiling vectors
    #

    tiling = tiling.lower()
    t = np.zeros(len(baseline))
    tdgrid = []

    # square grid
    dx = np.array([1, 0])
    dy = np.array([0, 1])
    nx = int(np.floor(T[0] / dt))
    ny = int(np.floor(T[1] / dt))

    # hexagonal grid
    if tiling == 'square':
        dm = dx
        dn = dy
        nm = nx
        nn = ny
        x = np.linspace(-nx, nx, 2 * nx + 1)
        y = np.linspace(-ny, ny, 2 * ny + 1)
        grid = np.array([[i, j] for i in x for j in y])
    # hexagonal grid
    elif re.match('hex', tiling):
        dm = (2 * dx + dy)
        dn = (-dx + dy)
        dx = dm - dn
        # tile grid so that origin gets tiled
        grid = []
        orig = np.array([0, 0])

        # find bottom left point on grid
        while orig[1] >= -ny:
            orig -= dn

        # loop over y
        for y in xrange(-ny, ny + 1):
            orig[0] = orig[0] % dx[0]
            # work out minimal x value
            minx = -nx
            while minx % 3 != orig[0]:
                minx += 1
            # tile x
            x = np.arange(minx, nx + 1, dx[0])
            # append to grid
            grid.extend([[i, y] for i in x])
            orig += dn
            orig[0] = orig[0] % dx[0]
        grid = np.asarray(grid)

    #
    # Following Rabaste, Chassande-Motin, Piran (2009), construct an ellipse
    # of physical values in 2D time-delay space for 3 detectors
    #

    #
    # (theta, phi) coordinate system is as follows:
    # detector 1 is origin
    # z-axis joins positively to detector 2
    # x-axis is orthogonal to z-axis in plane joining D1, D2, and D3
    # y-axis forms a right-handed coordinate system
    #

    # so need to rotate from Rabaste network coordinates into
    # earth-fixed coordinates at the end

    # set z-axis in Rabaste frame
    zaxis = baseline[0]

    # work out y-axis in Rabaste frame
    yaxis = np.cross(zaxis, baseline[1])
    yaxis /= np.linalg.norm(yaxis)

    # work out x-axis in Rabaste frame
    xaxis = np.cross(yaxis, zaxis)
    xaxis /= np.linalg.norm(xaxis)

    # work out lines of nodes
    north = np.array([0, 0, 1])
    lineofnodes = np.cross(baseline[0], north)
    lineofnodes /= np.linalg.norm(lineofnodes)

    # work out Euler angles
    alpha = np.arccos(np.dot(xaxis, lineofnodes))
    beta = np.arccos(np.dot(baseline[0], north))
    gamma = np.arccos(np.dot(lineofnodes, [1, 0, 0]))

    # construct rotation
    R = _rotation_euler(alpha, beta, gamma)

    #
    # construct sky position table
    #

    l = SkyPositionTable()
    # loop over time-delay between D1 and D2
    k = 0
    for i in grid:
        t = dt * i
        # construct coefficients of elliptical equation in quadratic form
        A = -T[1] / T[0] * t[0] * np.cos(angle)
        B = T[1]**2 * ((t[0] / T[0])**2 - np.sin(angle)**2)
        # test condition for inside ellipse and place point
        condition = t[1]**2 + 2 * A * t[1] + B
        if condition <= 0:
            ntheta = np.arccos(-t[0] / T[0])
            nphi   = np.arccos(-(T[0]*t[1]-T[1]*t[0]*np.cos(angle))/\
                                (T[1]*np.sqrt(T[0]**2-t[0]**2)*np.sin(angle)))
            p = SkyPosition()
            p.system = 'geographic'
            p.longitude = nphi
            p.latitude = lal.PI_2 - ntheta
            p.probability = None
            p.solid_angle = None
            p.normalize()
            p = p.rotate(R)
            p = GeographicToEquatorial(p, lal.LIGOTimeGPS(gpstime))
            l.append(p)
            if sky == 'full':
                p2 = SkyPosition()
                p2.longitude = p.longitude
                p2.latitude = p.latitude + lal.PI
                p2.system = 'equatorial'
                p2.normalize()
                l.append(p2)

    return l
Exemple #4
0
def TwoSiteSkyGrid(ifos, gpstime, dt=0.0005, sky='half', point=None):
    """
    Generates a SkyPositionTable for a two-site all-sky grid, covering either
    a hemisphere (sky='half') or full sphere (sky='full').

    The grid can be forced to pass through the given SkyPosition point if
    required.
    """

    # remove duplicate site references
    ifos = parse_sites(ifos)
    assert len(ifos) == 2, "More than two sites in given list of detectors"

    # get detectors
    detectors = [cached_detector.get(prefix_to_name[ifo])\
                 for ifo in ifos]

    # get light travel time
    ltt = lal.LightTravelTime(detectors[0], detectors[1])

    # get number of points
    max = int(np.floor(ltt / dt))

    # get baseline
    baseline = detectors[1].location - detectors[0].location
    baseline /= np.linalg.norm(baseline)

    #
    # construct rotation
    #

    # xaxis points overhead of detector 1 or given point
    # zaxis is baseline, or something else
    if point:
        xaxis = SphericalToCartesian(point)
        xaxis /= np.linalg.norm(xaxis)
        zaxis = np.cross(xaxis, baseline)
        zaxis /= np.linalg.norm(zaxis)
    else:
        xaxis = detectors[0].location
        xaxis /= np.linalg.norm(xaxis)
        zaxis = baseline
        yaxis = np.cross(zaxis, xaxis)
        yaxis /= np.linalg.norm(yaxis)

    yaxis = np.cross(xaxis, zaxis)
    yaxis /= np.linalg.norm(yaxis)

    # construct Euler rotation
    lineofnodes = np.cross([0, 0, 1], zaxis)
    lineofnodes /= np.linalg.norm(lineofnodes)

    # work out Euler angles
    alpha = np.arccos(np.dot([1, 0, 0], lineofnodes))
    beta = np.arccos(np.dot([0, 0, 1], zaxis))
    gamma = np.arccos(np.dot(lineofnodes, xaxis))

    # get rotation
    R = _rotation_euler(alpha, beta, gamma)

    # construct sky table
    l = SkyPositionTable()
    if sky == 'half': longs = [0]
    elif sky == 'full': longs = [0, lal.PI]
    else:
        raise AttributeError("Sky type \"%s\" not recognised, please use "
                             "'half' or 'full'" % sky)

    for long in longs:
        for i in xrange(-max, max + 1):
            # get time-delay
            t = i * dt
            # if time-delay greater that light travel time, skip
            if abs(t) >= ltt: continue
            # construct object
            e = SkyPosition()
            e.system = 'geographic'
            # project time-delay onto prime meridian
            e.longitude = long
            e.latitude = lal.PI_2 - np.arccos(-t / ltt)
            e.probability = None
            e.solid_angle = None
            e.normalize()
            e = e.rotate(R)
            e = GeographicToEquatorial(e, lal.LIGOTimeGPS(gpstime))
            if e not in l:
                l.append(e)

    return l
Exemple #5
0
def SkyPatch(ifos, ra, dec, radius, gpstime, dt=0.0005, sigma=1.65,\
             grid='circular'):
    """
    Returns a SkyPositionTable of circular rings emanating from a given
    central ra and dec. out to the maximal radius.
    """

    # form centre point
    p = SkyPosition()
    p.longitude = ra
    p.latitude = dec

    # get detectors
    ifos.sort()
    detectors = []
    for ifo in ifos:
        if ifo not in prefix_to_name.keys():
            raise ValueError("Interferometer '%s' not recognised." % ifo)
        detectors.append(cached_detector.get(\
                             prefix_to_name[ifo]))

    alpha = 0
    for i in xrange(len(ifos)):
        for j in xrange(i + 1, len(ifos)):
            # get opening angle
            baseline = lal.ArrivalTimeDiff(detectors[i].location,\
                                                detectors[j].location,\
                                                ra, dec, lal.LIGOTimeGPS(gpstime))
            ltt = float(
                lal.LIGOTimeGPS(
                    0, lal.LightTravelTime(detectors[i], detectors[j])))
            angle = np.arccos(baseline / ltt)

            # get window
            lmin = angle - radius
            lmax = angle + radius
            if lmin < lal.PI_2 and lmax > lal.PI_2:
                l = lal.PI_2
            elif np.fabs(lal.PI_2-lmin) <\
                     np.fabs(lal.PI_2-lmax):
                l = lmin
            else:
                l = lmax

            # get alpha
            dalpha = ltt * np.sin(l)
            if dalpha > alpha:
                alpha = dalpha

    # get angular resolution
    angRes = 2 * dt / alpha

    # generate grid
    if grid.lower() == 'circular':
        grid = CircularGrid(angRes, radius)
    else:
        raise RuntimeError("Must use grid='circular', others not coded yet")

    #
    # Need to rotate grid onto (ra, dec)
    #

    # calculate opening angle from north pole
    north = [0, 0, 1]
    angle = np.arccos(np.dot(north, SphericalToCartesian(p)))
    #angle = north.opening_angle(p)

    # get rotation axis
    axis = np.cross(north, SphericalToCartesian(p))
    axis = axis / np.linalg.norm(axis)

    # rotate grid
    R = _rotation(axis, angle)
    grid = grid.rotate(R)

    #
    # calculate probability density function
    #

    # assume Fisher distribution in angle from centre
    kappa = (0.66 * radius / sigma)**(-2)

    # compute probability
    for p in grid:
        overlap = np.cos(p.opening_angle(grid[0]))
        p.probability = np.exp(kappa * (overlap - 1))

    probs = [p.probability for p in grid]
    for p in grid:
        p.probability = p.probability / max(probs)

    return grid
Exemple #6
0
 def test_light_time(self):
     for d1 in self.d:
         for d2 in self.d:
             t1 = lal.LightTravelTime(d1.lal(), d2.lal()) * 1e-9
             t2 = d1.light_travel_time_to_detector(d2)
             self.assertAlmostEqual(t1, t2, 7)