Coverage for tests/testCatalogs.py : 11%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from __future__ import with_statement
2from builtins import zip
3from builtins import object
4import os
5import sqlite3
6import numpy as np
7import unittest
8import tempfile
9import shutil
10import lsst.utils.tests
11from lsst.sims.utils.CodeUtilities import sims_clean_up
12from lsst.sims.utils import ObservationMetaData
13from lsst.sims.catalogs.db import fileDBObject, CatalogDBObject
14from lsst.sims.catalogs.definitions import InstanceCatalog
15from lsst.sims.catalogs.decorators import compound
16from lsst.sims.utils import haversine, angularSeparation
19ROOT = os.path.abspath(os.path.dirname(__file__))
22def setup_module(module):
23 lsst.utils.tests.init()
26# a class of catalog that outputs all the significant figures in
27# ra and dec so that it can be read back in to make sure that our
28# Haversine-based query actually returns all of the points that
29# are inside the circular bound desired
30class BoundsCatalog(InstanceCatalog):
31 catalog_type = 'bounds_catalog'
32 refIdCol = 'id'
33 column_outputs = ['id', 'raJ2000', 'decJ2000']
35 default_formats = {'f': '%.20f'}
38def twice_fn(x):
39 return 2.0*x
42class TransformationCatalog(InstanceCatalog):
43 catalog_type = 'transformation_catalog'
44 refIdCol = 'id'
45 column_outputs = ['id', 'raJ2000', 'decJ2000']
46 default_formats = {'f': '%.12f'}
47 transformations = {'raJ2000': twice_fn}
50class BasicCatalog(InstanceCatalog):
51 catalog_type = 'basic_catalog'
52 refIdCol = 'id'
53 column_outputs = ['id', 'raJ2000', 'decJ2000', 'umag', 'gmag', 'rmag', 'imag',
54 'zmag', 'ymag']
56 default_formats = {'f': '%.12f'}
59class TestAstMixin(object):
60 @compound('ra_corr', 'dec_corr')
61 def get_points_corrected(self):
62 # Fake astrometric correction
63 ra_corr = self.column_by_name('raJ2000')+0.001
64 dec_corr = self.column_by_name('decJ2000')+0.001
65 return ra_corr, dec_corr
68class CustomCatalog(BasicCatalog, TestAstMixin):
69 catalog_type = 'custom_catalog'
70 refIdCol = 'id'
71 column_outputs = ['id', 'raJ2000', 'decJ2000', 'umag', 'gmag', 'rmag', 'imag',
72 'zmag', 'ymag', 'ra_corr', 'dec_corr']
75def compareFiles(file1, file2):
76 with open(file1) as fh:
77 str1 = "".join(fh.readlines())
78 with open(file2) as fh:
79 str2 = "".join(fh.readlines())
80 return str1 == str2
83def write_star_file_db(file_name):
85 np.random.seed(88)
86 nstars = 10000
87 ra = np.random.random_sample(nstars)*360.0
88 dec = (np.random.random_sample(nstars)-0.5)*180.0
89 umag = np.random.random_sample(nstars)*10.0 + 15.0
90 gmag = np.random.random_sample(nstars)*10.0 + 15.0
91 rmag = np.random.random_sample(nstars)*10.0 + 15.0
92 imag = np.random.random_sample(nstars)*10.0 + 15.0
93 zmag = np.random.random_sample(nstars)*10.0 + 15.0
94 ymag = np.random.random_sample(nstars)*10.0 + 15.0
96 with open(file_name, 'w') as output_file:
97 for ix, (rr, dd, um, gm, rm, im, zm, ym) in \
98 enumerate(zip(ra, dec, umag, gmag, rmag, imag, zmag, ymag)):
100 output_file.write('%d %.12f %.12f %.12f %.12f %.12f %.12f %.12f %.12f\n' %
101 (ix, rr, dd, um, gm, rm, im, zm, ym))
103 starDtype = np.dtype([('id', np.int),
104 ('raJ2000', np.float),
105 ('decJ2000', np.float),
106 ('umag', np.float),
107 ('gmag', np.float),
108 ('rmag', np.float),
109 ('imag', np.float),
110 ('zmag', np.float),
111 ('ymag', np.float)])
113 starDB = fileDBObject(file_name, runtable='stars', dtype=starDtype, idColKey='id')
114 starDB.raColName = 'raJ2000'
115 starDB.decColName = 'decJ2000'
117 controlData = np.genfromtxt(file_name, dtype=starDtype)
119 return starDB, controlData
122class InstanceCatalogTestCase(unittest.TestCase):
124 longMessage = True
126 @classmethod
127 def setUpClass(cls):
129 cls.scratch_dir = tempfile.mkdtemp(dir=ROOT, prefix="scratchSpace-")
130 cls.starTextName = os.path.join(cls.scratch_dir, 'icStarTestCatalog.txt')
132 if os.path.exists(cls.starTextName):
133 os.unlink(cls.starTextName)
135 cls.starDB, cls.starControlData = write_star_file_db(cls.starTextName)
137 @classmethod
138 def tearDownClass(cls):
140 if os.path.exists(cls.starTextName):
141 os.unlink(cls.starTextName)
142 if os.path.exists(cls.scratch_dir):
143 shutil.rmtree(cls.scratch_dir)
145 def setUp(self):
146 self.obsMd = ObservationMetaData(boundType = 'circle', pointingRA = 210.0, pointingDec = -60.0,
147 boundLength=20.0, mjd=52000., bandpassName='r')
149 def testStarLike(self):
150 """
151 Write a couple of catalogs. Verify that the objects that end up in the catalog fall
152 within the pointing and that the objects that do not end up in the catalog fall
153 outside of the pointing
154 """
156 catName = os.path.join(self.scratch_dir, '_starLikeCat.txt')
158 if os.path.exists(catName):
159 os.unlink(catName)
161 # this dtype corresponds to the outputs of the catalog
162 dtype = np.dtype([('id', np.int),
163 ('raJ2000', np.float),
164 ('decJ2000', np.float),
165 ('umag', np.float),
166 ('gmag', np.float),
167 ('rmag', np.float),
168 ('imag', np.float),
169 ('zmag', np.float),
170 ('ymag', np.float),
171 ('ra_corr', np.float),
172 ('dec_corr', np.float)])
174 t = self.starDB.getCatalog('custom_catalog', obs_metadata=self.obsMd)
175 t.write_catalog(catName)
177 testData = np.genfromtxt(catName, delimiter = ', ', dtype=dtype)
179 # make sure that something ended up in the catalog
180 self.assertGreater(len(testData), 0)
182 # iterate over the lines in the catalog
183 # verify that those line exist in the control data
184 # also verify that those lines fall within the requested field of view
185 for line in testData:
186 ic = np.where(self.starControlData['id'] == line['id'])[0][0]
187 self.assertAlmostEqual(line['umag'], self.starControlData['umag'][ic], 6)
188 self.assertAlmostEqual(line['gmag'], self.starControlData['gmag'][ic], 6)
189 self.assertAlmostEqual(line['rmag'], self.starControlData['rmag'][ic], 6)
190 self.assertAlmostEqual(line['imag'], self.starControlData['imag'][ic], 6)
191 self.assertAlmostEqual(line['zmag'], self.starControlData['zmag'][ic], 6)
192 self.assertAlmostEqual(line['ymag'], self.starControlData['ymag'][ic], 6)
193 self.assertAlmostEqual(line['raJ2000'], self.starControlData['raJ2000'][ic], 6)
194 self.assertAlmostEqual(line['decJ2000'], self.starControlData['decJ2000'][ic], 6)
195 self.assertAlmostEqual(line['ra_corr'], line['raJ2000']+0.001, 6)
196 self.assertAlmostEqual(line['dec_corr'], line['decJ2000']+0.001, 6)
197 dl = haversine(np.radians(line['raJ2000']), np.radians(line['decJ2000']),
198 self.obsMd._pointingRA, self.obsMd._pointingDec)
200 self.assertLess(np.degrees(dl), self.obsMd.boundLength)
202 # examine the lines that did not fall in the catalog
203 lines_not_in_catalog = []
204 for id_val in self.starControlData['id']:
205 if id_val not in testData['id']:
206 lines_not_in_catalog.append(id_val)
207 lines_not_in_catalog = np.array(lines_not_in_catalog)
209 self.assertGreater(len(lines_not_in_catalog), 0)
211 # make sure that those lines are, indeed, outside of the field of view
212 for ic in lines_not_in_catalog:
213 dl = haversine(self.obsMd._pointingRA, self.obsMd._pointingDec,
214 np.radians(self.starControlData['raJ2000'][ic]),
215 np.radians(self.starControlData['decJ2000'][ic]))
217 msg = '\nRA %e Dec %e\n' % (self.starControlData['raJ2000'][ic], self.starControlData['decJ2000'][ic])
218 msg += 'pointing RA %e Dec %e\n' % (self.obsMd.pointingRA, self.obsMd.pointingDec)
219 self.assertGreater(np.degrees(dl), self.obsMd.boundLength, msg=msg)
221 if os.path.exists(catName):
222 os.unlink(catName)
224 # now do the same thing for the basic catalog class
226 dtype = np.dtype([('id', np.int),
227 ('raJ2000', np.float),
228 ('decJ2000', np.float),
229 ('umag', np.float),
230 ('gmag', np.float),
231 ('rmag', np.float),
232 ('imag', np.float),
233 ('zmag', np.float),
234 ('ymag', np.float)])
236 t = self.starDB.getCatalog('basic_catalog', obs_metadata=self.obsMd)
237 t.write_catalog(catName)
239 testData = np.genfromtxt(catName, delimiter = ', ', dtype=dtype)
241 # make sure that something ended up in the catalog
242 self.assertGreater(len(testData), 0)
244 # iterate over the lines in the catalog
245 # verify that those line exist in the control data
246 # also verify that those lines fall within the requested field of view
247 for line in testData:
248 ic = np.where(self.starControlData['id'] == line['id'])[0][0]
249 self.assertAlmostEqual(line['umag'], self.starControlData['umag'][ic], 6)
250 self.assertAlmostEqual(line['gmag'], self.starControlData['gmag'][ic], 6)
251 self.assertAlmostEqual(line['rmag'], self.starControlData['rmag'][ic], 6)
252 self.assertAlmostEqual(line['imag'], self.starControlData['imag'][ic], 6)
253 self.assertAlmostEqual(line['zmag'], self.starControlData['zmag'][ic], 6)
254 self.assertAlmostEqual(line['ymag'], self.starControlData['ymag'][ic], 6)
255 self.assertAlmostEqual(line['raJ2000'], self.starControlData['raJ2000'][ic], 6)
256 self.assertAlmostEqual(line['decJ2000'], self.starControlData['decJ2000'][ic], 6)
257 dl = haversine(np.radians(line['raJ2000']), np.radians(line['decJ2000']),
258 self.obsMd._pointingRA, self.obsMd._pointingDec)
260 self.assertLess(np.degrees(dl), self.obsMd.boundLength)
262 # examine the lines that did not fall in the catalog
263 lines_not_in_catalog = []
264 for id_val in self.starControlData['id']:
265 if id_val not in testData['id']:
266 lines_not_in_catalog.append(id_val)
267 lines_not_in_catalog = np.array(lines_not_in_catalog)
269 self.assertGreater(len(lines_not_in_catalog), 0)
271 # make sure that those lines are, indeed, outside of the field of view
272 for ic in lines_not_in_catalog:
273 dl = haversine(self.obsMd._pointingRA, self.obsMd._pointingDec,
274 np.radians(self.starControlData['raJ2000'][ic]),
275 np.radians(self.starControlData['decJ2000'][ic]))
277 self.assertGreater(np.degrees(dl), self.obsMd.boundLength)
279 if os.path.exists(catName):
280 os.unlink(catName)
282 def test_transformation(self):
283 """
284 Test that transformations are applied to columns in an InstanceCatalog
285 """
286 catName = os.path.join(self.scratch_dir,
287 'transformation_catalog.txt')
289 if os.path.exists(catName):
290 os.unlink(catName)
292 t = self.starDB.getCatalog('transformation_catalog', obs_metadata=self.obsMd)
293 t.write_catalog(catName)
295 dtype = np.dtype([('id', np.int),
296 ('raJ2000', np.float),
297 ('decJ2000', np.float)])
299 testData = np.genfromtxt(catName, delimiter=', ', dtype=dtype)
300 self.assertGreater(len(testData), 0)
301 for line in testData:
302 ic = np.where(self.starControlData['id'] == line['id'])[0][0]
303 self.assertAlmostEqual(line['decJ2000'], self.starControlData['decJ2000'][ic], 5)
304 self.assertAlmostEqual(line['raJ2000'], 2.0*self.starControlData['raJ2000'][ic], 5)
306 if os.path.exists(catName):
307 os.unlink(catName)
309 def test_iter_catalog(self):
310 """
311 Test that iter_catalog returns the same results as write_catalog
312 """
314 obs = ObservationMetaData(pointingRA=10.0, pointingDec=-20.0,
315 boundLength=50.0, boundType='circle')
317 cat = BasicCatalog(self.starDB, obs_metadata=obs)
318 cat_name = os.path.join(self.scratch_dir, 'iter_catalog_control.txt')
319 cat.write_catalog(cat_name)
320 with open(cat_name, 'r') as in_file:
321 in_lines = in_file.readlines()
322 self.assertGreater(len(in_lines), 1)
323 self.assertLess(len(in_lines), len(self.starControlData))
325 cat = BasicCatalog(self.starDB, obs_metadata=obs)
326 line_ct = 0
327 for line in cat.iter_catalog():
328 str_line = '%d, %.12f, %.12f, %.12f, %.12f, %.12f, %.12f, %.12f, %.12f\n' % \
329 (line[0], line[1], line[2], line[3], line[4], line[5], line[6], line[7], line[8])
330 self.assertIn(str_line, in_lines)
331 line_ct += 1
332 self.assertEqual(line_ct, len(in_lines)-1)
334 if os.path.exists(cat_name):
335 os.unlink(cat_name)
337 def test_iter_catalog_chunks(self):
338 """
339 Test that iter_catalog_chunks returns the same results as write_catalog
340 """
342 obs = ObservationMetaData(pointingRA=10.0, pointingDec=-20.0,
343 boundLength=50.0, boundType='circle')
345 cat = BasicCatalog(self.starDB, obs_metadata=obs)
346 cat_name = os.path.join(self.scratch_dir, 'iter_catalog_chunks_control.txt')
347 cat.write_catalog(cat_name)
348 with open(cat_name, 'r') as in_file:
349 in_lines = in_file.readlines()
350 self.assertGreater(len(in_lines), 1)
351 self.assertLess(len(in_lines), len(self.starControlData))
353 cat = BasicCatalog(self.starDB, obs_metadata=obs)
354 line_ct = 0
355 for chunk, chunk_map in cat.iter_catalog_chunks(chunk_size=7):
356 for ix in range(len(chunk[0])):
357 str_line = '%d, %.12f, %.12f, %.12f, %.12f, %.12f, %.12f, %.12f, %.12f\n' % \
358 (chunk[0][ix], chunk[1][ix], chunk[2][ix], chunk[3][ix], chunk[4][ix],
359 chunk[5][ix], chunk[6][ix], chunk[7][ix], chunk[8][ix])
361 self.assertIn(str_line, in_lines)
362 line_ct += 1
364 self.assertEqual(line_ct, len(in_lines)-1)
366 if os.path.exists(cat_name):
367 os.unlink(cat_name)
371class boundingBoxTest(unittest.TestCase):
373 @classmethod
374 def setUpClass(cls):
375 cls.scratch_dir = tempfile.mkdtemp(dir=ROOT, prefix="scratchSpace-")
376 cls.starTextName = os.path.join(cls.scratch_dir,
377 'bbStarTestCatalog.txt')
379 cls.starDB, cls.starControlData = write_star_file_db(cls.starTextName)
381 @classmethod
382 def tearDownClass(cls):
383 sims_clean_up()
384 if os.path.exists(cls.starTextName):
385 os.unlink(cls.starTextName)
386 for file_name in os.listdir(cls.scratch_dir):
387 os.unlink(os.path.join(cls.scratch_dir, file_name))
388 if os.path.exists(cls.scratch_dir):
389 shutil.rmtree(cls.scratch_dir)
391 def setUp(self):
393 self.RAmin = 190.
394 self.RAmax = 210.
395 self.DECmin = -70.
396 self.DECmax = -50.
398 self.RAcenter = 200.
399 self.DECcenter = -60.
400 self.radius = 10.0
402 self.obsMdCirc = ObservationMetaData(boundType='circle',
403 pointingRA=self.RAcenter,
404 pointingDec=self.DECcenter,
405 boundLength=self.radius, mjd=52000., bandpassName='r')
407 self.obsMdBox = ObservationMetaData(boundType='box', pointingRA=0.5*(self.RAmax+self.RAmin),
408 pointingDec=0.5*(self.DECmin+self.DECmax),
409 boundLength=np.array([0.5*(self.RAmax-self.RAmin),
410 0.5*(self.DECmax-self.DECmin)]),
411 mjd=52000., bandpassName='r')
413 def testBoxBounds(self):
414 """
415 Make sure that box_bound_constraint in sims.catalogs.db.dbConnection.py
416 does not admit any objects outside of the bounding box
417 """
419 catName = os.path.join(self.scratch_dir, 'box_test_catalog.txt')
421 myCatalog = self.starDB.getCatalog('bounds_catalog', obs_metadata = self.obsMdBox)
423 myIterator = myCatalog.iter_catalog(chunk_size=10)
425 for line in myIterator:
426 self.assertGreater(line[1], self.RAmin)
427 self.assertLess(line[1], self.RAmax)
428 self.assertGreater(line[2], self.DECmin)
429 self.assertLess(line[2], self.DECmax)
431 myCatalog.write_catalog(catName)
433 # now we will test for the completeness of the box bounds
435 dtype = np.dtype([('id', np.int),
436 ('raJ2000', np.float),
437 ('decJ2000', np.float)])
439 testData = np.genfromtxt(catName, dtype=dtype, delimiter=', ')
441 for line in testData:
442 self.assertGreater(line['raJ2000'], self.RAmin)
443 self.assertGreater(line['decJ2000'], self.DECmin)
444 self.assertLess(line['raJ2000'], self.RAmax)
445 self.assertLess(line['decJ2000'], self.DECmax)
447 ct = 0
448 for line in self.starControlData:
449 if line['id'] not in testData['id']:
450 ct += 1
451 in_bounds = ((line['raJ2000'] < self.RAmax) and (line['raJ2000'] > self.RAmin) and
452 (line['decJ2000'] < self.DECmax) and (line['decJ2000'] > self.DECmin))
454 msg = 'violates bounds\nRA: %e < %e <%e\nDec: %e < %e < %e\n' % \
455 (self.RAmin, line['raJ2000'], self.RAmax,
456 self.DECmin, line['decJ2000'], self.DECmax)
458 self.assertFalse(in_bounds, msg=msg)
460 self.assertGreater(ct, 0)
462 if os.path.exists(catName):
463 os.unlink(catName)
465 def testCircBounds(self):
467 """
468 Make sure that circular_bound_constraint in sims.catalogs.db.dbConnection.py
469 does not admit any objects outside of the bounding circle
470 """
472 catName = os.path.join(self.scratch_dir,
473 'circular_test_catalog.txt')
475 if os.path.exists(catName):
476 os.unlink(catName)
478 myCatalog = self.starDB.getCatalog('bounds_catalog', obs_metadata = self.obsMdCirc)
479 myIterator = myCatalog.iter_catalog(chunk_size=10)
481 for line in myIterator:
482 rtest = np.degrees(haversine(np.radians(self.RAcenter), np.radians(self.DECcenter),
483 np.radians(line[1]), np.radians(line[2])))
485 self.assertLess(rtest, self.radius)
487 myCatalog.write_catalog(catName)
489 # now we will test for the completeness of the circular bounds
491 dtype = np.dtype([('id', np.int),
492 ('raJ2000', np.float),
493 ('decJ2000', np.float)])
495 testData = np.genfromtxt(catName, dtype=dtype, delimiter=', ')
497 self.assertGreater(len(testData), 0)
499 for line in testData:
500 dl = np.degrees(haversine(np.radians(line['raJ2000']), np.radians(line['decJ2000']),
501 np.radians(self.RAcenter), np.radians(self.DECcenter)))
503 self.assertLess(dl, self.radius)
505 ct = 0
506 for line in self.starControlData:
507 if line['id'] not in testData['id']:
508 ct += 1
509 dl = np.degrees(haversine(np.radians(line['raJ2000']), np.radians(line['decJ2000']),
510 np.radians(self.RAcenter), np.radians(self.DECcenter)))
512 self.assertGreater(dl, self.radius)
514 self.assertGreater(ct, 0)
516 if os.path.exists(catName):
517 os.unlink(catName)
519 def test_negative_RA(self):
520 """
521 Test that spatial queries behave correctly around RA=0
522 """
523 rng = np.random.RandomState(81234122)
524 db_name = os.path.join(self.scratch_dir, 'neg_ra.db')
525 with sqlite3.connect(db_name) as connection:
526 cursor = connection.cursor()
527 cursor.execute('''CREATE TABLE neg_ra_table
528 (cat_id int, ra real, dec real)''')
530 connection.commit()
531 n_samples = 1000
532 id_val = np.arange(n_samples, dtype=int) + 1
533 ra = 10.0*(rng.random_sample(n_samples)-0.5)
534 dec = rng.random_sample(n_samples)-0.5
535 values = ((int(ii), rr, dd) for ii, rr, dd in zip(id_val, ra, dec))
536 cursor.executemany('''INSERT INTO neg_ra_table VALUES (?, ?, ?)''', values)
537 connection.commit()
539 class negativeRaCatalogDBClass(CatalogDBObject):
540 tableid = 'neg_ra_table'
541 idColKey = 'cat_id'
542 raColName = 'ra'
543 decColName = 'dec'
544 objectTypeId = 126
546 class negativeRaCatalogClass(InstanceCatalog):
547 column_outputs = ['cat_id', 'ra', 'dec']
548 delimiter = ' '
550 db = negativeRaCatalogDBClass(database=db_name, driver='sqlite')
552 boundLength=0.2
553 pra = 359.9
554 pdec = 0.0
555 obs = ObservationMetaData(pointingRA=pra, pointingDec=pdec,
556 boundType='circle', boundLength=boundLength)
559 cat = negativeRaCatalogClass(db, obs_metadata=obs)
560 cat_name = os.path.join(self.scratch_dir, 'neg_ra_cat.txt')
561 cat.write_catalog(cat_name)
562 valid = np.where(angularSeparation(pra, pdec, ra, dec)<boundLength)
563 self.assertGreater(len(valid[0]), 0)
564 self.assertLess(len(valid[0]), n_samples)
565 valid_pos = np.where(np.logical_and(angularSeparation(pra, pdec, ra, dec)<boundLength,
566 ra>0.0))
567 valid_neg = np.where(np.logical_and(angularSeparation(pra, pdec, ra, dec)<boundLength,
568 ra<0.0))
569 self.assertGreater(len(valid_pos[0]), 0)
570 self.assertGreater(len(valid_neg[0]), 0)
571 self.assertLess(len(valid_pos[0]), len(valid[0]))
572 valid_id = id_val[valid]
573 valid_ra = ra[valid]
574 valid_dec = dec[valid]
576 cat_dtype = np.dtype([('cat_id', int), ('ra', float), ('dec', float)])
577 cat_data = np.genfromtxt(cat_name, dtype=cat_dtype)
578 np.testing.assert_array_equal(cat_data['cat_id'], valid_id)
579 np.testing.assert_array_almost_equal(cat_data['ra'], valid_ra, decimal=3)
580 np.testing.assert_array_almost_equal(cat_data['dec'], valid_dec, decimal=3)
582 # now try it when RA is specified as negative
583 pra = -0.1
584 pdec = 0.0
585 obs = ObservationMetaData(pointingRA=pra, pointingDec=pdec,
586 boundType='circle', boundLength=boundLength)
588 cat = negativeRaCatalogClass(db, obs_metadata=obs)
589 cat.write_catalog(cat_name)
591 cat_data = np.genfromtxt(cat_name, dtype=cat_dtype)
592 np.testing.assert_array_equal(cat_data['cat_id'], valid_id)
593 np.testing.assert_array_almost_equal(cat_data['ra'], valid_ra, decimal=3)
594 np.testing.assert_array_almost_equal(cat_data['dec'], valid_dec, decimal=3)
596 # test it on a box
597 pra = 359.9
598 pdec = 0.0
599 obs = ObservationMetaData(pointingRA=pra, pointingDec=pdec,
600 boundType='box', boundLength=boundLength)
602 cat = negativeRaCatalogClass(db, obs_metadata=obs)
603 dec_min = pdec-boundLength
604 dec_max = pdec+boundLength
606 valid_id = []
607 valid_ra = []
608 valid_dec = []
609 for rr, dd, ii in zip(ra, dec, id_val):
610 if dd>dec_max or dd<dec_min:
611 continue
612 if np.abs(rr+0.1)<boundLength:
613 valid_id.append(ii)
614 valid_ra.append(rr)
615 valid_dec.append(dd)
616 valid_id = np.array(valid_id)
617 valid_ra = np.array(valid_ra)
618 valid_dec = np.array(valid_dec)
620 cat.write_catalog(cat_name)
621 cat_data = np.genfromtxt(cat_name, dtype=cat_dtype)
622 np.testing.assert_array_equal(cat_data['cat_id'], valid_id)
623 np.testing.assert_array_almost_equal(cat_data['ra'], valid_ra, decimal=3)
624 np.testing.assert_array_almost_equal(cat_data['dec'], valid_dec, decimal=3)
626 # try when defined at negative
627 pra = -0.1
628 pdec = 0.0
629 obs = ObservationMetaData(pointingRA=pra, pointingDec=pdec,
630 boundType='box', boundLength=boundLength)
632 cat = negativeRaCatalogClass(db, obs_metadata=obs)
633 cat.write_catalog(cat_name)
634 cat_data = np.genfromtxt(cat_name, dtype=cat_dtype)
635 np.testing.assert_array_equal(cat_data['cat_id'], valid_id)
636 np.testing.assert_array_almost_equal(cat_data['ra'], valid_ra, decimal=3)
637 np.testing.assert_array_almost_equal(cat_data['dec'], valid_dec, decimal=3)
638 del db
639 if os.path.exists(db_name):
640 os.unlink(db_name)
642 def test_very_positive_RA(self):
643 """
644 Test that spatial queries behave correctly around RA=0 (when RA>350)
645 """
646 rng = np.random.RandomState(81234122)
647 db_name = os.path.join(self.scratch_dir, 'very_pos_ra.db')
648 with sqlite3.connect(db_name) as connection:
649 cursor = connection.cursor()
650 cursor.execute('''CREATE TABLE neg_ra_table
651 (cat_id int, ra real, dec real)''')
653 connection.commit()
654 n_samples = 1000
655 id_val = np.arange(n_samples, dtype=int) + 1
656 ra = 10.0*(rng.random_sample(n_samples)-0.5)
657 neg_dex = np.where(ra<0.0)
658 ra[neg_dex] += 360.0
659 dec = rng.random_sample(n_samples)-0.5
660 values = ((int(ii), rr, dd) for ii, rr, dd in zip(id_val, ra, dec))
661 cursor.executemany('''INSERT INTO neg_ra_table VALUES (?, ?, ?)''', values)
662 connection.commit()
664 class veryPositiveRaCatalogDBClass(CatalogDBObject):
665 tableid = 'neg_ra_table'
666 idColKey = 'cat_id'
667 raColName = 'ra'
668 decColName = 'dec'
669 objectTypeId = 126
671 class veryPositiveRaCatalogClass(InstanceCatalog):
672 column_outputs = ['cat_id', 'ra', 'dec']
673 delimiter = ' '
675 db = veryPositiveRaCatalogDBClass(database=db_name, driver='sqlite')
677 boundLength=0.2
678 pra = 359.9
679 pdec = 0.0
680 obs = ObservationMetaData(pointingRA=pra, pointingDec=pdec,
681 boundType='circle', boundLength=boundLength)
684 cat = veryPositiveRaCatalogClass(db, obs_metadata=obs)
685 cat_name = os.path.join(self.scratch_dir, 'very_pos_ra_cat.txt')
686 cat.write_catalog(cat_name)
687 valid = np.where(angularSeparation(pra, pdec, ra, dec)<boundLength)
688 self.assertGreater(len(valid[0]), 0)
689 self.assertLess(len(valid[0]), n_samples)
690 valid_pos = np.where(np.logical_and(angularSeparation(pra, pdec, ra, dec)<boundLength,
691 ra<350.0))
692 valid_neg = np.where(np.logical_and(angularSeparation(pra, pdec, ra, dec)<boundLength,
693 ra>350.0))
694 self.assertGreater(len(valid_pos[0]), 0)
695 self.assertGreater(len(valid_neg[0]), 0)
696 self.assertLess(len(valid_pos[0]), len(valid[0]))
697 valid_id = id_val[valid]
698 valid_ra = ra[valid]
699 valid_dec = dec[valid]
701 cat_dtype = np.dtype([('cat_id', int), ('ra', float), ('dec', float)])
702 cat_data = np.genfromtxt(cat_name, dtype=cat_dtype)
703 np.testing.assert_array_equal(cat_data['cat_id'], valid_id)
704 np.testing.assert_array_almost_equal(cat_data['ra'], valid_ra, decimal=3)
705 np.testing.assert_array_almost_equal(cat_data['dec'], valid_dec, decimal=3)
707 # now try it when RA is specified as negative
708 pra = -0.1
709 pdec = 0.0
710 obs = ObservationMetaData(pointingRA=pra, pointingDec=pdec,
711 boundType='circle', boundLength=boundLength)
713 cat = veryPositiveRaCatalogClass(db, obs_metadata=obs)
714 cat.write_catalog(cat_name)
716 cat_data = np.genfromtxt(cat_name, dtype=cat_dtype)
717 np.testing.assert_array_equal(cat_data['cat_id'], valid_id)
718 np.testing.assert_array_almost_equal(cat_data['ra'], valid_ra, decimal=3)
719 np.testing.assert_array_almost_equal(cat_data['dec'], valid_dec, decimal=3)
721 # test it on a box
722 pra = 359.9
723 pdec = 0.0
724 obs = ObservationMetaData(pointingRA=pra, pointingDec=pdec,
725 boundType='box', boundLength=boundLength)
727 cat = veryPositiveRaCatalogClass(db, obs_metadata=obs)
729 dec_min = pdec-boundLength
730 dec_max = pdec+boundLength
732 valid_id = []
733 valid_ra = []
734 valid_dec = []
735 for rr, dd, ii in zip(ra, dec, id_val):
736 if dd>dec_max or dd<dec_min:
737 continue
738 if np.abs(rr-359.9)<boundLength or (rr+0.1)<boundLength:
739 valid_id.append(ii)
740 valid_ra.append(rr)
741 valid_dec.append(dd)
742 valid_id = np.array(valid_id)
743 valid_ra = np.array(valid_ra)
744 valid_dec = np.array(valid_dec)
746 cat.write_catalog(cat_name)
747 cat_data = np.genfromtxt(cat_name, dtype=cat_dtype)
748 np.testing.assert_array_equal(cat_data['cat_id'], valid_id)
749 np.testing.assert_array_almost_equal(cat_data['ra'], valid_ra, decimal=3)
750 np.testing.assert_array_almost_equal(cat_data['dec'], valid_dec, decimal=3)
752 # try when defined at negative
753 pra = -0.1
754 pdec = 0.0
755 obs = ObservationMetaData(pointingRA=pra, pointingDec=pdec,
756 boundType='box', boundLength=boundLength)
758 cat = veryPositiveRaCatalogClass(db, obs_metadata=obs)
759 cat.write_catalog(cat_name)
760 cat_data = np.genfromtxt(cat_name, dtype=cat_dtype)
761 np.testing.assert_array_equal(cat_data['cat_id'], valid_id)
762 np.testing.assert_array_almost_equal(cat_data['ra'], valid_ra, decimal=3)
763 np.testing.assert_array_almost_equal(cat_data['dec'], valid_dec, decimal=3)
764 del db
765 if os.path.exists(db_name):
766 os.unlink(db_name)
769class MemoryTestClass(lsst.utils.tests.MemoryTestCase):
770 pass
773if __name__ == "__main__": 773 ↛ 774line 773 didn't jump to line 774, because the condition on line 773 was never true
774 lsst.utils.tests.init()
775 unittest.main()