Hide keyboard shortcuts

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 range 

3import os 

4import unittest 

5import sqlite3 

6import tempfile 

7import numpy as np 

8import lsst.utils.tests 

9from lsst.sims.utils.CodeUtilities import sims_clean_up 

10from lsst.sims.catUtils.utils import ObservationMetaDataGenerator 

11from lsst.sims.utils import CircleBounds, BoxBounds, altAzPaFromRaDec 

12from lsst.sims.utils import ObservationMetaData 

13from lsst.sims.catUtils.exampleCatalogDefinitions import PhoSimCatalogSersic2D 

14from lsst.sims.catUtils.exampleCatalogDefinitions import DefaultPhoSimHeaderMap 

15from lsst.sims.catUtils.utils import testGalaxyBulgeDBObj 

16from lsst.sims.catUtils.utils import makePhoSimTestDB 

17from lsst.utils import getPackageDir 

18 

19ROOT = os.path.abspath(os.path.dirname(__file__)) 

20 

21 

22def setup_module(module): 

23 lsst.utils.tests.init() 

24 

25 

26def get_val_from_obs(tag, obs): 

27 """ 

28 tag is the name of a data column 

29 

30 obs is an ObservationMetaData 

31 

32 returns the value of 'tag' for this obs 

33 """ 

34 if tag == 'fieldRA': 

35 return obs.pointingRA 

36 elif tag == 'fieldDec': 

37 return obs.pointingDec 

38 elif tag == 'rotSkyPos': 

39 return obs.rotSkyPos 

40 elif tag == 'expMJD': 

41 return obs.mjd.TAI 

42 elif tag == 'airmass': 

43 alt, az, pa = altAzPaFromRaDec(obs.pointingRA, obs.pointingDec, obs) 

44 return 1.0/(np.cos(np.pi/2.0-np.radians(alt))) 

45 elif tag == 'm5': 

46 return obs.m5[obs.bandpass] 

47 elif tag == 'skyBrightness': 

48 return obs.skyBrightness 

49 elif tag == 'seeing': 

50 return obs.seeing[obs.bandpass] 

51 elif tag == 'telescopeFilter': 

52 return obs.bandpass 

53 

54 transforms = {'dist2Moon': np.degrees, 

55 'moonAlt': np.degrees, 

56 'sunAlt': np.degrees, 

57 'moonRA': np.degrees, 

58 'moonDec': np.degrees} 

59 

60 if tag in transforms: 

61 return transforms[tag](obs.OpsimMetaData[tag]) 

62 

63 return obs.OpsimMetaData[tag] 

64 

65 

66def get_val_from_rec(tag, rec): 

67 """ 

68 tag is the name of a data column 

69 

70 rec is a record returned by a query to an OpSim database 

71 

72 returns the value of 'tag' for this rec 

73 """ 

74 if tag == 'telescopeFilter': 

75 return rec['filter'] 

76 elif tag == 'seeing': 

77 return rec['finSeeing'] # because the test opsim database uses the old schema 

78 elif tag == 'm5': 

79 return rec['fiveSigmaDepth'] 

80 elif tag == 'skyBrightness': 

81 return rec['filtSkyBrightness'] 

82 elif tag in ('fieldRA', 'fieldDec', 'moonRA', 'moonDec', 

83 'rotSkyPos', 'sunAlt', 'moonAlt', 'dist2Moon', 'altitude', 

84 'azimuth'): 

85 

86 return np.degrees(rec[tag]) 

87 

88 return rec[tag] 

89 

90 

91class ObservationMetaDataGeneratorTest(unittest.TestCase): 

92 

93 longMessage = True 

94 

95 @classmethod 

96 def tearDownClass(cls): 

97 sims_clean_up() 

98 

99 def setUp(self): 

100 

101 dbPath = os.path.join(getPackageDir('sims_data'), 

102 'OpSimData/opsimblitz1_1133_sqlite.db') 

103 

104 self.gen = ObservationMetaDataGenerator(database=dbPath, 

105 driver='sqlite') 

106 

107 def tearDown(self): 

108 del self.gen 

109 

110 def testExceptions(self): 

111 """ 

112 Make sure that RuntimeErrors get raised when they should 

113 """ 

114 gen = self.gen 

115 self.assertRaises(RuntimeError, gen.getObservationMetaData) 

116 self.assertRaises(RuntimeError, gen.getObservationMetaData, fieldRA=(1.0, 2.0, 3.0)) 

117 

118 def testQueryOnRanges(self): 

119 """ 

120 Test that ObservationMetaData objects returned by queries of the form 

121 min < value < max 

122 are, in fact, within that range. 

123 

124 Test when querying on both a single and two columns. 

125 """ 

126 gen = self.gen 

127 

128 # An list containing the bounds of our queries. 

129 # The order of the tuples must correspond to the order of 

130 # self.columnMapping in ObservationMetaDataGenerator. 

131 # This was generated with a separate script which printed 

132 # the median and maximum values of all of the quantities 

133 # in our test opsim database 

134 bounds = [('obsHistID', (5973, 7000)), 

135 ('fieldRA', (np.degrees(1.370916), np.degrees(1.40))), 

136 ('rawSeeing', (0.728562, 0.9)), 

137 ('seeing', (0.7, 0.9)), 

138 ('dist2Moon', (np.degrees(1.570307), np.degrees(1.9))), 

139 ('expMJD', (49367.129396, 49370.0)), 

140 ('m5', (22.815249, 23.0)), 

141 ('skyBrightness', (19.017605, 19.5))] 

142 

143 # test querying on a single column 

144 for line in bounds: 

145 tag = line[0] 

146 

147 args = {tag: line[1]} 

148 

149 results = gen.getObservationMetaData(**args) 

150 msg = "failed querying on %s" % tag 

151 self.assertGreater(len(results), 0, msg=msg) 

152 

153 for obs in results: 

154 val = get_val_from_obs(tag, obs) 

155 self.assertGreaterEqual(val, line[1][0], msg=msg) 

156 self.assertLessEqual(val, line[1][1], msg=msg) 

157 

158 # test querying on two columns at once 

159 for ix in range(len(bounds)): 

160 tag1 = bounds[ix][0] 

161 

162 for jx in range(ix+1, len(bounds)): 

163 tag2 = bounds[jx][0] 

164 

165 args = {} 

166 args[tag1] = bounds[ix][1] 

167 args[tag2] = bounds[jx][1] 

168 results = gen.getObservationMetaData(**args) 

169 msg = "failed querying %s and %s" % (tag1, tag2) 

170 self.assertGreater(len(results), 0, msg=msg) 

171 for obs in results: 

172 v1 = get_val_from_obs(tag1, obs) 

173 v2 = get_val_from_obs(tag2, obs) 

174 self.assertGreaterEqual(v1, bounds[ix][1][0], msg=msg) 

175 self.assertLessEqual(v1, bounds[ix][1][1], msg=msg) 

176 self.assertGreaterEqual(v2, bounds[jx][1][0], msg=msg) 

177 self.assertLessEqual(v2, bounds[jx][1][1], msg=msg) 

178 

179 def testOpSimQueryOnRanges(self): 

180 """ 

181 Test that getOpimRecords() returns correct results 

182 """ 

183 bounds = [('obsHistID', (5973, 7000)), 

184 ('fieldRA', (np.degrees(1.370916), np.degrees(1.40))), 

185 ('rawSeeing', (0.728562, 0.9)), 

186 ('seeing', (0.7, 0.9)), 

187 ('dist2Moon', (np.degrees(1.570307), np.degrees(1.9))), 

188 ('expMJD', (49367.129396, 49370.0)), 

189 ('m5', (22.815249, 23.0)), 

190 ('skyBrightness', (19.017605, 19.5))] 

191 

192 for line in bounds: 

193 tag = line[0] 

194 args = {tag: line[1]} 

195 results = self.gen.getOpSimRecords(**args) 

196 msg = 'failed querying %s ' % tag 

197 self.assertGreater(len(results), 0) 

198 for rec in results: 

199 val = get_val_from_rec(tag, rec) 

200 self.assertGreaterEqual(val, line[1][0], msg=msg) 

201 self.assertLessEqual(val, line[1][1], msg=msg) 

202 

203 for ix in range(len(bounds)): 

204 tag1 = bounds[ix][0] 

205 for jx in range(ix+1, len(bounds)): 

206 tag2 = bounds[jx][0] 

207 args = {tag1: bounds[ix][1], tag2: bounds[jx][1]} 

208 results = self.gen.getOpSimRecords(**args) 

209 msg = 'failed while querying %s and %s' % (tag1, tag2) 

210 self.assertGreater(len(results), 0) 

211 for rec in results: 

212 v1 = get_val_from_rec(tag1, rec) 

213 v2 = get_val_from_rec(tag2, rec) 

214 self.assertGreaterEqual(v1, bounds[ix][1][0], msg=msg) 

215 self.assertLessEqual(v1, bounds[ix][1][1], msg=msg) 

216 self.assertGreaterEqual(v2, bounds[jx][1][0], msg=msg) 

217 self.assertLessEqual(v2, bounds[jx][1][1], msg=msg) 

218 

219 def testQueryExactValues(self): 

220 """ 

221 Test that ObservationMetaData returned by a query demanding an exact value do, 

222 in fact, adhere to that requirement. 

223 """ 

224 gen = self.gen 

225 

226 bounds = [('obsHistID', 5973), 

227 ('expDate', 1220779), 

228 ('fieldRA', np.degrees(1.370916)), 

229 ('fieldDec', np.degrees(-0.456238)), 

230 ('moonRA', np.degrees(2.914132)), 

231 ('moonDec', np.degrees(0.06305)), 

232 ('rotSkyPos', np.degrees(3.116656)), 

233 ('telescopeFilter', 'i'), 

234 ('rawSeeing', 0.728562), 

235 ('seeing', 0.88911899999999999), 

236 ('sunAlt', np.degrees(-0.522905)), 

237 ('moonAlt', np.degrees(0.099096)), 

238 ('dist2Moon', np.degrees(1.570307)), 

239 ('moonPhase', 52.2325), 

240 ('expMJD', 49367.129396), 

241 ('visitExpTime', 30.0), 

242 ('m5', 22.815249), 

243 ('skyBrightness', 19.017605)] 

244 

245 for ii in range(len(bounds)): 

246 tag = bounds[ii][0] 

247 args = {} 

248 args[tag] = bounds[ii][1] 

249 results = gen.getObservationMetaData(**args) 

250 msg = 'failed querying %s' % tag 

251 self.assertGreater(len(results), 0, msg=msg) 

252 for obs in results: 

253 self.assertEqual(get_val_from_obs(tag, obs), bounds[ii][1], msg=msg) 

254 

255 def testOpSimQueryExact(self): 

256 """ 

257 Test that querying OpSim records for exact values works 

258 """ 

259 

260 bounds = [('obsHistID', 5973), 

261 ('expDate', 1220779), 

262 ('fieldRA', np.degrees(1.370916)), 

263 ('fieldDec', np.degrees(-0.456238)), 

264 ('moonRA', np.degrees(2.914132)), 

265 ('moonDec', np.degrees(0.06305)), 

266 ('rotSkyPos', np.degrees(3.116656)), 

267 ('telescopeFilter', 'i'), 

268 ('rawSeeing', 0.728562), 

269 ('seeing', 0.88911899999999999), 

270 ('sunAlt', np.degrees(-0.522905)), 

271 ('moonAlt', np.degrees(0.099096)), 

272 ('dist2Moon', np.degrees(1.570307)), 

273 ('moonPhase', 52.2325), 

274 ('expMJD', 49367.129396), 

275 ('visitExpTime', 30.0), 

276 ('m5', 22.815249), 

277 ('skyBrightness', 19.017605)] 

278 

279 for line in bounds: 

280 tag = line[0] 

281 args = {tag: line[1]} 

282 results = self.gen.getOpSimRecords(**args) 

283 msg = 'failed while querying %s' % tag 

284 self.assertGreater(len(results), 0, msg=msg) 

285 for rec in results: 

286 self.assertEqual(get_val_from_rec(tag, rec), line[1], msg=msg) 

287 

288 def testPassInOtherQuery(self): 

289 """ 

290 Test that you can pass OpSim pointings generated from another source 

291 into an ObservationMetaDataGenerator and still get ObservationMetaData 

292 out 

293 """ 

294 

295 pointing_list = self.gen.getOpSimRecords(fieldRA=np.degrees(1.370916)) 

296 self.assertGreater(len(pointing_list), 1) 

297 local_gen = ObservationMetaDataGenerator() 

298 obs_list = local_gen.ObservationMetaDataFromPointingArray(pointing_list) 

299 self.assertEqual(len(obs_list), len(pointing_list)) 

300 

301 for pp in pointing_list: 

302 obs = local_gen.ObservationMetaDataFromPointing(pp) 

303 self.assertIsInstance(obs, ObservationMetaData) 

304 

305 def testQueryLimit(self): 

306 """ 

307 Test that, when we specify a limit on the number of ObservationMetaData we want returned, 

308 that limit is respected 

309 """ 

310 gen = self.gen 

311 results = gen.getObservationMetaData(fieldRA=(np.degrees(1.370916), np.degrees(1.5348635)), 

312 limit=20) 

313 self.assertEqual(len(results), 20) 

314 

315 def testQueryOnFilter(self): 

316 """ 

317 Test that queries on the filter work. 

318 """ 

319 gen = self.gen 

320 results = gen.getObservationMetaData(fieldRA=np.degrees(1.370916), telescopeFilter='i') 

321 ct = 0 

322 for obs_metadata in results: 

323 self.assertAlmostEqual(obs_metadata._pointingRA, 1.370916) 

324 self.assertEqual(obs_metadata.bandpass, 'i') 

325 ct += 1 

326 

327 # Make sure that more than zero ObservationMetaData were returned 

328 self.assertGreater(ct, 0) 

329 

330 def testObsMetaDataBounds(self): 

331 """ 

332 Make sure that the bound specifications (i.e. a circle or a box on the 

333 sky) are correctly passed through to the resulting ObservationMetaData 

334 """ 

335 

336 gen = self.gen 

337 

338 # Test a cirlce with a specified radius 

339 results = gen.getObservationMetaData(fieldRA=np.degrees(1.370916), 

340 telescopeFilter='i', 

341 boundLength=0.9) 

342 ct = 0 

343 for obs_metadata in results: 

344 self.assertTrue(isinstance(obs_metadata.bounds, CircleBounds), 

345 msg='obs_metadata.bounds is not an intance of ' 

346 'CircleBounds') 

347 

348 # include some wiggle room, in case ObservationMetaData needs to 

349 # adjust the boundLength to accommodate the transformation between 

350 # ICRS and observed coordinates 

351 self.assertGreaterEqual(obs_metadata.bounds.radiusdeg, 0.9) 

352 self.assertLessEqual(obs_metadata.bounds.radiusdeg, 0.95) 

353 

354 self.assertAlmostEqual(obs_metadata.bounds.RA, 

355 np.radians(obs_metadata.pointingRA), 5) 

356 self.assertAlmostEqual(obs_metadata.bounds.DEC, 

357 np.radians(obs_metadata.pointingDec), 5) 

358 ct += 1 

359 

360 # Make sure that some ObservationMetaData were tested 

361 self.assertGreater(ct, 0) 

362 

363 boundLengthList = [1.2, (1.2, 0.6)] 

364 for boundLength in boundLengthList: 

365 results = gen.getObservationMetaData(fieldRA=np.degrees(1.370916), 

366 telescopeFilter='i', 

367 boundType='box', 

368 boundLength=boundLength) 

369 

370 if hasattr(boundLength, '__len__'): 

371 dra = boundLength[0] 

372 ddec = boundLength[1] 

373 else: 

374 dra = boundLength 

375 ddec = boundLength 

376 

377 ct = 0 

378 for obs_metadata in results: 

379 RAdeg = obs_metadata.pointingRA 

380 DECdeg = obs_metadata.pointingDec 

381 self.assertTrue(isinstance(obs_metadata.bounds, BoxBounds), 

382 msg='obs_metadata.bounds is not an instance of ' 

383 'BoxBounds') 

384 

385 self.assertAlmostEqual(obs_metadata.bounds.RAminDeg, RAdeg-dra, 10) 

386 

387 self.assertAlmostEqual(obs_metadata.bounds.RAmaxDeg, RAdeg+dra, 10) 

388 

389 self.assertAlmostEqual(obs_metadata.bounds.DECminDeg, DECdeg-ddec, 10) 

390 

391 self.assertAlmostEqual(obs_metadata.bounds.DECmaxDeg, DECdeg+ddec, 10) 

392 

393 self.assertAlmostEqual(obs_metadata.bounds.RA, np.radians(obs_metadata.pointingRA), 5) 

394 self.assertAlmostEqual(obs_metadata.bounds.DEC, np.radians(obs_metadata.pointingDec), 5) 

395 

396 ct += 1 

397 

398 # Make sure that some ObservationMetaData were tested 

399 self.assertGreater(ct, 0) 

400 

401 def testQueryOnNight(self): 

402 """ 

403 Check that the ObservationMetaDataGenerator can query on the 'night' 

404 column in the OpSim summary table 

405 """ 

406 

407 # the test database goes from night=0 to night=28 

408 # corresponding to 49353.032079 <= mjd <= 49381.38533 

409 night0 = 49353.032079 

410 

411 results = self.gen.getObservationMetaData(night=(11, 13)) 

412 

413 self.assertGreater(len(results), 1800) 

414 # there should be about 700 observations a night; 

415 # make sure we get at least 600 

416 

417 for obs in results: 

418 self.assertGreaterEqual(obs.mjd.TAI, night0+11.0) 

419 self.assertLessEqual(obs.mjd.TAI, night0+13.5) 

420 # the 0.5 is there because the last observation on night 13 could be 

421 # 13 days and 8 hours after the first observation on night 0 

422 self.assertGreaterEqual(obs._OpsimMetaData['night'], 11) 

423 self.assertLessEqual(obs._OpsimMetaData['night'], 13) 

424 

425 # query for an exact night 

426 results = self.gen.getObservationMetaData(night=15) 

427 

428 self.assertGreater(len(results), 600) 

429 # there should be about 700 observations a night; 

430 # make sure we get at least 600 

431 

432 for obs in results: 

433 self.assertEqual(obs._OpsimMetaData['night'], 15) 

434 self.assertGreaterEqual(obs.mjd.TAI, night0+14.9) 

435 self.assertLessEqual(obs.mjd.TAI, night0+15.9) 

436 

437 def testCreationOfPhoSimCatalog(self): 

438 """ 

439 Make sure that we can create PhoSim input catalogs using the returned 

440 ObservationMetaData. This test will just make sure that all of the 

441 expected header entries are there. 

442 """ 

443 

444 dbName = tempfile.mktemp(dir=ROOT, prefix='obsMetaDataGeneratorTest-', suffix='.db') 

445 makePhoSimTestDB(filename=dbName) 

446 bulgeDB = testGalaxyBulgeDBObj(driver='sqlite', database=dbName) 

447 gen = self.gen 

448 results = gen.getObservationMetaData(fieldRA=np.degrees(1.370916), 

449 telescopeFilter='i') 

450 testCat = PhoSimCatalogSersic2D(bulgeDB, obs_metadata=results[0]) 

451 testCat.phoSimHeaderMap = {} 

452 with lsst.utils.tests.getTempFilePath('.txt') as catName: 

453 testCat.write_catalog(catName) 

454 

455 if os.path.exists(dbName): 

456 os.unlink(dbName) 

457 

458 def testCreationOfPhoSimCatalog_2(self): 

459 """ 

460 Make sure that we can create PhoSim input catalogs using the returned 

461 ObservationMetaData. 

462 

463 Use the actual DefaultPhoSimHeader map; make sure that opsim_version 

464 does not make it into the header. 

465 """ 

466 

467 dbName = tempfile.mktemp(dir=ROOT, prefix='obsMetaDataGeneratorTest-', suffix='.db') 

468 makePhoSimTestDB(filename=dbName) 

469 bulgeDB = testGalaxyBulgeDBObj(driver='sqlite', database=dbName) 

470 gen = self.gen 

471 results = gen.getObservationMetaData(fieldRA=np.degrees(1.370916), 

472 telescopeFilter='i') 

473 testCat = PhoSimCatalogSersic2D(bulgeDB, obs_metadata=results[0]) 

474 testCat.phoSimHeaderMap = DefaultPhoSimHeaderMap 

475 with lsst.utils.tests.getTempFilePath('.txt') as catName: 

476 testCat.write_catalog(catName) 

477 ct_lines = 0 

478 with open(catName, 'r') as in_file: 

479 for line in in_file: 

480 ct_lines += 1 

481 self.assertNotIn('opsim_version', line) 

482 self.assertGreater(ct_lines, 10) # check that some lines did get written 

483 

484 if os.path.exists(dbName): 

485 os.unlink(dbName) 

486 

487 def testCreationOfPhoSimCatalog_3(self): 

488 """ 

489 Make sure that we can create PhoSim input catalogs using the returned 

490 ObservationMetaData. 

491 

492 Test that an error is actually raised if we try to build a PhoSim catalog 

493 with a v3 header map using a v4 ObservationMetaData 

494 """ 

495 

496 dbName = tempfile.mktemp(dir=ROOT, prefix='obsMetaDataGeneratorTest-', suffix='.db') 

497 makePhoSimTestDB(filename=dbName) 

498 bulgeDB = testGalaxyBulgeDBObj(driver='sqlite', database=dbName) 

499 opsim_db = os.path.join(getPackageDir('sims_data'), 'OpSimData', 

500 'astro-lsst-01_2014.db') 

501 assert os.path.isfile(opsim_db) 

502 gen = ObservationMetaDataGenerator(opsim_db, driver='sqlite') 

503 results = gen.getObservationMetaData(fieldRA=(70.0, 85.0), 

504 telescopeFilter='i') 

505 self.assertGreater(len(results), 0) 

506 testCat = PhoSimCatalogSersic2D(bulgeDB, obs_metadata=results[0]) 

507 testCat.phoSimHeaderMap = DefaultPhoSimHeaderMap 

508 with lsst.utils.tests.getTempFilePath('.txt') as catName: 

509 with self.assertRaises(RuntimeError): 

510 testCat.write_catalog(catName) 

511 

512 if os.path.exists(dbName): 

513 os.unlink(dbName) 

514 

515 

516class ObsMetaDataGenMockOpsimTest(unittest.TestCase): 

517 """ 

518 This class will test the performance of the ObservationMetaDataGenerator 

519 on a 'mock OpSim' database (i.e. a database of pointings whose Summary 

520 table contains only a subset of the official OpSim schema) 

521 """ 

522 

523 @classmethod 

524 def setUpClass(cls): 

525 cls.opsim_db_name = tempfile.mktemp(dir=ROOT, prefix='mock_opsim_sqlite-', suffix='.db') 

526 

527 conn = sqlite3.connect(cls.opsim_db_name) 

528 c = conn.cursor() 

529 c.execute('''CREATE TABLE Summary (obsHistID int, expMJD real, ''' 

530 '''fieldRA real, fieldDec real, filter text)''') 

531 conn.commit() 

532 rng = np.random.RandomState(77) 

533 n_pointings = 100 

534 ra_data = rng.random_sample(n_pointings)*2.0*np.pi 

535 dec_data = (rng.random_sample(n_pointings)-0.5)*np.pi 

536 mjd_data = rng.random_sample(n_pointings)*1000.0 + 59580.0 

537 filter_dexes = rng.randint(0, 6, n_pointings) 

538 bands = ('u', 'g', 'r', 'i', 'z', 'y') 

539 filter_data = [] 

540 for ii in filter_dexes: 

541 filter_data.append(bands[ii]) 

542 

543 for ii in range(n_pointings): 

544 cmd = '''INSERT INTO Summary VALUES(%i, %f, %f, %f, '%s')''' % \ 

545 (ii, mjd_data[ii], ra_data[ii], dec_data[ii], filter_data[ii]) 

546 c.execute(cmd) 

547 conn.commit() 

548 conn.close() 

549 

550 @classmethod 

551 def tearDownClass(cls): 

552 

553 sims_clean_up() 

554 

555 if os.path.exists(cls.opsim_db_name): 

556 os.unlink(cls.opsim_db_name) 

557 

558 def setUp(self): 

559 self.obs_meta_gen = ObservationMetaDataGenerator(database=self.opsim_db_name) 

560 

561 def tearDown(self): 

562 del self.obs_meta_gen 

563 

564 def testOnNonExistentDatabase(self): 

565 """ 

566 Test that an exception is raised if you try to connect to an query 

567 a database that does not exist. 

568 """ 

569 

570 test_name = 'non_existent.db' 

571 with self.assertRaises(RuntimeError) as context: 

572 ObservationMetaDataGenerator(database=test_name, 

573 driver='sqlite') 

574 

575 self.assertEqual(context.exception.args[0], 

576 '%s is not a file' % test_name) 

577 

578 self.assertFalse(os.path.exists(test_name)) 

579 

580 def testSpatialQuery(self): 

581 """ 

582 Test that when we run a spatial query on the mock opsim database, we get expected results. 

583 """ 

584 

585 raBounds = (45.0, 100.0) 

586 results = self.obs_meta_gen.getObservationMetaData(fieldRA=raBounds) 

587 self.assertGreater(len(results), 0) 

588 for obs in results: 

589 self.assertGreater(obs.pointingRA, raBounds[0]) 

590 self.assertLessEqual(obs.pointingDec, raBounds[1]) 

591 

592 def testSelectException(self): 

593 """ 

594 Test that an exception is raised if you try to SELECT pointings on a column that does not exist 

595 """ 

596 with self.assertRaises(RuntimeError) as context: 

597 self.obs_meta_gen.getObservationMetaData(rotSkyPos=(27.0, 112.0)) 

598 self.assertIn("You have asked ObservationMetaDataGenerator to SELECT", 

599 context.exception.args[0]) 

600 

601 def testIncompletDB(self): 

602 """ 

603 Test that if the mock OpSim database does not have all required columns, an exception 

604 is raised. 

605 """ 

606 opsim_db_name = tempfile.mktemp(dir=ROOT, prefix='incomplete_mock_opsim_sqlite-', suffix='.db') 

607 

608 conn = sqlite3.connect(opsim_db_name) 

609 c = conn.cursor() 

610 c.execute('''CREATE TABLE Summary (obsHistID int, expMJD real, ''' 

611 '''fieldRA real, filter text)''') 

612 conn.commit() 

613 

614 rng = np.random.RandomState(77) 

615 n_pointings = 100 

616 ra_data = rng.random_sample(n_pointings)*2.0*np.pi 

617 mjd_data = rng.random_sample(n_pointings)*1000.0 + 59580.0 

618 filter_dexes = rng.randint(0, 6, n_pointings) 

619 bands = ('u', 'g', 'r', 'i', 'z', 'y') 

620 filter_data = [] 

621 for ii in filter_dexes: 

622 filter_data.append(bands[ii]) 

623 

624 for ii in range(n_pointings): 

625 cmd = '''INSERT INTO Summary VALUES(%i, %f, %f, '%s')''' % \ 

626 (ii, mjd_data[ii], ra_data[ii], filter_data[ii]) 

627 c.execute(cmd) 

628 conn.commit() 

629 conn.close() 

630 

631 incomplete_obs_gen = ObservationMetaDataGenerator(database=opsim_db_name) 

632 

633 with self.assertRaises(RuntimeError) as context: 

634 incomplete_obs_gen.getObservationMetaData(telescopeFilter='r') 

635 self.assertIn("ObservationMetaDataGenerator requires that the database", 

636 context.exception.args[0]) 

637 

638 if os.path.exists(opsim_db_name): 

639 os.unlink(opsim_db_name) 

640 

641 

642class MemoryTestClass(lsst.utils.tests.MemoryTestCase): 

643 pass 

644 

645if __name__ == "__main__": 645 ↛ 646line 645 didn't jump to line 646, because the condition on line 645 was never true

646 lsst.utils.tests.init() 

647 unittest.main()