示例#1
0
    def traceSplitReverse(self, r, inCoordSys=globalCoordSys, forwardCoordSys=None,
                          reverseCoordSys=None, minFlux=1e-3, verbose=False):
        if verbose:
            strtemplate = "traceSplitReverse {:15s} flux = {:18.8f}   nphot = {:10d}"
            print(strtemplate.format(self.name, np.sum(r.flux), len(r)))
        if self.skip:
            return r, None, inCoordSys, None

        if forwardCoordSys is None:
            forwardCoordSys = self.items[-1].coordSys
        if reverseCoordSys is None:
            reverseCoordSys = self.items[0].coordSys

        workQueue = [(r, inCoordSys, "reverse", len(self.items)-1)]

        outRForward = []
        outRReverse = []

        while workQueue:
            rays, inCoordSys, direction, itemIndex = workQueue.pop()
            item = self.items[itemIndex]
            if direction == "forward":
                rForward, rReverse, tmpForwardCoordSys, tmpReverseCoordSys = \
                    item.traceSplit(rays, inCoordSys, minFlux=minFlux, verbose=verbose)
            elif direction == "reverse":
                rForward, rReverse, tmpForwardCoordSys, tmpReverseCoordSys = \
                    item.traceSplitReverse(rays, inCoordSys, minFlux=minFlux, verbose=verbose)
            else:
                raise RuntimeError("Shouldn't get here!")

            rForward.trimVignettedInPlace(minFlux)
            rReverse.trimVignettedInPlace(minFlux)

            if itemIndex == 0:
                if len(rReverse) > 0:
                    if tmpReverseCoordSys != reverseCoordSys:
                        transform = batoid.CoordTransform(tmpReverseCoordSys, reverseCoordSys)
                        transform.applyForwardInPlace(rReverse)
                    outRReverse.append(rReverse)
            else:
                if len(rReverse) > 0:
                    workQueue.append((rReverse, tmpReverseCoordSys, "reverse", itemIndex-1))

            if itemIndex == len(self.items)-1:
                if len(rForward) > 0:
                    if tmpForwardCoordSys != forwardCoordSys:
                        transform = batoid.CoordTransform(tmpForwardCoordSys, forwardCoordSys)
                        transform.applyForwardInPlace(rForward)
                    outRForward.append(rForward)
            else:
                if len(rForward) > 1:
                    workQueue.append((rForward, tmpForwardCoordSys, "forward", itemIndex+1))

        rForward = batoid.concatenateRayVectors(outRForward)
        rReverse = batoid.concatenateRayVectors(outRReverse)
        return rForward, rReverse, forwardCoordSys, reverseCoordSys
示例#2
0
def test_RayVector():
    import random
    random.seed(5772)
    rayList = []
    for i in range(1000):
        rayList.append(
            batoid.Ray(
                random.gauss(0.0, 1.0),  # x
                random.gauss(0.0, 1.0),  # y
                random.gauss(0.0, 1.0),  # z
                random.gauss(0.0, 1.0),  # vx
                random.gauss(0.0, 1.0),  # vy
                random.gauss(0.0, 1.0),  # vz
                random.gauss(0.0, 1.0),  # t0
                random.gauss(1000.0, 1.0),  # wavelength
                random.gauss(100.0, 1.0),  # flux
                random.choice([True, False])  # vignetted
            ))
    rayVector = batoid.RayVector(rayList)
    assert rayVector.monochromatic == False
    do_pickle(rayVector)
    np.testing.assert_equal(rayVector.x,
                            np.array([ray.x for ray in rayVector]))
    np.testing.assert_equal(rayVector.y,
                            np.array([ray.y for ray in rayVector]))
    np.testing.assert_equal(rayVector.z,
                            np.array([ray.z for ray in rayVector]))
    np.testing.assert_equal(rayVector.vx,
                            np.array([ray.vx for ray in rayVector]))
    np.testing.assert_equal(rayVector.vy,
                            np.array([ray.vy for ray in rayVector]))
    np.testing.assert_equal(rayVector.vz,
                            np.array([ray.vz for ray in rayVector]))
    np.testing.assert_equal(rayVector.t,
                            np.array([ray.t for ray in rayVector]))
    np.testing.assert_equal(rayVector.wavelength,
                            np.array([ray.wavelength for ray in rayVector]))
    np.testing.assert_equal(rayVector.flux,
                            np.array([ray.flux for ray in rayVector]))
    np.testing.assert_equal(rayVector.vignetted,
                            np.array([ray.vignetted for ray in rayVector]))
    np.testing.assert_equal(rayVector.failed,
                            np.array([ray.failed for ray in rayVector]))
    np.testing.assert_equal(
        rayVector.phase([1, 2, 3], 4.0),
        np.array([ray.phase([1, 2, 3], 4.0) for ray in rayVector]))
    np.testing.assert_equal(
        rayVector.amplitude([1, 2, 3], 4.0),
        np.array([ray.amplitude([1, 2, 3], 4.0) for ray in rayVector]))

    np.testing.assert_equal(
        rayVector.v, np.array([[ray.vx, ray.vy, ray.vz] for ray in rayVector]))
    np.testing.assert_equal(
        rayVector.r, np.array([[ray.x, ray.y, ray.z] for ray in rayVector]))
    np.testing.assert_equal(rayVector.k,
                            np.array([ray.k for ray in rayVector]))
    np.testing.assert_equal(rayVector.omega,
                            np.array([ray.omega for ray in rayVector]))

    np.testing.assert_equal(rayVector.kx,
                            np.array([ray.kx for ray in rayVector]))
    np.testing.assert_equal(rayVector.ky,
                            np.array([ray.ky for ray in rayVector]))
    np.testing.assert_equal(rayVector.kz,
                            np.array([ray.kz for ray in rayVector]))

    # Try the other ctor
    rayVector2 = batoid.RayVector(
        np.array([ray.x for ray in rayList]),
        np.array([ray.y for ray in rayList]),
        np.array([ray.z for ray in rayList]),
        np.array([ray.vx for ray in rayList]),
        np.array([ray.vy for ray in rayList]),
        np.array([ray.vz for ray in rayList]),
        np.array([ray.t for ray in rayList]),
        np.array([ray.wavelength for ray in rayList]),
        np.array([ray.flux for ray in rayList]),
        np.array([ray.vignetted for ray in rayList]))
    assert rayVector == rayVector2
    assert rayVector2.monochromatic == False

    # See if we can make monochromatic True
    rayVector3 = batoid.RayVector(np.array([ray.x for ray in rayList]),
                                  np.array([ray.y for ray in rayList]),
                                  np.array([ray.z for ray in rayList]),
                                  np.array([ray.vx for ray in rayList]),
                                  np.array([ray.vy for ray in rayList]),
                                  np.array([ray.vz for ray in rayList]),
                                  np.array([ray.t for ray in rayList]),
                                  np.array([1.0 for ray in rayList]),
                                  np.array([ray.flux for ray in rayList]),
                                  np.array([ray.vignetted for ray in rayList]))
    assert rayVector3.monochromatic == True

    # Make sure we really got a view and not a copy
    x = rayVector.x
    x[0] += 1
    assert np.all(x == rayVector.x)
    assert not rayVector.x.flags.owndata

    # What about lifetimes?  What happens to x if rayVector disappears?
    x2 = np.copy(x)
    assert x is not x2
    del rayVector
    assert np.all(x == x2)  # it survives!

    # Test concatenateRayVectors
    rv1 = batoid.RayVector(rayList[0:5])
    rv2 = batoid.RayVector(rayList[5:10])
    rv3 = batoid.RayVector(rayList[10:12])
    rv4 = batoid.RayVector(rayList[12:40])
    rvA = batoid.concatenateRayVectors([rv1, rv2, rv3, rv4])
    rvB = batoid.RayVector(rayList[0:40])
    assert rvA == rvB
示例#3
0
def drdth(optic,
          theta_x,
          theta_y,
          wavelength,
          nrad=6,
          naz=36,
          projection='postel'):
    """Calculate derivative of focal plane coord with respect to field angle.

    Parameters
    ----------
    optic : batoid.Optic
        Optical system
    theta_x, theta_y : float
        Field angle in radians
    wavelength : float
        Wavelength in meters
    nrad : int, optional
        Number of ray radii to use.  (see RayVector.asPolar())
    naz : int, optional
        Approximate number of azimuthal angles in outermost ring.  (see
        RayVector.asPolar())
    projection : {'postel', 'zemax', 'gnomonic', 'stereographic', 'lambert', 'orthographic'}
        Projection used to convert field angle to direction cosines.

    Returns
    -------
    drdth : (2, 2), ndarray
        Jacobian transformation matrix for converting between (theta_x, theta_y)
        and (x, y) on the focal plane.

    Notes
    -----
        This is the Jacobian of pixels -> tangent plane, (and importantly, not
        pixels -> ra/dec).  It should be *close* to the inverse plate scale
        though, especially near the center of the tangent plane projection.
    """
    # We just use a finite difference approach here.
    dth = 1e-5

    # Make direction cosine vectors
    nominalCos = fieldToDirCos(theta_x, theta_y, projection=projection)
    dthxCos = fieldToDirCos(theta_x + dth, theta_y, projection=projection)
    dthyCos = fieldToDirCos(theta_x, theta_y + dth, projection=projection)

    rays = batoid.RayVector.asPolar(optic=optic,
                                    wavelength=wavelength,
                                    dirCos=nominalCos,
                                    nrad=nrad,
                                    naz=naz)
    rays_x = batoid.RayVector.asPolar(optic=optic,
                                      wavelength=wavelength,
                                      dirCos=dthxCos,
                                      nrad=nrad,
                                      naz=naz)
    rays_y = batoid.RayVector.asPolar(optic=optic,
                                      wavelength=wavelength,
                                      dirCos=dthyCos,
                                      nrad=nrad,
                                      naz=naz)

    # Faster to concatenate and trace all at once
    rays_c = batoid.concatenateRayVectors([rays, rays_x, rays_y])
    optic.trace(rays_c)
    n = len(rays)
    rays = rays_c[:n]
    rays_x = rays_c[n:2 * n]
    rays_y = rays_c[2 * n:3 * n]

    w = ~rays.vignetted
    mx = np.mean(rays.x[w])
    my = np.mean(rays.y[w])

    # meters / radian
    drx_dthx = (np.mean(rays_x.x[w]) - mx) / dth
    drx_dthy = (np.mean(rays_y.x[w]) - mx) / dth
    dry_dthx = (np.mean(rays_x.y[w]) - my) / dth
    dry_dthy = (np.mean(rays_y.y[w]) - my) / dth

    return np.array([[drx_dthx, drx_dthy], [dry_dthx, dry_dthy]])