23 __all__ = [
"BoxGrid",
"makeSipIwcToPixel",
"makeSipPixelToIwc"]
32 from numpy.testing
import assert_allclose, assert_array_equal
33 from astshim.test import makeForwardPolyMap, makeTwoWayPolyMap
44 """Divide a box into nx by ny sub-boxes that tile the region 46 The sub-boxes will be of the same type as `box` and will exactly tile `box`; 47 they will also all be the same size, to the extent possible (some variation 48 is inevitable for integer boxes that cannot be evenly divided. 52 box : `lsst.geom.Box2I` or `lsst.geom.Box2D` 53 the box to subdivide; the boxes in the grid will be of the same type 54 numColRow : pair of `int` 55 number of columns and rows 59 if len(numColRow) != 2:
61 "numColRow=%r; must be a sequence of two integers" % (numColRow,))
69 raise RuntimeError(
"Unknown class %s of box %s" % (
type(box), box))
73 minPoint = box.getMin()
75 dtype = np.array(minPoint).dtype
77 self.
_divList = [np.linspace(start=box.getMin()[i],
81 dtype=dtype)
for i
in range(2)]
88 """Return the box at the specified x,y index 92 indXY : pair of `ints` 93 the x,y index to return 97 subBox : `lsst.geom.Box2I` or `lsst.geom.Box2D` 105 return self.shape[0]*self.shape[1]
108 """Return an iterator over all boxes, where column varies most quickly 116 """Information about a FrameSet 120 frameSet : `ast.FrameSet` 121 The FrameSet about which you want information 130 Index of current frame 131 isBaseSkyFrame : `bool` 132 Is the base frame an `ast.SkyFrame`? 133 isCurrSkyFrame : `bool` 134 Is the current frame an `ast.SkyFrame`? 144 """Return a list of ast.PolyMap coefficients for the specified SIP matrix 146 The returned list of coefficients for an ast.PolyMap 147 that computes the following function: 149 f(dxy) = dxy + sipPolynomial(dxy)) 150 where dxy = pixelPosition - pixelOrigin 151 and sipPolynomial is a polynomial with terms `<name>n_m for x^n y^m` 152 (e.g. A2_0 is the coefficient for x^2 y^0) 156 metadata : lsst.daf.base.PropertySet 157 FITS metadata describing a WCS with the specified SIP coefficients 159 The desired SIP terms: one of A, B, AP, BP 164 A list of coefficients for an ast.PolyMap that computes 165 the specified SIP polynomial, including a term for out = in 169 This is an internal function for use by makeSipIwcToPixel 170 and makeSipPixelToIwc 172 outAxisDict = dict(A=1, B=2, AP=1, BP=2)
173 outAxis = outAxisDict.get(name)
175 raise RuntimeError(
"%s not a supported SIP name" % (name,))
176 width = metadata.getAsInt(
"%s_ORDER" % (name,)) + 1
181 coeffs.append([1.0, outAxis, 1, 0])
183 coeffs.append([1.0, outAxis, 0, 1])
185 for xPower
in range(width):
186 for yPower
in range(width):
187 coeffName =
"%s_%s_%s" % (name, xPower, yPower)
188 if not metadata.exists(coeffName):
191 coeff = metadata.getAsDouble(coeffName)
192 coeffs.append([coeff, outAxis, xPower, yPower])
194 raise RuntimeError(
"No %s coefficients found" % (name,))
199 """Make an IWC to pixel transform with SIP distortion from FITS-WCS metadata 201 This function is primarily intended for unit tests. 202 IWC is intermediate world coordinates, as described in the FITS papers. 206 metadata : lsst.daf.base.PropertySet 207 FITS metadata describing a WCS with inverse SIP coefficients 211 lsst.afw.geom.TransformPoint2ToPoint2 212 Transform from IWC position to pixel position (zero-based) 213 in the forward direction. The inverse direction is not defined. 218 The inverse SIP terms APn_m, BPn_m are polynomial coefficients x^n y^m 219 for computing transformed x, y respectively. If we call the resulting 220 polynomial inverseSipPolynomial, the returned transformation is: 222 pixelPosition = pixel origin + uv + inverseSipPolynomial(uv) 223 where uv = inverseCdMatrix * iwcPosition 225 crpix = (metadata.getScalar(
"CRPIX1") - 1, metadata.getScalar(
"CRPIX2") - 1)
230 coeffArr = np.array(coeffList, dtype=float)
231 sipPolyMap =
ast.PolyMap(coeffArr, 2,
"IterInverse=0")
233 iwcToPixelMap = cdMatrixMap.inverted().
then(sipPolyMap).
then(pixelRelativeToAbsoluteMap)
238 """Make a pixel to IWC transform with SIP distortion from FITS-WCS metadata 240 This function is primarily intended for unit tests. 241 IWC is intermediate world coordinates, as described in the FITS papers. 245 metadata : lsst.daf.base.PropertySet 246 FITS metadata describing a WCS with forward SIP coefficients 250 lsst.afw.geom.TransformPoint2ToPoint2 251 Transform from pixel position (zero-based) to IWC position 252 in the forward direction. The inverse direction is not defined. 257 The forward SIP terms An_m, Bn_m are polynomial coefficients x^n y^m 258 for computing transformed x, y respectively. If we call the resulting 259 polynomial sipPolynomial, the returned transformation is: 261 iwcPosition = cdMatrix * (dxy + sipPolynomial(dxy)) 262 where dxy = pixelPosition - pixelOrigin 264 crpix = (metadata.getScalar(
"CRPIX1") - 1, metadata.getScalar(
"CRPIX2") - 1)
265 pixelAbsoluteToRelativeMap =
ast.ShiftMap(crpix).inverted()
269 coeffArr = np.array(coeffList, dtype=float)
270 sipPolyMap =
ast.PolyMap(coeffArr, 2,
"IterInverse=0")
271 pixelToIwcMap = pixelAbsoluteToRelativeMap.then(sipPolyMap).
then(cdMatrixMap)
276 """A FrameSet with base or current frame possibly permuted, with associated 279 Only two-axis frames will be permuted. 283 frameSet : `ast.FrameSet` 284 The FrameSet you wish to permute. A deep copy is made. 286 Permute the base frame's axes? 288 Permute the current frame's axes? 293 If you try to permute a frame that does not have 2 axes 299 frameSet : `ast.FrameSet` 300 The FrameSet that may be permuted. A local copy is made. 301 isBaseSkyFrame : `bool` 302 Is the base frame an `ast.SkyFrame`? 303 isCurrSkyFrame : `bool` 304 Is the current frame an `ast.SkyFrame`? 305 isBasePermuted : `bool` 306 Are the base frame axes permuted? 307 isCurrPermuted : `bool` 308 Are the current frame axes permuted? 310 def __init__(self, frameSet, permuteBase, permuteCurr):
318 raise RuntimeError(
"Base frame has {} axes; 2 required to permute".
format(baseNAxes))
319 self.
frameSet.current = fsInfo.baseInd
321 self.
frameSet.current = fsInfo.currInd
325 raise RuntimeError(
"Current frame has {} axes; 2 required to permute".
format(currNAxes))
333 """Base class for unit tests of Transform<X>To<Y> 335 Subclasses must call `TransformTestBaseClass.setUp(self)` 336 if they provide their own version. 338 If a package other than afw uses this class then it must 339 override the `getTestDir` method to avoid writing into 340 afw's test directory. 344 """Return a directory where temporary test files can be written 346 The default implementation returns the test directory of the `afw` 349 If this class is used by a test in a package other than `afw` 350 then the subclass must override this method. 357 Subclasses should call this method if they override setUp. 369 "Generic": (1, 2, 3, 4),
379 "SpherePoint": (1, 3, 4),
392 """Make an array of generic point data 394 The data will be suitable for spherical points 399 Number of points in the array 401 Number of axes in the point 405 np.array of floats with shape (nAxes, nPoints) 406 The values are as follows; if nAxes != 2: 407 The first point has values `[0, delta, 2*delta, ..., (nAxes-1)*delta]` 408 The Nth point has those values + N 409 if nAxes == 2 then the data is scaled so that the max value of axis 1 410 is a bit less than pi/2 414 oneAxis = np.arange(nPoints, dtype=float)
416 rawData = np.array([j * delta + oneAxis
for j
in range(nAxes)], dtype=float)
420 maxLatitude = np.max(rawData[1])
421 rawData *= math.pi * 0.4999 / maxLatitude
426 """Make one generic point 431 Number of axes in the point 433 Increment between axis values 437 A list of `nAxes` floats with values `[0, delta, ..., (nAxes-1)*delta] 439 return [i*delta
for i
in range(nAxes)]
448 Endpoint class name prefix; the full class name is name + "Endpoint" 449 nAxes : `int` or `None`, optional 450 number of axes; an int is required if `name` == "Generic"; 455 subclass of `lsst.afw.geom.BaseEndpoint` 456 The constructed endpoint 461 If `name` == "Generic" and `nAxes` is None or <= 0 463 EndpointClassName = name +
"Endpoint" 464 EndpointClass = getattr(afwGeom, EndpointClassName)
465 if name ==
"Generic":
467 raise TypeError(
"nAxes must be an integer for GenericEndpoint")
468 return EndpointClass(nAxes)
469 return EndpointClass()
473 """Return the appropriate frame for the given name and nAxes 478 Endpoint class name prefix; the full class name is name + "Endpoint" 479 nAxes : `int` or `None`, optional 480 number of axes; an int is required if `name` == "Generic"; 486 The constructed frame 491 If `name` == "Generic" and `nAxes` is `None` or <= 0 497 """Return a list of 0 or more frames that are not a valid match for the 503 Endpoint class name prefix; the full class name is name + "Endpoint" 507 Collection of `ast.Frame` 508 A collection of 0 or more frames 527 The FrameSet will contain 4 frames and three transforms connecting them. 528 The idenity of each frame is provided by self.frameIdentDict 530 Frame Index Mapping from this frame to the next 531 `baseFrame` 1 `ast.UnitMap(nIn)` 532 Frame(nIn) 2 `polyMap` 533 Frame(nOut) 3 `ast.UnitMap(nOut)` 537 - `nIn` = `baseFrame.nAxes` 538 - `nOut` = `currFrame.nAxes` 539 - `polyMap` = `makeTwoWayPolyMap(nIn, nOut)` 544 The FrameSet as described above 548 baseFrame : `ast.Frame` 550 currFrame : `ast.Frame` 553 nIn = baseFrame.nAxes
554 nOut = currFrame.nAxes
559 baseFrame = baseFrame.copy()
561 currFrame = currFrame.copy()
567 frameSet.addFrame(ast.FrameSet.CURRENT,
ast.UnitMap(nIn), frame2)
570 frameSet.addFrame(ast.FrameSet.CURRENT, polyMap, frame3)
571 frameSet.addFrame(ast.FrameSet.CURRENT,
ast.UnitMap(nOut), currFrame)
576 """Iterator over 0 or more frameSets with SkyFrames axes permuted 578 Only base and current SkyFrames are permuted. If neither the base nor 579 the current frame is a SkyFrame then no frames are returned. 583 iterator over `PermutedFrameSet` 587 if not (fsInfo.isBaseSkyFrame
or fsInfo.isCurrSkyFrame):
590 permuteBaseList = [
False,
True]
if fsInfo.isBaseSkyFrame
else [
False]
591 permuteCurrList = [
False,
True]
if fsInfo.isCurrSkyFrame
else [
False]
592 for permuteBase
in permuteBaseList:
593 for permuteCurr
in permuteCurrList:
598 """Make a Jacobian matrix for the equation described by 604 the dimensions of the input and output data; see makeTwoWayPolyMap 605 inPoint : `numpy.ndarray` 606 an array of size `nIn` representing the point at which the Jacobian 612 an `nOut` x `nIn` array of first derivatives 614 basePolyMapCoeff = 0.001
615 baseCoeff = 2.0 * basePolyMapCoeff
616 coeffs = np.empty((nOut, nIn))
617 for iOut
in range(nOut):
618 coeffOffset = baseCoeff * iOut
619 for iIn
in range(nIn):
620 coeffs[iOut, iIn] = baseCoeff * (iIn + 1) + coeffOffset
621 coeffs[iOut, iIn] *= inPoint[iIn]
622 assert coeffs.ndim == 2
624 assert coeffs.shape == (nOut, nIn)
628 """Check applyForward and applyInverse for a transform 632 transform : `lsst.afw.geom.Transform` 633 The transform to check 634 mapping : `ast.Mapping` 635 The mapping the transform should use. This mapping 636 must contain valid forward or inverse transformations, 637 but they need not match if both present. Hence the 638 mappings returned by make*PolyMap are acceptable. 640 Error message suffix describing test parameters 642 fromEndpoint = transform.fromEndpoint
643 toEndpoint = transform.toEndpoint
644 mappingFromTransform = transform.getMapping()
648 self.assertEqual(nIn, fromEndpoint.nAxes, msg=msg)
649 self.assertEqual(nOut, toEndpoint.nAxes, msg=msg)
653 inPoint = fromEndpoint.pointFromData(rawInPoint)
658 inArray = fromEndpoint.arrayFromData(rawInArray)
660 if mapping.hasForward:
661 self.assertTrue(transform.hasForward)
662 outPoint = transform.applyForward(inPoint)
663 rawOutPoint = toEndpoint.dataFromPoint(outPoint)
664 assert_allclose(rawOutPoint, mapping.applyForward(rawInPoint), err_msg=msg)
665 assert_allclose(rawOutPoint, mappingFromTransform.applyForward(rawInPoint), err_msg=msg)
667 outArray = transform.applyForward(inArray)
668 rawOutArray = toEndpoint.dataFromArray(outArray)
669 self.assertFloatsAlmostEqual(rawOutArray, mapping.applyForward(rawInArray), msg=msg)
670 self.assertFloatsAlmostEqual(rawOutArray, mappingFromTransform.applyForward(rawInArray), msg=msg)
674 outPoint = toEndpoint.pointFromData(rawOutPoint)
676 outArray = toEndpoint.arrayFromData(rawOutArray)
678 self.assertFalse(transform.hasForward)
680 if mapping.hasInverse:
681 self.assertTrue(transform.hasInverse)
685 inversePoint = transform.applyInverse(outPoint)
686 rawInversePoint = fromEndpoint.dataFromPoint(inversePoint)
687 assert_allclose(rawInversePoint, mapping.applyInverse(rawOutPoint), err_msg=msg)
688 assert_allclose(rawInversePoint, mappingFromTransform.applyInverse(rawOutPoint), err_msg=msg)
693 inverseArray = transform.applyInverse(outArray)
694 rawInverseArray = fromEndpoint.dataFromArray(inverseArray)
695 self.assertFloatsAlmostEqual(rawInverseArray, mapping.applyInverse(rawOutArray), msg=msg)
696 self.assertFloatsAlmostEqual(rawInverseArray, mappingFromTransform.applyInverse(rawOutArray),
699 self.assertFalse(transform.hasInverse)
702 """Check that two Transforms are each others' inverses. 706 forward : `lsst.afw.geom.Transform` 707 the reference Transform to test 708 inverse : `lsst.afw.geom.Transform` 709 the transform that should be the inverse of `forward` 711 error message suffix describing test parameters 713 fromEndpoint = forward.fromEndpoint
714 toEndpoint = forward.toEndpoint
715 forwardMapping = forward.getMapping()
716 inverseMapping = inverse.getMapping()
719 self.assertEqual(forward.fromEndpoint,
720 inverse.toEndpoint, msg=msg)
721 self.assertEqual(forward.toEndpoint,
722 inverse.fromEndpoint, msg=msg)
723 self.assertEqual(forward.hasForward, inverse.hasInverse, msg=msg)
724 self.assertEqual(forward.hasInverse, inverse.hasForward, msg=msg)
730 inPoint = fromEndpoint.pointFromData(rawInPoint)
732 outPoint = toEndpoint.pointFromData(rawOutPoint)
737 inArray = fromEndpoint.arrayFromData(rawInArray)
739 outArray = toEndpoint.arrayFromData(rawOutArray)
741 if forward.hasForward:
742 self.assertEqual(forward.applyForward(inPoint),
743 inverse.applyInverse(inPoint), msg=msg)
744 self.assertEqual(forwardMapping.applyForward(rawInPoint),
745 inverseMapping.applyInverse(rawInPoint), msg=msg)
747 assert_array_equal(forward.applyForward(inArray),
748 inverse.applyInverse(inArray),
750 assert_array_equal(forwardMapping.applyForward(rawInArray),
751 inverseMapping.applyInverse(rawInArray),
754 if forward.hasInverse:
755 self.assertEqual(forward.applyInverse(outPoint),
756 inverse.applyForward(outPoint), msg=msg)
757 self.assertEqual(forwardMapping.applyInverse(rawOutPoint),
758 inverseMapping.applyForward(rawOutPoint), msg=msg)
759 assert_array_equal(forward.applyInverse(outArray),
760 inverse.applyForward(outArray),
762 assert_array_equal(forwardMapping.applyInverse(rawOutArray),
763 inverseMapping.applyForward(rawOutArray),
767 """Check Transform_<fromName>_<toName> using the Mapping constructor 771 fromName, toName : `str` 772 Endpoint name prefix for "from" and "to" endpoints, respectively, 773 e.g. "Point2" for `lsst.afw.geom.Point2Endpoint` 774 fromAxes, toAxes : `int` 775 number of axes in fromFrame and toFrame, respectively 777 transformClassName =
"Transform{}To{}".
format(fromName, toName)
778 TransformClass = getattr(afwGeom, transformClassName)
779 baseMsg =
"TransformClass={}".
format(TransformClass.__name__)
782 for nIn, nOut
in itertools.product(self.
goodNAxes[fromName],
784 msg =
"{}, nIn={}, nOut={}".
format(baseMsg, nIn, nOut)
789 desStr =
"{}[{}->{}]".
format(transformClassName, nIn, nOut)
790 self.assertEqual(
"{}".
format(transform), desStr)
791 self.assertEqual(repr(transform),
"lsst.afw.geom." + desStr)
806 for nIn, badNOut
in itertools.product(self.
goodNAxes[fromName],
809 msg =
"{}, nIn={}, badNOut={}".
format(baseMsg, nIn, badNOut)
810 with self.assertRaises(InvalidParameterError, msg=msg):
814 for badNIn, nOut
in itertools.product(self.
badNAxes[fromName],
817 msg =
"{}, badNIn={}, nOut={}".
format(baseMsg, nIn, nOut)
818 with self.assertRaises(InvalidParameterError, msg=msg):
822 """Check Transform_<fromName>_<toName> using the FrameSet constructor 826 fromName, toName : `str` 827 Endpoint name prefix for "from" and "to" endpoints, respectively, 828 e.g. "Point2" for `lsst.afw.geom.Point2Endpoint` 830 transformClassName =
"Transform{}To{}".
format(fromName, toName)
831 TransformClass = getattr(afwGeom, transformClassName)
832 baseMsg =
"TransformClass={}".
format(TransformClass.__name__)
833 for nIn, nOut
in itertools.product(self.
goodNAxes[fromName],
835 msg =
"{}, nIn={}, nOut={}".
format(baseMsg, nIn, nOut)
840 self.assertEqual(frameSet.nFrame, 4)
844 badFrameSet = self.
makeFrameSet(badBaseFrame, currFrame)
845 with self.assertRaises(InvalidParameterError):
848 reallyBadFrameSet = self.
makeFrameSet(badBaseFrame, badCurrFrame)
849 with self.assertRaises(InvalidParameterError):
852 badFrameSet = self.
makeFrameSet(baseFrame, badCurrFrame)
853 with self.assertRaises(InvalidParameterError):
858 desStr =
"{}[{}->{}]".
format(transformClassName, nIn, nOut)
859 self.assertEqual(
"{}".
format(transform), desStr)
860 self.assertEqual(repr(transform),
"lsst.afw.geom." + desStr)
864 mappingFromTransform = transform.getMapping()
866 self.assertEqual(
type(transform),
type(transformCopy))
867 self.assertEqual(transform.getMapping(), mappingFromTransform)
879 if permutedFS.isBaseSkyFrame:
880 baseFrame = permutedFS.frameSet.getFrame(ast.FrameSet.BASE)
882 desBaseLonAxis = 2
if permutedFS.isBasePermuted
else 1
883 self.assertEqual(baseFrame.lonAxis, desBaseLonAxis)
884 if permutedFS.isCurrSkyFrame:
885 currFrame = permutedFS.frameSet.getFrame(ast.FrameSet.CURRENT)
887 desCurrLonAxis = 2
if permutedFS.isCurrPermuted
else 1
888 self.assertEqual(currFrame.lonAxis, desCurrLonAxis)
894 """Test Transform<fromName>To<toName>.inverted 898 fromName, toName : `str` 899 Endpoint name prefix for "from" and "to" endpoints, respectively, 900 e.g. "Point2" for `lsst.afw.geom.Point2Endpoint` 902 transformClassName =
"Transform{}To{}".
format(fromName, toName)
903 TransformClass = getattr(afwGeom, transformClassName)
904 baseMsg =
"TransformClass={}".
format(TransformClass.__name__)
905 for nIn, nOut
in itertools.product(self.
goodNAxes[fromName],
907 msg =
"{}, nIn={}, nOut={}".
format(baseMsg, nIn, nOut)
911 "{}, Map={}".
format(msg,
"TwoWay"))
915 "{}, Map={}".
format(msg,
"Forward"))
919 "{}, Map={}".
format(msg,
"Inverse"))
922 """Test Transform<fromName>To<toName>.inverted for a specific 925 Also check that inverted() and getInverted() return the same 930 TransformClass : `type` 931 The class of transform to test, such as TransformPoint2ToPoint2 932 mapping : `ast.Mapping` 933 The mapping to use for the transform 938 inverse = transform.inverted()
939 inverseInverse = inverse.inverted()
946 """Test Transform<fromName>To<toName>.getJacobian 950 fromName, toName : `str` 951 Endpoint name prefix for "from" and "to" endpoints, respectively, 952 e.g. "Point2" for `lsst.afw.geom.Point2Endpoint` 954 transformClassName =
"Transform{}To{}".
format(fromName, toName)
955 TransformClass = getattr(afwGeom, transformClassName)
956 baseMsg =
"TransformClass={}".
format(TransformClass.__name__)
957 for nIn, nOut
in itertools.product(self.
goodNAxes[fromName],
959 msg =
"{}, nIn={}, nOut={}".
format(baseMsg, nIn, nOut)
962 fromEndpoint = transform.fromEndpoint
966 inPoint = fromEndpoint.pointFromData(rawInPoint)
967 jacobian = transform.getJacobian(inPoint)
968 assert_allclose(jacobian, self.
makeJacobian(nIn, nOut, rawInPoint),
972 inPoint = fromEndpoint.pointFromData(rawInPoint)
973 jacobian = transform.getJacobian(inPoint)
974 assert_allclose(jacobian, self.
makeJacobian(nIn, nOut, rawInPoint),
978 """Test Transform<fromName>To<midName>.then(Transform<midName>To<toName>) 983 the prefix of the starting endpoint (e.g., "Point2" for a 984 Point2Endpoint) for the final, concatenated Transform 986 the prefix for the shared endpoint where two Transforms will be 989 the prefix of the ending endpoint for the final, concatenated 992 TransformClass1 = getattr(afwGeom,
993 "Transform{}To{}".
format(fromName, midName))
994 TransformClass2 = getattr(afwGeom,
995 "Transform{}To{}".
format(midName, toName))
996 baseMsg =
"{}.then({})".
format(TransformClass1.__name__,
997 TransformClass2.__name__)
998 for nIn, nMid, nOut
in itertools.product(self.
goodNAxes[fromName],
1001 msg =
"{}, nIn={}, nMid={}, nOut={}".
format(
1002 baseMsg, nIn, nMid, nOut)
1004 transform1 = TransformClass1(polyMap1)
1006 transform2 = TransformClass2(polyMap2)
1007 transform = transform1.then(transform2)
1009 fromEndpoint = transform1.fromEndpoint
1010 toEndpoint = transform2.toEndpoint
1013 outPointMerged = transform.applyForward(inPoint)
1014 outPointSeparate = transform2.applyForward(
1015 transform1.applyForward(inPoint))
1016 assert_allclose(toEndpoint.dataFromPoint(outPointMerged),
1017 toEndpoint.dataFromPoint(outPointSeparate),
1021 inPointMerged = transform.applyInverse(outPoint)
1022 inPointSeparate = transform1.applyInverse(
1023 transform2.applyInverse(outPoint))
1025 fromEndpoint.dataFromPoint(inPointMerged),
1026 fromEndpoint.dataFromPoint(inPointSeparate),
1030 if midName ==
"Generic":
1034 transform1 = TransformClass1(polyMap)
1036 transform2 = TransformClass2(polyMap)
1037 with self.assertRaises(InvalidParameterError):
1038 transform = transform1.then(transform2)
1041 if fromName != midName:
1044 joinNAxes =
set(self.
goodNAxes[fromName]).intersection(
1047 for nIn, nMid, nOut
in itertools.product(self.
goodNAxes[fromName],
1051 transform1 = TransformClass1(polyMap)
1053 transform2 = TransformClass1(polyMap)
1054 with self.assertRaises(InvalidParameterError):
1055 transform = transform1.then(transform2)
1058 """Assert that two transforms are equal""" 1059 self.assertEqual(
type(transform1),
type(transform2))
1060 self.assertEqual(transform1.fromEndpoint, transform2.fromEndpoint)
1061 self.assertEqual(transform1.toEndpoint, transform2.toEndpoint)
1062 self.assertEqual(transform1.getMapping(), transform2.getMapping())
1064 fromEndpoint = transform1.fromEndpoint
1065 toEndpoint = transform1.toEndpoint
1066 mapping = transform1.getMapping()
1070 if mapping.hasForward:
1073 inArray = fromEndpoint.arrayFromData(rawInArray)
1074 outArray = transform1.applyForward(inArray)
1075 outData = toEndpoint.dataFromArray(outArray)
1076 outArrayRoundTrip = transform2.applyForward(inArray)
1077 outDataRoundTrip = toEndpoint.dataFromArray(outArrayRoundTrip)
1078 assert_allclose(outData, outDataRoundTrip)
1080 if mapping.hasInverse:
1083 outArray = toEndpoint.arrayFromData(rawOutArray)
1084 inArray = transform1.applyInverse(outArray)
1085 inData = fromEndpoint.dataFromArray(inArray)
1086 inArrayRoundTrip = transform2.applyInverse(outArray)
1087 inDataRoundTrip = fromEndpoint.dataFromArray(inArrayRoundTrip)
1088 assert_allclose(inData, inDataRoundTrip)
1091 """Check persistence of a transform 1093 className =
type(transform).__name__
1096 transformStr = transform.writeString()
1097 serialVersion, serialClassName, serialRest = transformStr.split(
" ", 2)
1098 self.assertEqual(
int(serialVersion), 1)
1099 self.assertEqual(serialClassName, className)
1100 badStr1 =
" ".join([
"2", serialClassName, serialRest])
1102 transform.readString(badStr1)
1103 badClassName =
"x" + serialClassName
1104 badStr2 =
" ".join([
"1", badClassName, serialRest])
1106 transform.readString(badStr2)
1107 transformFromStr1 = transform.readString(transformStr)
1111 transformFromStr2 = afwGeom.transformFromString(transformStr)
1119 transform.writeFits(filename)
def __init__(self, frameSet, permuteBase, permuteCurr)
Eigen::Matrix2d getCdMatrixFromMetadata(daf::base::PropertySet &metadata)
Read a CD matrix from FITS WCS metadata.
def __init__(self, frameSet)
MatrixMap is a form of Mapping which performs a general linear transformation.
A floating-point coordinate rectangle geometry.
A UnitMap is a unit (null) Mapping that has no effect on the coordinates supplied to it...
daf::base::PropertySet * set
std::string getPackageDir(std::string const &packageName)
return the root directory of a setup package
SkyFrame is a specialised form of Frame which describes celestial longitude/latitude coordinate syste...
def makeTwoWayPolyMap(nIn, nOut)
Frame is used to represent a coordinate system.
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
def makeSipPixelToIwc(metadata)
ShiftMap is a linear Mapping which shifts each axis by a specified constant value.
def __getitem__(self, indXY)
def getTempFilePath(ext, expectOutput=True)
def __init__(self, box, numColRow)
Reports invalid arguments.
PolyMap is a Mapping which performs a general polynomial transformation.
def makeSipPolyMapCoeffs(metadata, name)
An integer coordinate rectangle.
def makeForwardPolyMap(nIn, nOut)
A FrameSet consists of a set of one or more Frames (which describe coordinate systems), connected together by Mappings (which describe how the coordinate systems are inter-related).
def makeSipIwcToPixel(metadata)