def test_004_inverse_constructor(): try: a = t.Inverse() except TypeError: a = t.Identity() b = t.Inverse(a) assert (f"{b}" == "Transform( Inverse Identity )") else: assert (False) # Should have thrown an error a = t.Identity() b = t.Inverse(a) c = t.Inverse(b) assert (f"{c}" == "Transform( Inverse Inverse Identity )")
def test_007_composition(): a = t.PlusOne_() b = a.inverse() try: c = t.Composition(a, b) assert False, "composition of a non-list should throw an error" except: pass # Construct an inverse c = t.Composition([a, b]) d = c.inverse() assert ( f"{c}" == "Transform( ( (_PlusOne) o (Inverse _PlusOne) ) )"\ and f"{d}" == "Transform( Inverse ( (_PlusOne) o (Inverse _PlusOne) ) )") # Check that Composition flattens compositions into one list e = t.Composition([c, c]) assert ( f"{e}" == "Transform( ( (_PlusOne) o (Inverse _PlusOne) o (_PlusOne) o (Inverse _PlusOne) ) )" ) # Check that Composition tracks dimensions correctly. In particular, idim/odim propagates through # transforms with 0 dim to the first nonzero one b = t.Identity() c = t.Composition([b, b]) assert (c.idim == 0 and c.odim == 0) c = t.Composition([a, b]) assert (c.idim == 1 and c.odim == 1) c = t.Composition([b, a]) assert (c.idim == 1 and c.odim == 1)
def test_006_inverse_method(): a = t.Identity() b = a.inverse() # Identity is idempotent -- should get same transform back assert (f"{b}" == f"{a}" and f"{b}" == "Transform( Identity )") a = t.PlusOne_() assert (f"{a}" == "Transform( _PlusOne )") # PlusOne_ is non-idempotent - should get Inverse b = a.inverse() assert (f"{b}" == "Transform( Inverse _PlusOne )") # Inverting the inverse via method should unwrap the inversion c = b.inverse() assert (f"{a}" == f"{c}")
def test_012_resample(): # Since the main engine is in helpers (resmple is a wrapper), this is # really just a basic functionality test that the wrapper works right. # Makes use of Scale, which is in Basic -- but since this is a test, not # the main code, so there's no circular dependence. # Simple 7x5 array with a single nonzero spot a = np.zeros([7, 5]) # 7 tall, 5 wide a[2, 2] = 1 # Check that identity and shape specs work trans = t.Identity() b = trans.resample(a, method='nearest') assert (b.shape == (7, 5)) assert (np.all(b == a)) b = trans.resample(a, shape=[5, 5], method='nearest') assert (b.shape == (5, 5)) assert (np.all(a[0:5, 0:5] == b)) # Try scaling up by a factor of 2.5 -- this should make a 3x3 square # of ones trans = t.Scale(2.5, post=[2, 2], pre=[-2, -2]) b = trans.resample(a, method='neares') assert (b.shape == (7, 5)) checkval = np.zeros([7, 5]) checkval[1:4, 1:4] = 1 assert (np.all(b == checkval)) # Check that anisotropy works in the correct direction trans = t.Scale([1, 2.5], post=[2, 2], pre=[-2, -2]) b = trans.resample(a, method='nearest') assert (b.shape == (7, 5)) checkval = np.zeros([7, 5]) checkval[1:4, 2] = 1 assert (np.all(b == checkval))
def test_013_remap(): # remap is all about scientific coordinates, so we have to gin up some # FITS headers. # The test article (a) is a simple asymmetric cross. a = np.zeros([7, 7]) a[1:5, 3] = 1 a[3, 0:5] = 1 ahdr = { 'SIMPLE': 'T', 'NAXIS': 2, 'NAXIS1': 7, 'NAXIS2': 7, 'CRPIX1': 4, 'CRPIX2': 4, 'CRVAL1': 0, 'CRVAL2': 0, 'CDELT1': 1, 'CDELT2': 1, 'CUNIT1': 'pixel', 'CUNIT2': 'pixel', 'CTYPE1': 'X', 'CTYPE2': 'Y' } trans = t.Identity() b = trans.remap({'data': a, 'header': ahdr}, method='nearest') assert (np.all(b['data'] == a)) # This tests actual transformation and also broadcast since # PlusOne_ is 1D and a is 2D # # The autoscaling ought to completely undo the plus-one, so this should # be a no-op except for incrementing CRVAL1. trans = t.PlusOne_() b = trans.remap({'data': a, 'header': ahdr}, method='nearest') assert (np.all(a == b['data'])) assert (b['header']['CRPIX1'] == 4) assert (b['header']['CRPIX2'] == 4) assert (b['header']['CRVAL1'] == 1) assert (b['header']['CRVAL2'] == 0) assert (b['header']['CDELT1'] == 1) assert (b['header']['CDELT2'] == 1) # This again tests autoscaling - scale(3) should expand everything, # but autoscaling should put it back. trans = t.Scale(3, dim=2) b = trans.remap({'data': a, 'header': ahdr}, method='nearest') assert (np.all(a == b['data'])) assert (b['header']['CRPIX1'] == 4) assert (b['header']['CRPIX2'] == 4) assert (b['header']['CRVAL1'] == 0) assert (b['header']['CRVAL2'] == 0) print(f"CDELT1 is {b['header']['CDELT1']}") assert (np.isclose(b['header']['CDELT1'], 3, atol=1e-10)) assert (np.isclose(b['header']['CDELT2'], 3, atol=1e-10)) # Test manual scaling of the output by setting the output_range # This *should* be a no-op # Note: output range is to/from the *edge* of the outermost pixel, # so the span is the full span of the image trans = t.Identity() b = trans.remap({ 'data': a, 'header': ahdr }, method='nearest', output_range=[[-3.5, 3.5], [-3.5, 3.5]]) assert (np.all(a == b['data'])) assert (b['header']['CRPIX1'] == 4) assert (b['header']['CRPIX2'] == 4) assert (b['header']['CRVAL1'] == 0) assert (b['header']['CRVAL2'] == 0) print(f"CDELT1 is {b['header']['CDELT1']}") assert (np.isclose(b['header']['CDELT1'], 1, atol=1e-10)) assert (np.isclose(b['header']['CDELT2'], 1, atol=1e-10)) b = trans.remap({ 'data': a, 'header': ahdr }, method='nearest', output_range=[[-3.5 / 3, 3.5 / 3], [-3.5 / 3, 3.5 / 3]]) expando = np.array([[0, 0, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 0, 0], [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], [0, 0, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 0, 0]]) assert (np.all(np.isclose(expando, b['data'], atol=1e-10))) assert (b['header']['CRPIX1'] == 4) assert (b['header']['CRPIX2'] == 4) assert (b['header']['CRVAL1'] == 0) assert (b['header']['CRVAL2'] == 0) assert (np.isclose(b['header']['CDELT1'], 1 / 3.0, atol=1e-10)) assert (np.isclose(b['header']['CDELT2'], 1 / 3.0, atol=1e-10)) trans = t.Scale(3, dim=2) b = trans.remap({ 'data': a, 'header': ahdr }, method='nearest', output_range=[[-3.5, 3.5], [-3.5, 3.5]]) assert (np.all(np.isclose(expando, b['data'], atol=1e-10))) assert (np.isclose(b['header']['CDELT1'], 1, atol=1e-10)) assert (np.isclose(b['header']['CDELT2'], 1, atol=1e-10))
def test_003_identity_apply(): a = t.Identity() b = np.array([1, 2]) c = a.apply(b) assert (np.all(b == c))
def test_002_identity_constructor(): a = t.Identity() assert (f"{a}" == "Transform( Identity )")
def test_008_wrap(): a = t.PlusOne_() b = t.Identity() c = t.Wrap(b, a) assert (f"{c}" == "Transform( ( (Inverse _PlusOne) o (Identity) o (_PlusOne) ) )")