File: pgspheretest.py

package info (click to toggle)
gavodachs 2.11%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 8,972 kB
  • sloc: python: 100,078; xml: 3,014; javascript: 2,360; ansic: 918; sh: 216; makefile: 31
file content (229 lines) | stat: -rw-r--r-- 8,093 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
"""
Unit tests for our pgsphere interface.
"""

#c Copyright 2008-2024, the GAVO project <gavo@ari.uni-heidelberg.de>
#c
#c This program is free software, covered by the GNU GPL.  See the
#c COPYING file in the source distribution.


from astropy import units as u

from gavo.helpers import testhelpers

from gavo import utils
from gavo.stc import bboxes
from gavo.utils import DEG
from gavo.utils import pgsphere

import tresc


# this is http://alasky.u-strasbg.fr/footprints/cats/vizier/I/206?product=MOC&nside=64
_SAMPLE_FITS_MOC = utils.getDirtyBytes("""
eJztl2tMW2Ucxh810WhijNH4QY05iRq2qEOI2eYFI20PUGxPO9rKZbqtQGFFKKNQKAiJTjeNt206
3eYE4m2aZYOp87YpxGxeolHHFplm4gSdGjM1Xpbsg7dfwUQyKQRcjInnSX4f+p7zPu//9ianAbfX
7zENI8eYQEEj0yiOR5uaIjGjvNXw+pxGTbg5bOT63cYs/5y8SDwWbUhEZo/b4nAH/e6SNH7zJ1qc
XFZuiTtgpPG7fPp+Bf6SVBoT+80l3wIz1+OPJg1vorYp6otXRuKGs745Eg9XR4y68DJjVl04adSn
1kfTNkuCpuVKW79pa9TMli1btmzZsmXL1n9Wqc+/gNtn5RgZDrcVzHV4zIxxj//6nqwY/xGZXv/q
93P2DP2y0vhdMUO/7An9sudlTd/P7/SFrODx+7+QP5nfDOIL5rlNjytwHP18Rd7RfmRkFY4tZUy+
Ywq/YKnfHPNjDk3PMX6ZBrMcqU1NdWqoQ5Z7gRFL1JXzL2li+RyBxRZOafqbaVhju+urjGUp58Yp
4vMVucwit5VPfNbo6cfG543Eq6OxaoNb6TKNcKzSsMxA0HSN3qq/y+nDMVAawM/559I/qp/9/82W
LVu2bNmaWlJuBwzAIPwmOR6B/TAE30rO+bAe+mEXsO76QDJdcAdsga+kvCfhRSm/EX6XCrzwPnwv
uQUnAD7ul6VC3ilcAc/ATnhNuv5CuAzmQjWsgSdgk+Q5BRZIXt717pGs86AQFkE3DEv+TGnBfVIR
eQROhbNhHXwIn0vB06UQMYTYFyLn0CvwnnTDlbAcboeH4Cep+CQgxuJ7pRLyKr0HOqUy8ijDu2wO
cF7ZVXBYWpgNxHzjbGnRPGnx+dKSr6Xy76QK8qngWcXbUuVZEIYH4CUgtsoRKXIBmFJVBuBdRR+q
24C6LvVDMfwgRa8B6h7leQ0x1bwj1Z4LO6RYr1S/AX6UGsivgXfi10mNUdgI9KbxVdgLv0hN1C5x
GjADCeJPXA0LgbonHgN6k3gW3gTmI0GszXfBC4BXC/taOK/lGylJLZKclaRASTySz0utF8GlwLNW
4m7NAfrQRg/azgBybcuDh+Fx6ZZrYbfUTq/byam9DlYDzzroXQe97eB3x7vws3RrjbT8JqAuK1qk
lazfH5NWOeCotPp1aQ3xPJgAZnftiXCOtH67tIFzNxLLoyGpk3p3srdrJTBvXcxPNz3rrgBmq5s+
dRPXJuJ7ulXazH3YTF+39Ehb6dHW26QeatBDTXsZ9F7mddsb0nPksJ0a7Vgi7WSe+si5j/vS96vU
T136iau/S9pFb3bfLb3FndpzRBpYCsztAHM3QP33OqV95L8vDvR2EN9Bct9fKX3E748vAeb0AHfr
AOd+Qq5D9HyImf70YlgL1PAg+R3kLn7GO8PlgMcwMz28TRo5GejTSBAiwF0YuROIa+Qp6YtVcEg6
dLN0+EzpyJfSUWK3ZcuWLVu2/p/6A9x9I/E=""")


class AsPolyTest(testhelpers.VerboseTest):
	def _assertCircleBecomesPolygon(self, alpha, delta, radius):
		alpha, delta, radius = alpha*DEG, delta*DEG, radius*DEG
		c = pgsphere.SCircle(pgsphere.SPoint(alpha, delta), radius)
		poly = c.asPoly()
		for pt in poly.points:
			self.assertAlmostEqual(radius,
				bboxes.angular_separation(
					pt.x*u.rad, pt.y*u.rad, alpha*u.rad, delta*u.rad).to(u.rad).value)
	
	def testCircle1AsPoly(self):
		self._assertCircleBecomesPolygon(0, 90, 3)

	def testCircle2AsPoly(self):
		self._assertCircleBecomesPolygon(0, 0, 8)

	def testCircle3AsPoly(self):
		self._assertCircleBecomesPolygon(80, -10, 20)

	def testCircle4AsPoly(self):
		self._assertCircleBecomesPolygon(120, -80, 1)

	def testCircle5AsPoly(self):
		self._assertCircleBecomesPolygon(220, -45, 1)

	def testCircle6AsPoly(self):
		self._assertCircleBecomesPolygon(320, 45, 90)

	def testPolyAsPoly(self):
		p = pgsphere.SPoly([pgsphere.SPoint(*p) for p in
			((0.5, 0.4), (1, -0.2), (1.5, 0))])
		self.assertTrue(p.asPoly() is p)
	
	def testNormSboxAsPoly(self):
		b = pgsphere.SBox(pgsphere.SPoint(0.2, -0.5), pgsphere.SPoint(2, 0.1))
		self.assertEqual(b.asPoly(),
			pgsphere.SPoly([pgsphere.SPoint(*p) for p in
			((0.2, -0.5), (0.2, 0.1), (2, 0.1), (2, -0.5))]))

	def testInvSboxAsPoly(self):
		b = pgsphere.SBox(pgsphere.SPoint(2, 0.1), pgsphere.SPoint(-0.1, -0.5))
		self.assertEqual(b.asPoly(),
			pgsphere.SPoly([pgsphere.SPoint(*p) for p in
			((-0.1, -0.5), (-0.1, 0.1), (2, 0.1), (2, -0.5))]))


class FromDALITest(testhelpers.VerboseTest):
	def testShortPolyDALIConstructor(self):
		self.assertRaisesWithMsg(ValueError,
			"Need an even-numbered number (>=6) of floats in a DALI polygon representation, got 4 floats.",
			pgsphere.SPoly.fromDALI,
			([1, 1, 2, 2],))

	def testOddPolyDALIConstructor(self):
		self.assertRaisesWithMsg(ValueError,
			"Need an even-numbered number (>=6) of floats in a DALI polygon representation, got 7 floats.",
			pgsphere.SPoly.fromDALI,
			([-1.5372606267401516, 85.26415832196923, -1.5372606267401516, 85.25833260227361, -1.5401725504711685, 85.25541973647518, -1.5416285063290134],))

	def testCoveringCircle(self):
		points = [pgsphere.SPoint.fromDegrees(*v) for v in [
			(2, 3), (355, -9), (0, 0)]]
		c = pgsphere.SCircle.fromPointSet(points)
		self.assertEqual(c.asSTCS("X"),
			"Circle X 359.0157337607 -1.9990620034 6.2881158141")


class MOCDryTest(testhelpers.VerboseTest):
	def testBadMOCRandom(self):
		self.assertRaisesWithMsg(ValueError,
			"No order separator visible in MOC literal 'Habe nun Philosophie"
				"/Juristerei/Medic...'",
			pgsphere.SMoc.fromASCII,
			("Habe nun Philosophie/Juristerei/Medicin und leider ach Theologie",))

	def testBadMOCJunkAtStart(self):
		self.assertRaisesWithMsg(ValueError,
			"MOC literal 'Habe 1/3,4 3/45,9' does not start with order spec",
			pgsphere.SMoc.fromASCII,
			("Habe 1/3,4 3/45,9",))
	
	def testJunkInCenter(self):
		self.assertRaisesWithMsg(ValueError,
			"MOC literal syntax error at char 4",
			pgsphere.SMoc.fromASCII,
			("1/3, Habe, 4 3/45,9",))

	def testMOCConstruction(self):
		m = pgsphere.SMoc.fromASCII("1/1\n3 4 2/4 25 12-14 21")
		self.assertEqual(m.moc[2], frozenset([4, 12, 13, 14, 21, 25]))

	def testFITSConstructor(self):
		m = pgsphere.SMoc.fromFITS(_SAMPLE_FITS_MOC)
		self.assertTrue(14400 in m.moc[6])

	def testToASCII(self):
		m = pgsphere.SMoc.fromASCII("1/1,3,4 2/4,25,12-14,21")
		self.assertEqual(m.asASCII(),
			"1/1 3-4 2/4 12-14 21 25")

	def testMocFromPoly(self):
		m = pgsphere.SPoly.fromDALI([0, 0, 45, 0, 0, 90]).asSMoc(order=4)
		self.assertEqual(m.asASCII(),
			'1/2 2/2 14 71 77 3/2 14 50 62 279 283 305 317'
			' 4/2 14 50 62 194 206 242 254 1111 1115 1127 1131 1217 1229 1265 1277'
			' 4/')
	
	def testMocFromCircle(self):
		m = pgsphere.SCircle.fromDALI([-50, 33, 2]).asPoly().asSMoc()
		self.assertEqual(m.asASCII(),
			'5/3309 6/13233-13235 13240-13241 13243-13246 13280 13282 6/')

	def testMocFromCircleInclusive(self):
		m = pgsphere.SCircle.fromDALI([-50, 33, 2]).asPoly().asSMoc(inclusive=True)
		self.assertEqual(m.asASCII(),
			'4/827 6/13211 13214-13215 13258 13280 13282 13288 13290 14609 14612 6/')

	def testCircleSMoc(self):
		c = pgsphere.SCircle.fromDALI([250, -79, 0.25])
		self.assertEqual(
			c.asSMoc(order=7).asSTCS("X"),
			"MOC 7/164157 7/")
	
	def testMaxOrderParsed(self):
		m = pgsphere.SMoc.fromASCII("3/5,6 7/")
		self.assertEqual(m.maxOrder, 7)
	
	def testMaxOrderSerialialised(self):
		m = pgsphere.SMoc.fromASCII("7/ 0/1-2")
		self.assertEqual(m.asASCII(), "0/1-2 7/")
	
	def testMaxOrderWithRegrid(self):
		m = pgsphere.SMoc.fromASCII("4/55 9/40031-43210")
		m2 = m.asSMoc(3)
		self.assertEqual(m2.maxOrder, 3)

	def testMaxOrderLower(self):
		m = pgsphere.SMoc.fromASCII("0/2-3 4/")
		m2 = m.asSMoc(7)
		self.assertEqual(m2.maxOrder, 4)
	

class InDBTest(testhelpers.VerboseTest):
	resources = [("conn", tresc.dbConnection)]

	def makeTable(self, testedType, testValue):
		self.conn.execute("CREATE TABLE pgstest (col %s)"%testedType)
		self.conn.execute("INSERT INTO pgstest (col) VALUES (%(val)s)",
			{"val": testValue})

	def assertTripsRound(self, testedType, testValue):
		try:
			self.makeTable(testedType, testValue)
			res = list(self.conn.query("SELECT * from pgstest"))
			self.assertEqual(res[0][0], testValue)
		finally:
			self.conn.rollback()

	def testSPoints(self):
		self.assertTripsRound("spoint", pgsphere.SPoint(2,0.5))

	def testSCircle(self):
		self.assertTripsRound("scircle",
			pgsphere.SCircle(pgsphere.SPoint(2,0.5), 0.25))

	def testSPoly(self):
		self.assertTripsRound("spoly",
			pgsphere.SPoly([pgsphere.SPoint(2,0.5),
				pgsphere.SPoint(2.5,-0.5),
				pgsphere.SPoint(1.5,0),]))

	def testSBox(self):
		self.assertTripsRound("sbox",
			pgsphere.SBox(pgsphere.SPoint(2.5,-0.5),
				pgsphere.SPoint(2.0,0.5)))

	def testSMocRoundTrip(self):
		self.assertTripsRound("smoc",
			pgsphere.SMoc.fromASCII('29/2-5,20-29,123,444,17-21,33-39,332-339,0-1'))


if __name__=="__main__":
	testhelpers.main(InDBTest)