class PupilFitterTest(unittest.TestCase):
    def setUp(self):
        self.shape = (256, 256)
        self.radius = 52.3
        self.cx = 120.6
        self.cy = 70.9
        self.inradius = 15
        self.params2check_circle = np.array(
            [self.cx - 0.5, self.cy - 0.5, self.radius])
        self.params2check_anular = np.array(
            [self.cx - 0.5, self.cy - 0.5, self.radius, self.inradius])
        self.testMask1 = CircularMask(self.shape,
                                      maskRadius=self.radius,
                                      maskCenter=(self.cx, self.cy))
        self.testMask2 = AnnularMask(self.shape,
                                     maskRadius=self.radius,
                                     maskCenter=(self.cx, self.cy),
                                     inRadius=self.inradius)

    def test_docstring(self):
        print("In method %s" % self._testMethodName)
        import arte.utils.shape_fitter as pf_module
        doctest.testmod(pf_module, raise_on_error=True)

    def test_ransac(self):
        print("In method %s" % self._testMethodName)
        ff = ShapeFitter(self.testMask1.asTransmissionValue())
        ff.fit_circle_ransac()
        np.testing.assert_allclose(ff.parameters(),
                                   self.params2check_circle,
                                   rtol=0.01)

    def test_circle_correlation(self):
        print("In method %s" % self._testMethodName)
        mm = ['Nelder-Mead']
        for xx in mm:
            print("Tested method %s" % xx)
            ff = ShapeFitter(self.testMask1.asTransmissionValue())
            ff.fit_circle_correlation(method=xx, options={'disp': True})
            p1 = ff.parameters()
            print(p1)
            np.testing.assert_allclose(p1, self.params2check_circle, rtol=0.01)

    def test_annular_correlation(self):
        print("In method %s" % self._testMethodName)
        mm = ['Nelder-Mead']
        for xx in mm:
            print("Tested method %s" % xx)
            ff2 = ShapeFitter(self.testMask2.asTransmissionValue())
            ff2.fit_annular_correlation(method=xx, options={'disp': True})
            p2 = ff2.parameters()
            print(p2)

            #           if xx == 'CG' or xx == 'BFGS' or xx == 'L-BFGS-B' or xx == 'TNC' \
            #                     or xx == 'SLSQP' or xx == 'trust-constr':
            #                 p1 = p1[[1, 0, 2]]
            #                 p2 = p2[[1, 0, 2]]
            #                 rtol = 3

            np.testing.assert_allclose(p2, self.params2check_anular, rtol=0.01)
Ejemplo n.º 2
0
 def testRegionOfInterest(self):
     shape= (140, 100)
     aMask= CircularMask(shape, maskRadius=20, maskCenter=(60, 45))
     roi= aMask.regionOfInterest()
     self.assertEqual(40, roi.ymin)
     self.assertEqual(80, roi.ymax)
     self.assertEqual(25, roi.xmin)
     self.assertEqual(65, roi.xmax)
 def _createCircularMask(self):
     from arte.types.mask import CircularMask
     radiusInPx = 0.5 * self._pupilDiameterInMeters / \
         self.pupilPlanePixelSizeInMeters()
     centerInPx = [self._pupilDiameterInPixels / 2,
                   self._pupilDiameterInPixels / 2]
     self._mask = CircularMask(
         (self._pupilDiameterInPixels, self._pupilDiameterInPixels),
         radiusInPx, centerInPx)
Ejemplo n.º 4
0
 def test(self):
     psg = PhaseScreenGenerator(self._nPx, self._dPup, self._L0)
     psg.generateNormalizedPhaseScreens(self._howMany)
     mask = CircularMask((self._nPx, self._nPx))
     got = self.meanStd(
         np.ma.masked_array(
             psg.rescaleTo(self._r0).getInRadiansAt(self._lambda),
             np.tile(mask.mask(), (self._howMany, 1))))
     want = self.stdInRad(self._dPup, r0AtLambda(self._r0, self._lambda))
     print('%g %g %g -> got %g want %g / ratio %f' %
           (self._dPup, self._r0, self._lambda, got, want, want / got))
 def setUp(self):
     self.shape = (256, 256)
     self.radius = 52.3
     self.cx = 120.6
     self.cy = 70.9
     self.inradius = 15
     self.params2check_circle = np.array(
         [self.cx - 0.5, self.cy - 0.5, self.radius])
     self.params2check_anular = np.array(
         [self.cx - 0.5, self.cy - 0.5, self.radius, self.inradius])
     self.testMask1 = CircularMask(self.shape,
                                   maskRadius=self.radius,
                                   maskCenter=(self.cx, self.cy))
     self.testMask2 = AnnularMask(self.shape,
                                  maskRadius=self.radius,
                                  maskCenter=(self.cx, self.cy),
                                  inRadius=self.inradius)
Ejemplo n.º 6
0
 def testCreateCircularMaskFromMaskedArray(self):
     shape= (140, 100)
     aMask= CircularMask(shape, maskRadius=20, maskCenter=(60, 40))
     maskedArray= np.ma.masked_array(np.ones(shape), mask=aMask.mask())
     retrievedMask= CircularMask.fromMaskedArray(maskedArray)
     self.assertEqual(aMask.radius(), retrievedMask.radius())
     self.assertTrue(np.array_equal(aMask.center(), retrievedMask.center()))
class FourierAdaptiveOptics(object):

    RAD2ARCSEC = (3600 * 180) / np.pi
    ARCSEC2RAD = np.pi / (180 * 3600)

    def __init__(self,
                 pupilDiameterInMeters=8.0,
                 wavelength=1e-6,
                 focalPlaneFieldOfViewInArcsec=1.0,
                 resolutionFactor=2):
        self._pupilDiameterInMeters = pupilDiameterInMeters
        self._wavelength = wavelength
        self._focalPlaneFieldOfViewInArcsec = focalPlaneFieldOfViewInArcsec
        self._resolutionFactor = resolutionFactor

        self._nyquistFocalPlanePixelSizeInArcsec = 0.5 * \
            self._wavelength / self._pupilDiameterInMeters * self.RAD2ARCSEC

        self._focalPlanePixelSizeInArcsec = \
            self._nyquistFocalPlanePixelSizeInArcsec / self._resolutionFactor

        self._computePixelSizes(self._focalPlanePixelSizeInArcsec,
                                self._focalPlaneFieldOfViewInArcsec,
                                self._wavelength)

        self._pupilDiameterInPixels = self._noFocalPlanePixels
        self._phaseMapInMeters = None

        self._focalPlaneCoordinatesInArcsec = \
            self._createFocalPlaneCoordinatesInArcSec()
        self._focalPlaneAngularFreqCoords = \
            self._createFocalPlaneAngularFrequencyCoordinatesInInverseRadians()
        self._pupilPlaneCoordinatesInMeters = \
            self._createPupilPlaneCoordinatesInMeters()
        self._pupilPlaneSpatialFrequencyCoordinatesInInverseMeters = \
            self._createPupilPlaneSpatialFrequencyCoordiantesInInverseMeters()

        self._resetAll()

        self._mask = None
        self._focalLength = 125.
        self._createCircularMask()
        self._createPupilFunction()

        self.setPhaseMapInMeters(self._createFlatPhaseMap())

    def _computePixelSizes(self,
                           focalPlanePixelSizeInArcsec,
                           focalPlaneFieldOfViewInArcsec,
                           wavelenghtInMeters):
        self._noFocalPlanePixels = int(
            focalPlaneFieldOfViewInArcsec / focalPlanePixelSizeInArcsec)

        self._focalPlaneAngularFrequencyPixelSizeInInverseRadians = 1. / (
            self._noFocalPlanePixels * focalPlanePixelSizeInArcsec *
            self.ARCSEC2RAD)

        self._pupilPlaneSpatialFrequencyPizelSizeInInverseMeters = (
            focalPlanePixelSizeInArcsec * self.ARCSEC2RAD /
            wavelenghtInMeters)

        self._pupilPlanePixelSizeInMeters = 1. / (
            self._noFocalPlanePixels *
            self._pupilPlaneSpatialFrequencyPizelSizeInInverseMeters)

    def _resetAll(self):
        self._field = None
        self._pupilFunction = None
        self._amplitudeTransferFunction = None
        self._psf = None
        self._otf = None
        self._stf = None

    def pupilDiameterInMeters(self):
        return self._pupilDiameterInMeters

    def wavelengthInMeters(self):
        return self._wavelength

    def resolutionFactor(self):
        return self._resolutionFactor

    def focalPlaneFieldOfViewInArcsec(self):
        return self._focalPlaneFieldOfViewInArcsec

    def focalPlaneSizeInPixels(self):
        return self._noFocalPlanePixels

    def focalPlanePixelSizeInArcsec(self):
        return self._focalPlanePixelSizeInArcsec

    def focalPlaneAngularFrequencyPixelSizeInInverseRadians(self):
        return self._focalPlaneAngularFrequencyPixelSizeInInverseRadians

    def pupilPlanePixelSizeInMeters(self):
        return self._pupilPlanePixelSizeInMeters

    def focalPlaneAngularFrequencyCoordinatesInInverseRadians(self):
        return self._focalPlaneAngularFreqCoords

    def focalPlaneCoordinatesInArcsec(self):
        return self._focalPlaneCoordinatesInArcsec

    def pupilPlaneCoordinatesInMeters(self):
        return self._pupilPlaneCoordinatesInMeters

    def pupilPlaneSpatialFrequencyPizelSizeInInverseMeters(self):
        return self._pupilPlaneSpatialFrequencyPizelSizeInInverseMeters

    def field(self):
        if self._field is None:
            self._computeField()
        return self._field

    def psf(self):
        if self._psf is None:
            self._createPsf()
        return self._psf

    def otf(self):
        if self._otf is None:
            self._createOtf()
        return self._otf

    def stf(self):
        if self._stf is None:
            self._createStructureFunction()
        return self._stf

    def pupilFunction(self):
        if self._pupilFunction is None:
            self._createPupilFunction()
        return self._pupilFunction

    def amplitudeTransferFunction(self):
        if self._amplitudeTransferFunction is None:
            self._createAmplitudeTransferFunction()
        return self._amplitudeTransferFunction

    def focalPlaneCoordsInArcsec(self):
        return self._focalPlaneCoordinatesInArcsec / 4.848e-6

    def setPhaseMapInMeters(self, phaseMapInMeters):
        self._phaseMapInMeters = phaseMapInMeters
        self._resetAll()

    def _createCircularMask(self):
        from arte.types.mask import CircularMask
        radiusInPx = 0.5 * self._pupilDiameterInMeters / \
            self.pupilPlanePixelSizeInMeters()
        centerInPx = [self._pupilDiameterInPixels / 2,
                      self._pupilDiameterInPixels / 2]
        self._mask = CircularMask(
            (self._pupilDiameterInPixels, self._pupilDiameterInPixels),
            radiusInPx, centerInPx)

    def _createPupilFunction(self):
        domain = DomainXY.from_shape((self._pupilDiameterInPixels,
                                      self._pupilDiameterInPixels),
                                     self.pupilPlanePixelSizeInMeters())
        self._pupilFunction = S2DF(
            self._mask.asTransmissionValue(), domain=domain)

    def _createFlatPhaseMap(self):
        nPx = self._pupilDiameterInPixels
        pupPxSize = self.pupilPlanePixelSizeInMeters()
        domain = DomainXY.from_shape((nPx, nPx), pupPxSize)
        phase = S2DF(np.ones((nPx, nPx)), domain=domain)
        return phase

    def _computeField(self):
        phaseInRadians = self._phaseMapInMeters.values() / \
            self._wavelength * 2 * np.pi
        amplitude = np.ones_like(phaseInRadians)
        field = amplitude * np.exp(phaseInRadians * 1j)
        self._field = S2DF(
            field * self._mask.asTransmissionValue(),
            self._phaseMapInMeters.xCoord(),
            self._phaseMapInMeters.yCoord())

    def _extendFieldMap(self, fm, howManyTimes):
        fmExt = np.zeros(np.array(fm.shape) * howManyTimes,
                         dtype=np.complex128)
        fmExt[0:fm.shape[0], 0:fm.shape[1]] = fm
        return fmExt

    def _createAmplitudeTransferFunction(self):
        pupF = self.pupilFunction()
        rescaleCoordFact = 1 / (self.wavelengthInMeters() * self._focalLength)
        self._amplitudeTransferFunction = S2DF(
            pupF.values(),
            pupF.xCoord() * rescaleCoordFact,
            pupF.yCoord() * rescaleCoordFact)

    def _createOtf(self):
        ac = self._autoCorrelate(self.amplitudeTransferFunction())
        self._otf = S2DF(ac.values() / ac.values().max(),
                         ac.xCoord(),
                         ac.yCoord())

    def _autoCorrelate(self, scalar2dfunct):
        functFT = bfft.direct(scalar2dfunct)
        aa = S2DF(np.abs(functFT.values() ** 2),
                  functFT.xCoord(),
                  functFT.yCoord())
        return bfft.inverse(aa)

    def _createPsf(self):
        psf = bfft.inverse(self.otf())
        rescaleCoordFact = 1 / self._focalLength
        self._psf = S2DF(psf.values(),
                         psf.xCoord() * rescaleCoordFact,
                         psf.yCoord() * rescaleCoordFact)

    def _createStructureFunction(self):
        extFieldMap = self._extendFieldMap(self.field(),
                                           self._resolutionFactor)
        ac = self._autoCorrelate(extFieldMap)
        cc = (np.asarray(ac.shape) / 2).astype(np.int)
        self._stf = 2 * (ac[cc[0], cc[1]] - ac)

    def _createFocalPlaneCoordinatesInArcSec(self):
        return bfft.distances_x_map(
            self.focalPlaneSizeInPixels(),
            self.focalPlanePixelSizeInArcsec())

    def _createFocalPlaneAngularFrequencyCoordinatesInInverseRadians(self):
        return bfft.frequencies_x_map(
            self.focalPlaneSizeInPixels(),
            self.focalPlanePixelSizeInArcsec() * self.ARCSEC2RAD)

    def _createPupilPlaneCoordinatesInMeters(self):
        return bfft.distances_x_map(
            self.focalPlaneSizeInPixels(),
            self.pupilPlanePixelSizeInMeters())

    def _createPupilPlaneSpatialFrequencyCoordiantesInInverseMeters(self):
        return bfft.frequencies_x_map(
            self.focalPlaneSizeInPixels(),
            self.pupilPlanePixelSizeInMeters())
Ejemplo n.º 8
0
 def testAnularMask(self):
     mask1= CircularMask((10, 10),4,(5,5))
     mask2= CircularMask((10, 10),2,(5,5))
     mask3 = AnnularMask ((10, 10),4,(5,5),2)
     mask4 = mask1.mask() | ~mask2.mask()
     self.assertEqual(mask3.mask().all(), mask4.all())
Ejemplo n.º 9
0
 def testAsTransmissionValue(self):
     mask= CircularMask((10, 10))
     transmission= mask.asTransmissionValue()
     self.assertEqual(1, transmission[5, 5])
     self.assertEqual(0, transmission[0, 0])
Ejemplo n.º 10
0
 def testPassingCenterNone(self):
     mask= CircularMask((20, 10))
     self.assertTrue(np.allclose([10, 5],
                                 mask.center()),
                     "center is %s" % mask.center())
Ejemplo n.º 11
0
 def testPassingRadiusNone(self):
     mask= CircularMask((10, 10))
     self.assertEqual(5, mask.radius())
Ejemplo n.º 12
0
 def testNullRadiusMakeNullMask(self):
     mask= CircularMask((10, 20), maskRadius=0)
     self.assertTrue(np.all(mask.mask()))
Ejemplo n.º 13
0
 def testStandard(self):
     mask= CircularMask((13, 14))
     self.assertEqual(mask.shape(), (13, 14))