def __init__(self, airmassCol='airmass', decCol='dec_rad', skyBrightCol='filtSkyBrightness', seeingCol='FWHMeff', filterCol='filter', moonAltCol='moonAlt', sunAltCol='sunAlt', site='LSST'): self.site = Site(site) self.units = ['mags'] self.airmassCol = airmassCol self.decCol = decCol self.skyBrightCol = skyBrightCol self.seeingCol = seeingCol self.filterCol = filterCol self.moonAltCol = moonAltCol self.sunAltCol = sunAltCol self.m5_stacker = FiveSigmaStacker() self.m5Col = self.m5_stacker.colsAdded[0] self.colsReq = [airmassCol, decCol, skyBrightCol, seeingCol, filterCol, moonAltCol, sunAltCol] self.colsReq.extend(self.m5_stacker.colsReq) self.colsReq = list(set(self.colsReq)) self.colsAdded = ['m5Optimal']
def __init__(self, nside=default_nside, alt_max=86.5): """ Parameters ---------- alt_max : float The maximum altitude one can point the telescope (degrees) """ self.ra, self.dec = _hpid2RaDec(nside, np.arange(hp.nside2npix(nside))) self.max_alt = np.radians(alt_max) self.sin_dec = np.sin(self.dec) self.cos_dec = np.cos(self.dec) site = Site('LSST') self.sin_lat = np.sin(site.latitude_rad) self.cos_lat = np.cos(site.latitude_rad) self.lon = site.longitude_rad # compute the hour angle when a point hits the alt_max cos_ha = (np.sin(self.max_alt) - self.sin_dec*self.sin_lat)/(self.cos_dec * self.cos_lat) self.lmst_max = np.arccos(cos_ha) + self.ra self.nans = np.isnan(self.lmst_max)
def fetchLatLonHeight(self): """ Returns the latitude, longitude, and height of the telescope used by the config file. """ if 'Config' not in self.tables: print('Cannot access Config table to retrieve site parameters; using sims.utils.Site instead.') site = Site(name='LSST') lat = site.latitude_rad lon = site.longitude_rad height = site.elev else: table = self.tables['Config'] lat = table.query_columns_Array(colnames=['paramValue'], constraint="paramName = 'latitude'") lat = float(lat['paramValue'][0]) lon = table.query_columns_Array(colnames=['paramValue'], constraint="paramName = 'longitude'") lon = float(lon['paramValue'][0]) height = table.query_columns_Array(colnames=['paramValue'], constraint="paramName = 'height'") height = float(height['paramValue'][0]) return lat, lon, height
def test_against_catalog(self): """ Compare deprecession results to a catalog that was validated with PhoSim. """ obs = ObservationMetaData(pointingRA=53.00913847303155535, pointingDec=-27.43894880881512321, rotSkyPos=256.75075318193080420, mjd=59580.13955500000156462, site=Site(name="LSST", pressure=0.0, humidity=0.0)) dtype = np.dtype([('id', int), ('ra', float), ('dec', float), ('ra_deprecessed', float), ('dec_deprecessed', float), ('x_dm', float), ('y_dm', float), ('x_focal', float), ('y_focal', float), ('x_cam', float), ('y_cam', float)]) data = np.genfromtxt(os.path.join(getPackageDir('sims_catUtils'), 'tests', 'testData', 'pixel_prediction_catalog.txt'), dtype=dtype) ra_obs, dec_obs = observedFromICRS(data['ra'], data['dec'], obs_metadata=obs, includeRefraction=False, epoch=2000.0) phosim_mixin = PhoSimAstrometryBase() ra_dep, dec_dep = phosim_mixin._dePrecess(np.radians(ra_obs), np.radians(dec_obs), obs) dd = 3600.0 * angularSeparation( data['ra_deprecessed'], data['dec_deprecessed'], np.degrees(ra_dep), np.degrees(dec_dep)) self.assertLess(dd.max(), 1.0e-5)
def testGetRotSkyPos(self): rotTelList = self.rng.random_sample(len(self.raList)) * 2.0 * np.pi mjd = 56321.8 obsTemp = ObservationMetaData(mjd=mjd, site=Site(longitude=self.lon, latitude=self.lat, name='LSST')) rotSkyRad = utils._getRotSkyPos(self.raList, self.decList, obsTemp, rotTelList) rotSkyDeg = utils.getRotSkyPos(np.degrees(self.raList), np.degrees(self.decList), obsTemp, np.degrees(rotTelList)) np.testing.assert_array_almost_equal(rotSkyRad, np.radians(rotSkyDeg), 10) rotSkyRad = utils._getRotSkyPos(self.raList, self.decList, obsTemp, rotTelList[0]) rotSkyDeg = utils.getRotSkyPos(np.degrees(self.raList), np.degrees(self.decList), obsTemp, np.degrees(rotTelList[0])) np.testing.assert_array_almost_equal(rotSkyRad, np.radians(rotSkyDeg), 10) for ra, dec, rotTel in \ zip(self.raList, self.decList, rotTelList): rotSkyRad = utils._getRotSkyPos(ra, dec, obsTemp, rotTel) rotSkyDeg = utils.getRotSkyPos(np.degrees(ra), np.degrees(dec), obsTemp, np.degrees(rotTel)) self.assertAlmostEqual(rotSkyRad, np.radians(rotSkyDeg), 10)
def testradec2altaz(self): np.random.seed(42) ra = np.random.rand(100) * np.pi * 2 dec = np.random.rand(100) * np.pi - np.pi / 2 site = Site('LSST') mjd = 55000 omd = ObservationMetaData(mjd=mjd, site=site) trueAlt, trueAz, pa = _altAzPaFromRaDec(ra, dec, omd) fastAlt, fastAz = sb.stupidFast_RaDec2AltAz(ra, dec, site.latitude_rad, site.longitude_rad, mjd) distanceDiff = haversine(trueAz, trueAlt, fastAz, fastAlt) degreeTol = 2. # 2-degree tolerance on the fast transform assert (np.degrees(distanceDiff.max()) < degreeTol) # make sure we don't have nans alt, az = sb.stupidFast_RaDec2AltAz(np.radians(np.array([0.])), np.radians(np.array([-90.])), np.radians(-30.2444), np.radians(-70.7494), 59582.05125) assert (~np.isnan(alt)) assert (~np.isnan(az))
def __init__(self, nside=default_nside, max_airmass=2.5, polar_limit=-80.): """ Parameters ---------- max_airmass : float (2.5) The maximum airmass to consider a point visible polar_limit : float (-80.) Consider anything below dec polar_limit to always be visible. (degrees) """ if nside is None: nside = utils.set_default_nside() # most fields should have a min and max lmst where they are less than max_airmass self.ra, self.dec = _hpid2RaDec(nside, np.arange(hp.nside2npix(nside))) alt_limit = np.pi / 2. - np.arccos(1. / max_airmass) site = Site('LSST') lat = site.latitude_rad self.lon = site.longitude_rad sinalt = np.sin(alt_limit) sindec = np.sin(self.dec) sinlat = np.sin(lat) cosdec = np.cos(self.dec) coslat = np.cos(lat) cosha = (sinalt - sindec * sinlat) / (cosdec * coslat) # Here's the hour angle (plus or minus) for each healpixel self.ha_limit = np.arccos(cosha) * 12 / np.pi # Consider some regions circumpolar self.ha_limit[np.where(self.dec < np.radians(polar_limit))] = 12. self.polar_limit = polar_limit self.feature = self.ra * 0.
def testAltAzPaFromRaDec(self): mjd = 57432.7 obs = ObservationMetaData(mjd=mjd, site=Site(longitude=self.lon, latitude=self.lat, name='LSST')) altRad, azRad, paRad = utils._altAzPaFromRaDec(self.raList, self.decList, obs) altDeg, azDeg, paDeg = utils.altAzPaFromRaDec(np.degrees(self.raList), np.degrees(self.decList), obs) np.testing.assert_array_almost_equal(altRad, np.radians(altDeg), 10) np.testing.assert_array_almost_equal(azRad, np.radians(azDeg), 10) np.testing.assert_array_almost_equal(paRad, np.radians(paDeg), 10) altRad, azRad, paRad = utils._altAzPaFromRaDec(self.raList, self.decList, obs) altDeg, azDeg, paDeg = utils.altAzPaFromRaDec(np.degrees(self.raList), np.degrees(self.decList), obs) np.testing.assert_array_almost_equal(altRad, np.radians(altDeg), 10) np.testing.assert_array_almost_equal(azRad, np.radians(azDeg), 10) np.testing.assert_array_almost_equal(paRad, np.radians(paDeg), 10) for ra, dec, in zip(self.raList, self.decList): altRad, azRad, paRad = utils._altAzPaFromRaDec(ra, dec, obs) altDeg, azDeg, paDeg = utils.altAzPaFromRaDec( np.degrees(ra), np.degrees(dec), obs) self.assertAlmostEqual(altRad, np.radians(altDeg), 10) self.assertAlmostEqual(azRad, np.radians(azDeg), 10) self.assertAlmostEqual(paRad, np.radians(paDeg), 10)
def __init__(self, location=None, park_alt=86.5, park_az=0., start_filter='r', mjd0=0): self.park_alt_rad = np.radians(park_alt) self.park_az_rad = np.radians(park_az) self.current_filter = start_filter if location is None: self.location = Site('LSST') self.location.lat_rad = np.radians(self.location.latitude) self.location.lon_rad = np.radians(self.location.longitude) # Our RA,Dec to Alt,Az converter self.radec2altaz = radec2altazpa(self.location) self.setup_camera() self.setup_dome() self.setup_telescope() self.setup_optics() # Park the telescope self.park() self.last_mjd = mjd0
order = np.argsort(intids) ointids = intids[order] left = np.searchsorted(ointids, uintids, side='left') right = np.searchsorted(ointids, uintids, side='right') for i in range(np.size(left)): ids[left[i]:right[i]] = uids[i] result = np.zeros(np.size(intids), dtype=dtype) result[order] = ids return result # Try and run ubercal on the cannon data. Hopefully get out a # Load up the telescope properties, has .lat and .lon telescope = Site('LSST') nside = 8 filt = 'R' starIDs = [] dateIDs = [] hpIDs = [] starMags = [] starMags_err = [] mjds = [] airmasses = [] altLimit = 25. # Degrees sunAltLimit = np.radians(-20.)
def makePhoSimTestDB(filename='PhoSimTestDatabase.db', size=1000, seedVal=32, radius=0.1, deltaRA=None, deltaDec=None, bandpass='******', m5=None, seeing=None, magnorm_min=17.0, delta_magnorm=4.0, **kwargs): """ Make a test database to storing cartoon information for the test phoSim input catalog to use. The method will return an ObservationMetaData object guaranteed to encompass the objects in this database. @param [in] filename is a string indicating the name of the DB file to be created @param [in] size is the number of objects int he database @param [in] seedVal is the seed passed to the random number generator @param [in] radius is the radius (in degrees) of the field of view to be returned @param [in] bandpass is the bandpas(es) of the observation to be passed to ObservationMetaData (optional) @param [in] m5 is the m5 value(s) to be passed to ObservationMetaData (optional) @param [in] seeing is the seeing value(s) in arcseconds to be passed to ObservationMetaData (optional) @param [in] deltaRA/Dec are numpy arrays that indicate where (in relation to the center of the field of view) objects should be placed. These coordinates are in degrees. Specifying either of these paramters will overwrite size. If you only specify one of these parameters, the other will be set randomly. These parameters are optional. @param [in] magnorm_min is the min magnorm (magNorms for sources in the database will be distributed according to a random deviate drawn from magnorm_min + random*delta_magnorm) @param [in] delta_magnorm (see documentation for magnorm_min) """ if os.path.exists(filename): os.unlink(filename) # just an example of some valid SED file names galaxy_seds = [ 'Const.80E07.02Z.spec', 'Inst.80E07.002Z.spec', 'Burst.19E07.0005Z.spec' ] agn_sed = 'agn.spec' star_seds = [ 'km20_5750.fits_g40_5790', 'm2.0Full.dat', 'bergeron_6500_85.dat_6700' ] rng = np.random.RandomState(seedVal) if deltaRA is not None and deltaDec is not None: if len(deltaRA) != len(deltaDec): raise RuntimeError("WARNING in makePhoSimTestDB deltaRA and " "deltaDec have different lengths") if deltaRA is not None: size = len(deltaRA) elif deltaDec is not None: size = len(deltaDec) # create the ObservationMetaData object mjd = 52000.0 alt = np.pi / 2.0 az = 0.0 testSite = Site(name='LSST') obsTemp = ObservationMetaData(mjd=mjd, site=testSite) centerRA, centerDec = _raDecFromAltAz(alt, az, obsTemp) rotTel = _getRotTelPos(centerRA, centerDec, obsTemp, 0.0) rotSkyPos = _getRotSkyPos(centerRA, centerDec, obsTemp, rotTel) obs_metadata = ObservationMetaData(pointingRA=np.degrees(centerRA), pointingDec=np.degrees(centerDec), rotSkyPos=np.degrees(rotSkyPos), bandpassName=bandpass, mjd=mjd, boundType='circle', boundLength=2.0 * radius, site=testSite, m5=m5, seeing=seeing) moon_alt = -90.0 sun_alt = -90.0 moon_ra, moon_dec = raDecFromAltAz(moon_alt, 0.0, obs_metadata) dist2moon = haversine(np.radians(moon_ra), np.radians(moon_dec), obs_metadata._pointingRA, obs_metadata._pointingDec) obs_metadata.OpsimMetaData = { 'moonra': moon_ra, 'moondec': moon_dec, 'moonalt': moon_alt, 'sunalt': sun_alt, 'dist2moon': dist2moon, 'rottelpos': np.degrees(rotTel) } # Now begin building the database. # First create the tables. conn = sqlite3.connect(filename) c = conn.cursor() try: c.execute('''CREATE TABLE galaxy_bulge (galtileid int, galid int, bra real, bdec real, ra real, dec real, magnorm_bulge real, sedname_bulge text, a_b real, b_b real, pa_bulge real, bulge_n int, ext_model_b text, av_b real, rv_b real, u_ab real, g_ab real, r_ab real, i_ab real, z_ab real, y_ab real, redshift real, BulgeHalfLightRadius real)''' ) conn.commit() except: raise RuntimeError("Error creating galaxy_bulge table.") try: c.execute('''CREATE TABLE galaxy (galtileid int, galid int, ra real, dec real, bra real, bdec real, dra real, ddec real, agnra real, agndec real, magnorm_bulge, magnorm_disk, magnorm_agn, sedname_bulge text, sedname_disk text, sedname_agn text, varParamStr text, a_b real, b_b real, pa_bulge real, bulge_n int, a_d real, b_d real, pa_disk real, disk_n int, ext_model_b text, av_b real, rv_b real, ext_model_d text, av_d real, rv_d real, u_ab real, g_ab real, r_ab real, i_ab real, z_ab real, y_ab real, redshift real, BulgeHalfLightRadius real, DiskHalfLightRadius real)''' ) conn.commit() except: raise RuntimeError("Error creating galaxy table.") try: c.execute('''CREATE TABLE galaxy_agn (galtileid int, galid int, agnra real, agndec real, ra real, dec real, magnorm_agn real, sedname_agn text, varParamStr text, u_ab real, g_ab real, r_ab real, i_ab real, z_ab real, y_ab real, redshift real)''' ) except: raise RuntimeError("Error creating galaxy_agn table.") try: c.execute('''CREATE TABLE StarAllForceseek (simobjid int, ra real, decl real, magNorm real, mudecl real, mura real, galacticAv real, vrad real, varParamStr text, sedFilename text, parallax real, ebv real)''') except: raise RuntimeError("Error creating StarAllForceseek table.") # Now generate the data to be stored in the tables. rr = rng.random_sample(size) * np.radians(radius) theta = rng.random_sample(size) * 2.0 * np.pi if deltaRA is None: ra = np.degrees(centerRA + rr * np.cos(theta)) else: ra = np.degrees(centerRA) + deltaRA if deltaDec is None: dec = np.degrees(centerDec + rr * np.sin(theta)) else: dec = np.degrees(centerDec) + deltaDec bra = np.radians(ra + rng.random_sample(size) * 0.01 * radius) bdec = np.radians(dec + rng.random_sample(size) * 0.01 * radius) dra = np.radians(ra + rng.random_sample(size) * 0.01 * radius) ddec = np.radians(dec + rng.random_sample(size) * 0.01 * radius) agnra = np.radians(ra + rng.random_sample(size) * 0.01 * radius) agndec = np.radians(dec + rng.random_sample(size) * 0.01 * radius) magnorm_bulge = rng.random_sample(size) * delta_magnorm + magnorm_min magnorm_disk = rng.random_sample(size) * delta_magnorm + magnorm_min magnorm_agn = rng.random_sample(size) * delta_magnorm + magnorm_min b_b = rng.random_sample(size) * 0.2 a_b = b_b + rng.random_sample(size) * 0.05 b_d = rng.random_sample(size) * 0.5 a_d = b_d + rng.random_sample(size) * 0.1 BulgeHalfLightRadius = rng.random_sample(size) * 0.2 DiskHalfLightRadius = rng.random_sample(size) * 0.5 pa_bulge = rng.random_sample(size) * 360.0 pa_disk = rng.random_sample(size) * 360.0 av_b = rng.random_sample(size) * 0.3 av_d = rng.random_sample(size) * 0.3 rv_b = rng.random_sample(size) * 0.1 + 2.0 rv_d = rng.random_sample(size) * 0.1 + 2.0 u_ab = rng.random_sample(size) * 4.0 + 17.0 g_ab = rng.random_sample(size) * 4.0 + 17.0 r_ab = rng.random_sample(size) * 4.0 + 17.0 i_ab = rng.random_sample(size) * 4.0 + 17.0 z_ab = rng.random_sample(size) * 4.0 + 17.0 y_ab = rng.random_sample(size) * 4.0 + 17.0 redshift = rng.random_sample(size) * 2.0 t0_mjd = mjd - rng.random_sample(size) * 1000.0 agn_tau = rng.random_sample(size) * 1000.0 + 1000.0 agnSeed = rng.randint(2, 4001, size=size) agn_sfu = rng.random_sample(size) agn_sfg = rng.random_sample(size) agn_sfr = rng.random_sample(size) agn_sfi = rng.random_sample(size) agn_sfz = rng.random_sample(size) agn_sfy = rng.random_sample(size) rrStar = rng.random_sample(size) * np.radians(radius) thetaStar = rng.random_sample(size) * 2.0 * np.pi if deltaRA is None: raStar = centerRA + rrStar * np.cos(thetaStar) else: raStar = centerRA + np.radians(deltaRA) if deltaDec is None: decStar = centerDec + rrStar * np.sin(thetaStar) else: decStar = centerDec + np.radians(deltaDec) raStar = np.degrees(raStar) decStar = np.degrees(decStar) magnormStar = rng.random_sample(size) * delta_magnorm + magnorm_min mudecl = rng.random_sample(size) * 0.0001 mura = rng.random_sample(size) * 0.0001 galacticAv = rng.random_sample(size) * 0.05 * 3.1 vrad = rng.random_sample(size) * 1.0 parallax = 0.00045 + rng.random_sample(size) * 0.00001 period = rng.random_sample(size) * 20.0 amp = rng.random_sample(size) * 5.0 # write the data to the tables. for i in range(size): cmd = '''INSERT INTO galaxy_bulge VALUES (%i, %i, %f, %f, %f, %f, %f, '%s', %f, %f, %f, %i, '%s', %f, %f, %f, %f, %f, %f, %f, %f, %f, %f)''' % \ (i, i, bra[i], bdec[i], ra[i], dec[i], magnorm_bulge[i], galaxy_seds[i%len(galaxy_seds)], a_b[i], b_b[i], pa_bulge[i], 4, 'CCM', av_b[i], rv_b[i], u_ab[i], g_ab[i], r_ab[i], i_ab[i], z_ab[i], y_ab[i], redshift[i], BulgeHalfLightRadius[i]) c.execute(cmd) varParam = { 'varMethodName': 'applyAgn', 'pars': { 'agn_tau': round(agn_tau[i], 4), 't0_mjd': round(t0_mjd[i], 4), 'agn_sfu': round(agn_sfu[i], 4), 'agn_sfg': round(agn_sfg[i], 4), 'agn_sfr': round(agn_sfr[i], 4), 'agn_sfi': round(agn_sfi[i], 4), 'agn_sfz': round(agn_sfz[i], 4), 'agn_sfy': round(agn_sfy[i], 4), 'seed': int(agnSeed[i]) } } paramStr = json.dumps(varParam) cmd = '''INSERT INTO galaxy VALUES (%i, %i, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, '%s', '%s', '%s', '%s', %f, %f, %f, %i, %f, %f, %f, %i, '%s', %f, %f, '%s', %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f)''' % \ (i, i, ra[i], dec[i], bra[i], bdec[i], dra[i], ddec[i], agnra[i], agndec[i], magnorm_bulge[i], magnorm_disk[i], magnorm_agn[i], galaxy_seds[i%len(galaxy_seds)], galaxy_seds[i%len(galaxy_seds)], agn_sed, paramStr, a_b[i], b_b[i], pa_bulge[i], 4, a_d[i], b_d[i], pa_disk[i], 1, 'CCM', av_b[i], rv_b[i], 'CCM', av_d[i], rv_d[i], u_ab[i], g_ab[i], r_ab[i], i_ab[i], z_ab[i], y_ab[i], redshift[i], BulgeHalfLightRadius[i], DiskHalfLightRadius[i]) c.execute(cmd) cmd = '''INSERT INTO galaxy_agn VALUES (%i, %i, %f, %f, %f, %f, %f, '%s', '%s', %f, %f, %f, %f, %f, %f, %f)''' % \ (i, i, agnra[i], agndec[i], ra[i], dec[i], magnorm_agn[i], agn_sed, paramStr, u_ab[i], g_ab[i], r_ab[i], i_ab[i], z_ab[i], y_ab[i], redshift[i]) c.execute(cmd) varParam = { 'varMethodName': 'testVar', 'pars': { 'period': period[i], 'amplitude': amp[i] } } paramStr = json.dumps(varParam) cmd = '''INSERT INTO StarAllForceseek VALUES (%i, %f, %f, %f, %f, %f, %f, %f, '%s', '%s', %f, %f)''' %\ (i, raStar[i], decStar[i], magnormStar[i], mudecl[i], mura[i], galacticAv[i], vrad[i], paramStr, star_seds[i%len(star_seds)], parallax[i], galacticAv[i]/3.1) c.execute(cmd) conn.commit() conn.close() return obs_metadata
def test_eq(self): """ Test that we have correctly implemented __eq__ in Site """ reference_site = Site(name='ref', longitude=112.12, latitude=-83.121, temperature=112.1, height=3124.2, pressure=891.2, humidity=0.341, lapseRate=0.008) other_site = Site(name='ref', longitude=112.12, latitude=-83.121, temperature=112.1, height=3124.2, pressure=891.2, humidity=0.341, lapseRate=0.008) self.assertEqual(reference_site, other_site) self.assertFalse(reference_site != other_site) self.assertTrue(reference_site == other_site) # just in case we ever change the class to convert # to radians only on demand, call for latitude/longitude # in radians and then check that the two instances are # still equal (since __eq__ just loops over the contents # of self.__dict__, this could fail if other_site has not # yet assigned a value to longitude/latitude_rad reference_site.latitude_rad self.assertEqual(reference_site, other_site) self.assertFalse(reference_site != other_site) self.assertTrue(reference_site == other_site) reference_site.longitude_rad self.assertEqual(reference_site, other_site) self.assertFalse(reference_site != other_site) self.assertTrue(reference_site == other_site) reference_site.temperature_kelvin self.assertEqual(reference_site, other_site) self.assertFalse(reference_site != other_site) self.assertTrue(reference_site == other_site) # now test that __ne__ works correctly other_site = Site(name='other', longitude=112.12, latitude=-83.121, temperature=112.1, height=3124.2, pressure=891.2, humidity=0.341, lapseRate=0.008) self.assertNotEqual(reference_site, other_site) self.assertFalse(reference_site == other_site) self.assertTrue(reference_site != other_site) other_site = Site(name='ref', longitude=112.13, latitude=-83.121, temperature=112.1, height=3124.2, pressure=891.2, humidity=0.341, lapseRate=0.008) self.assertNotEqual(reference_site, other_site) self.assertFalse(reference_site == other_site) self.assertTrue(reference_site != other_site) other_site = Site(name='ref', longitude=112.12, latitude=-83.122, temperature=112.1, height=3124.2, pressure=891.2, humidity=0.341, lapseRate=0.008) self.assertNotEqual(reference_site, other_site) self.assertFalse(reference_site == other_site) self.assertTrue(reference_site != other_site) other_site = Site(name='ref', longitude=112.12, latitude=-83.121, temperature=112.2, height=3124.2, pressure=891.2, humidity=0.341, lapseRate=0.008) self.assertNotEqual(reference_site, other_site) self.assertFalse(reference_site == other_site) self.assertTrue(reference_site != other_site) other_site = Site(name='ref', longitude=112.12, latitude=-83.121, temperature=112.1, height=3124.3, pressure=891.2, humidity=0.341, lapseRate=0.008) self.assertNotEqual(reference_site, other_site) self.assertFalse(reference_site == other_site) self.assertTrue(reference_site != other_site) other_site = Site(name='ref', longitude=112.12, latitude=-83.121, temperature=112.1, height=3124.2, pressure=891.3, humidity=0.341, lapseRate=0.008) self.assertNotEqual(reference_site, other_site) self.assertFalse(reference_site == other_site) self.assertTrue(reference_site != other_site) other_site = Site(name='ref', longitude=112.12, latitude=-83.121, temperature=112.1, height=3124.2, pressure=891.2, humidity=0.342, lapseRate=0.008) self.assertNotEqual(reference_site, other_site) self.assertFalse(reference_site == other_site) self.assertTrue(reference_site != other_site) other_site = Site(name='ref', longitude=112.12, latitude=-83.121, temperature=112.1, height=3124.2, pressure=891.2, humidity=0.341, lapseRate=0.009) self.assertNotEqual(reference_site, other_site) self.assertFalse(reference_site == other_site) self.assertTrue(reference_site != other_site) # test blank Sites ref_site = Site() other_site = Site() self.assertEqual(ref_site, other_site) self.assertTrue(ref_site == other_site) self.assertFalse(ref_site != other_site)
def __init__(self, observatory='LSST', twilight=True, zodiacal=True, moon=True, airglow=True, lowerAtm=False, upperAtm=False, scatteredStar=False, mergedSpec=True, mags=False, preciseAltAz=False, airmass_limit=2.5): """ Instatiate the SkyModel. This loads all the required template spectra/magnitudes that will be used for interpolation. Parameters ---------- Observatory : Site object object with attributes lat, lon, elev. But default loads LSST. twilight : bool (True) Include twilight component (True) zodiacal : bool (True) Include zodiacal light component (True) moon : bool (True) Include scattered moonlight component (True) airglow : bool (True) Include airglow component lowerAtm : bool (False) Include lower atmosphere component. This component is part of `mergedSpec`. upperAtm : bool (False) Include upper atmosphere component. This component is part of `mergedSpec`. scatteredStar : bool (False) Include scattered starlight component. This component is part of `mergedSpec`. mergedSpec : bool (True) Compute the lowerAtm, upperAtm, and scatteredStar simultaneously since they are all functions of only airmass. mags : bool (False) By default, the sky model computes a 17,001 element spectrum. If `mags` is True, the model will return the LSST ugrizy magnitudes (in that order). preciseAltAz : bool (False) If False, use the fast alt, az to ra, dec coordinate transformations that do not take abberation, diffraction, etc into account. Results in errors up to ~1.5 degrees, but an order of magnitude faster than coordinate transforms in sims_utils. airmass_limit : float (2.5) Most of the models are only accurate to airmass 2.5. If set higher, airmass values higher than 2.5 are set to 2.5. """ self.moon = moon self.lowerAtm = lowerAtm self.twilight = twilight self.zodiacal = zodiacal self.upperAtm = upperAtm self.airglow = airglow self.scatteredStar = scatteredStar self.mergedSpec = mergedSpec self.mags = mags self.preciseAltAz = preciseAltAz # Airmass limit. self.airmassLimit = airmass_limit if self.mags: self.npix = 6 else: self.npix = 17001 self.components = { 'moon': self.moon, 'lowerAtm': self.lowerAtm, 'twilight': self.twilight, 'upperAtm': self.upperAtm, 'airglow': self.airglow, 'zodiacal': self.zodiacal, 'scatteredStar': self.scatteredStar, 'mergedSpec': self.mergedSpec } # Check that the merged component isn't being run with other components mergedComps = [self.lowerAtm, self.upperAtm, self.scatteredStar] for comp in mergedComps: if comp & self.mergedSpec: warnings.warn( "Adding component multiple times to the final output spectra." ) interpolators = { 'scatteredStar': ScatteredStar, 'airglow': Airglow, 'lowerAtm': LowerAtm, 'upperAtm': UpperAtm, 'mergedSpec': MergedSpec, 'moon': MoonInterp, 'zodiacal': ZodiacalInterp, 'twilight': TwilightInterp } # Load up the interpolation objects for each component self.interpObjs = {} for key in self.components: if self.components[key]: self.interpObjs[key] = interpolators[key](mags=self.mags) # Set up a pyephem observatory object if hasattr(observatory, 'latitude_rad') & hasattr( observatory, 'longitude_rad') & hasattr(observatory, 'height'): self.telescope = observatory self.Observatory = ephem.Observer() self.Observatory.lat = self.telescope.latitude_rad self.Observatory.lon = self.telescope.longitude_rad self.Observatory.elevation = self.telescope.height elif observatory == 'LSST': self.telescope = Site('LSST') self.Observatory = ephem.Observer() self.Observatory.lat = self.telescope.latitude_rad self.Observatory.lon = self.telescope.longitude_rad self.Observatory.elevation = self.telescope.height else: self.Observatory = observatory # Note that observing conditions have not been set self.paramsSet = False
for det in camera: if det.getType() != SCIENCE: continue det_name_list.append(det.getName()) det_name_list.sort() opsimdb = os.path.join('/Users', 'danielsf', 'physics', 'lsst_150412', 'Development', 'garage', 'OpSimData', 'minion_1016_sqlite.db') assert os.path.exists(opsimdb) obs_gen = ObservationMetaDataGenerator(database=opsimdb) obs_list = obs_gen.getObservationMetaData(obsHistID=args.obs) obs = obs_list[0] filter_name = obs.bandpass site_no_atm = Site(name="LSST", pressure=0.0, humidity=0.0) obs.site = site_no_atm assert np.abs(obs.site.pressure) < 1.0e-6 assert np.abs(obs.site.humidity) < 1.0e-6 xpix_0 = np.arange(200.0, 3800.0, 1000.0) ypix_0 = np.arange(200.0, 3800.0, 1000.0) pix_grid = np.meshgrid(xpix_0, ypix_0) cam_xpix_in = pix_grid[0].flatten() cam_ypix_in = pix_grid[1].flatten() camera_wrapper = LSSTCameraWrapper() de_precessor = PhoSimAstrometryBase() phosim_header_map = copy.deepcopy(DefaultPhoSimHeaderMap) phosim_header_map['nsnap'] = 1
# Need to build a kdtree to quick search for healpixes within a radius mjd_start = 59580.033829 survey_length = 10 # days time_step = 10. # minitues mjds = np.arange(mjd_start, mjd_start + survey_length + time_step / 60. / 24., time_step / 60. / 24.) names = ['u', 'g', 'r', 'i', 'z', 'y', 'airmass', 'mask'] types = [float] * 7 types.append(int) results = np.zeros((mjds.size, map_size), dtype=list(zip(names, types))) results['mask'] = 1 site = Site('LSST') moon = ephem.Moon() venus = ephem.Venus() sun = ephem.Sun() doff = ephem.Date(0) - ephem.Date('1858/11/17') lsstObs = ephem.Observer() lsstObs.lat = np.radians(site.latitude) lsstObs.lon = np.radians(site.longitude) lsstObs.elevation = site.height sm = sb.SkyModel(mags=True) filterDict = {'u': 0, 'g': 1, 'r': 2, 'i': 3, 'z': 4, 'y': 5} indices = np.arange(mjds.size)
def testRaDec(self): """ Test that raDecFromNativeLonLat does invert nativeLonLatFromRaDec """ rng = np.random.RandomState(42) nSamples = 100 # because raDecFromNativeLonLat is only good rrList = rng.random_sample(nSamples) * 50.0 # out to a zenith distance of ~ 70 degrees thetaList = rng.random_sample(nSamples) * 2.0 * np.pi rrPointingList = rng.random_sample(10) * 50.0 thetaPointingList = rng.random_sample(10) * 2.0 * np.pi mjdList = rng.random_sample(nSamples) * 10000.0 + 43000.0 for rrp, thetap, mjd in \ zip(rrPointingList, thetaPointingList, mjdList): site = Site(name='LSST') raZenith, decZenith = raDecFromAltAz( 180.0, 0.0, ObservationMetaData(mjd=mjd, site=site)) rp = raZenith + rrp * np.cos(thetap) dp = decZenith + rrp * np.sin(thetap) obs = ObservationMetaData(pointingRA=rp, pointingDec=dp, mjd=mjd, site=site) raList_icrs = (raZenith + rrList * np.cos(thetaList)) % 360.0 decList_icrs = decZenith + rrList * np.sin(thetaList) raList_obs, decList_obs = observedFromICRS(raList_icrs, decList_icrs, obs_metadata=obs, epoch=2000.0, includeRefraction=True) # calculate the distance between the ICRS position and the observed # geocentric position dd_icrs_obs_list = arcsecFromRadians( haversine(np.radians(raList_icrs), np.radians(decList_icrs), np.radians(raList_obs), np.radians(decList_obs))) for rr, dd, dd_icrs_obs in zip(raList_icrs, decList_icrs, dd_icrs_obs_list): lon, lat = nativeLonLatFromRaDec(rr, dd, obs) r1, d1 = raDecFromNativeLonLat(lon, lat, obs) # the distance between the input RA, Dec and the round-trip output # RA, Dec distance = arcsecFromRadians( haversine(np.radians(r1), np.radians(d1), np.radians(rr), np.radians(dd))) rr_obs, dec_obs = observedFromICRS(rr, dd, obs_metadata=obs, epoch=2000.0, includeRefraction=True) # verify that the round trip through nativeLonLat only changed # RA, Dec by less than an arcsecond self.assertLess(distance, 1.0) # verify that any difference in the round trip is much less # than the distance between the ICRS and the observed geocentric # RA, Dec self.assertLess(distance, dd_icrs_obs * 0.01)
def __init__(self, basis_functions, basis_weights, extra_features=None, extra_basis_functions=None, filtername='r', filter2='g', slew_approx=7.5, filter_change_approx=140., read_approx=2., nexp=2, min_exptime=15., max_exptime=60., ideal_pair_time=22., min_pair_time=15., search_radius=30., alt_max=85., az_range=90., smoothing_kernel=None, nside=default_nside, dither=True, seed=42, ignore_obs='ack', tag_fields=False, tag_map=None, tag_names=None, sun_alt_limit=-19., survey_note='blob', sitename='LSST'): """ Parameters ---------- min_exp_time : float (15.) The minimum exposure time to use (seconds). This is the exposure time when conditions are dark time on the meridian (or better). max_exp_time : float (60.) The maximum exposure time to use (seconds) filtername : str ('r') The filter to observe in. filter2 : str ('g') The filter to pair with the first observation. If set to None, no pair will be observed. slew_approx : float (7.5) The approximate slewtime between neerby fields (seconds). Used to calculate how many observations can be taken in the desired time block. filter_change_approx : float (140.) The approximate time it takes to change filters (seconds). ideal_pair_time : float (22.) The ideal time gap wanted between observations to the same pointing (minutes) min_pair_time : float (15.) The minimum acceptable pair time (minutes) search_radius : float (30.) The radius around the reward peak to look for additional potential pointings (degrees) alt_max : float (85.) The maximum altitude to include (degrees). az_range : float (90.) The range of azimuths to consider around the peak reward value (degrees). sitename : str ('LSST') The name of the site to lookup latitude and longitude. """ if nside is None: nside = set_default_nside() if extra_features is None: extra_features = {} extra_features['night'] = features.Current_night() extra_features['mounted_filters'] = features.Mounted_filters() extra_features['mjd'] = features.Current_mjd() extra_features[ 'night_boundaries'] = features.CurrentNightBoundaries() extra_features['sun_moon_alt'] = features.Sun_moon_alts() extra_features['lmst'] = features.Current_lmst( ) # Pretty sure in hours extra_features['current_filter'] = features.Current_filter() extra_features['altaz'] = features.AltAzFeature() if extra_basis_functions is None: extra_basis_functions = {} extra_basis_functions['filter1_m5diff'] = M5_diff_basis_function( filtername=filtername, nside=nside) if filter2 is not None: extra_basis_functions[ 'filter2_m5diff'] = M5_diff_basis_function( filtername=filter2, nside=nside) super(Vary_expt_survey, self).__init__(basis_functions=basis_functions, basis_weights=basis_weights, extra_features=extra_features, extra_basis_functions=extra_basis_functions, filtername=filtername, block_size=0, smoothing_kernel=smoothing_kernel, dither=dither, seed=seed, ignore_obs=ignore_obs, tag_fields=tag_fields, tag_map=tag_map, tag_names=tag_names, nside=nside) self.nexp = nexp self.min_exptime = min_exptime self.max_exptime = max_exptime self.slew_approx = slew_approx self.read_approx = read_approx self.hpids = np.arange(hp.nside2npix(self.nside)) # If we are taking pairs in same filter, no need to add filter change time. if filtername == filter2: filter_change_approx = 0 # Compute the minimum time needed to observe a blob (or observe, then repeat.) if filter2 is not None: self.time_needed = (min_pair_time * 60. * 2. + read_approx + filter_change_approx) / 24. / 3600. # Days else: self.time_needed = (min_pair_time * 60. + read_approx) / 24. / 3600. # Days self.filter_set = set(filtername) if filter2 is None: self.filter2_set = self.filter_set else: self.filter2_set = set(filter2) self.sun_alt_limit = np.radians(sun_alt_limit) self.ra, self.dec = _hpid2RaDec(self.nside, self.hpids) # Look up latitude and longitude for alt,az conversions later # XXX: TODO: lat and lon should be in the Observatory feature. But that feature # needs documentation on what's in it! site = Site(name=sitename) self.lat = site.latitude_rad self.lon = site.longitude_rad self.survey_note = survey_note self.counter = 1 # start at 1, because 0 is default in empty observation self.filter2 = filter2 self.search_radius = np.radians(search_radius) self.az_range = np.radians(az_range) self.alt_max = np.radians(alt_max) self.min_pair_time = min_pair_time self.ideal_pair_time = ideal_pair_time
def makePhoSimTestDB(filename='PhoSimTestDatabase.db', size=1000, seedVal=32, radius=0.1, displacedRA=None, displacedDec=None, bandpass=None, m5=None, seeing=None, **kwargs): """ Make a test database to storing cartoon information for the test phoSim input catalog to use. The method will return an ObservationMetaData object guaranteed to encompass the objects in this database. @param [in] filename is a string indicating the name of the DB file to be created @param [in] size is the number of objects int he database @param [in] seedVal is the seed passed to the random number generator @param [in] radius is the radius (in degrees) of the field of view to be returned @param [in] bandpass is the bandpas(es) of the observation to be passed to ObservationMetaData (optional) @param [in] m5 is the m5 value(s) to be passed to ObservationMetaData (optional) @param [in] seeing is the seeing value(s) in arcseconds to be passed to ObservationMetaData (optional) @param [in] displacedRA/Dec are numpy arrays that indicate where (in relation to the center of the field of view) objects should be placed. These coordinates are in degrees. Specifying either of these paramters will overwrite size. If you only specify one of these parameters, the other will be set randomly. These parameters are optional. """ if os.path.exists(filename): os.unlink(filename) #just an example of some valid SED file names galaxy_seds = [ 'Const.80E07.02Z.spec', 'Inst.80E07.002Z.spec', 'Burst.19E07.0005Z.spec' ] agn_sed = 'agn.spec' star_seds = [ 'km20_5750.fits_g40_5790', 'm2.0Full.dat', 'bergeron_6500_85.dat_6700' ] numpy.random.seed(seedVal) if displacedRA is not None and displacedDec is not None: if len(displacedRA) != len(displacedDec): raise RuntimeError( "WARNING in makePhoSimTestDB displacedRA and displacedDec have different lengths" ) if displacedRA is not None: size = len(displacedRA) elif displacedDec is not None: size = len(displacedDec) #create the ObservationMetaData object mjd = 52000.0 alt = numpy.pi / 2.0 az = 0.0 band = 'r' testSite = Site() centerRA, centerDec = raDecFromAltAz(alt, az, testSite.longitude, testSite.latitude, mjd) rotTel = getRotTelPos(centerRA, centerDec, testSite.longitude, testSite.latitude, mjd, 0.0) obsDict = calcObsDefaults(centerRA, centerDec, alt, az, rotTel, mjd, band, testSite.longitude, testSite.latitude) obsDict['Opsim_expmjd'] = mjd phoSimMetaData = OrderedDict([ (k, (obsDict[k], numpy.dtype(type(obsDict[k])))) for k in obsDict if k != 'Opsim_filter' or bandpass is None ]) obs_metadata = ObservationMetaData(boundType='circle', boundLength=2.0 * radius, phoSimMetaData=phoSimMetaData, site=testSite, bandpassName=bandpass, m5=m5, seeing=seeing) #Now begin building the database. #First create the tables. conn = sqlite3.connect(filename) c = conn.cursor() try: c.execute('''CREATE TABLE galaxy_bulge (galtileid int, galid int, bra real, bdec real, ra real, dec real, magnorm_bulge real, sedname_bulge text, a_b real, b_b real, pa_bulge real, bulge_n int, ext_model_b text, av_b real, rv_b real, u_ab real, g_ab real, r_ab real, i_ab real, z_ab real, y_ab real, redshift real, BulgeHalfLightRadius real)''' ) conn.commit() except: raise RuntimeError("Error creating galaxy_bulge table.") try: c.execute('''CREATE TABLE galaxy (galtileid int, galid int, ra real, dec real, bra real, bdec real, dra real, ddec real, agnra real, agndec real, magnorm_bulge, magnorm_disk, magnorm_agn, sedname_bulge text, sedname_disk text, sedname_agn text, varParamStr text, a_b real, b_b real, pa_bulge real, bulge_n int, a_d real, b_d real, pa_disk real, disk_n int, ext_model_b text, av_b real, rv_b real, ext_model_d text, av_d real, rv_d real, u_ab real, g_ab real, r_ab real, i_ab real, z_ab real, y_ab real, redshift real, BulgeHalfLightRadius real, DiskHalfLightRadius real)''' ) conn.commit() except: raise RuntimeError("Error creating galaxy table.") try: c.execute('''CREATE TABLE galaxy_agn (galtileid int, galid int, agnra real, agndec real, ra real, dec real, magnorm_agn real, sedname_agn text, varParamStr text, u_ab real, g_ab real, r_ab real, i_ab real, z_ab real, y_ab real, redshift real)''' ) except: raise RuntimeError("Error creating galaxy_agn table.") try: c.execute('''CREATE TABLE starsALL_forceseek (simobjid int, ra real, decl real, magNorm real, mudecl real, mura real, galacticAv real, vrad real, varParamStr text, sedFilename text, parallax real)''' ) except: raise RuntimeError("Error creating starsALL_forceseek table.") #Now generate the data to be stored in the tables. rr = numpy.random.sample(size) * numpy.radians(radius) theta = numpy.random.sample(size) * 2.0 * numpy.pi if displacedRA is None: ra = numpy.degrees(centerRA + rr * numpy.cos(theta)) else: ra = numpy.degrees(centerRA) + displacedRA if displacedDec is None: dec = numpy.degrees(centerDec + rr * numpy.sin(theta)) else: dec = numpy.degrees(centerDec) + displacedDec bra = numpy.radians(ra + numpy.random.sample(size) * 0.01 * radius) bdec = numpy.radians(dec + numpy.random.sample(size) * 0.01 * radius) dra = numpy.radians(ra + numpy.random.sample(size) * 0.01 * radius) ddec = numpy.radians(dec + numpy.random.sample(size) * 0.01 * radius) agnra = numpy.radians(ra + numpy.random.sample(size) * 0.01 * radius) agndec = numpy.radians(dec + numpy.random.sample(size) * 0.01 * radius) magnorm_bulge = numpy.random.sample(size) * 4.0 + 17.0 magnorm_disk = numpy.random.sample(size) * 5.0 + 17.0 magnorm_agn = numpy.random.sample(size) * 5.0 + 17.0 b_b = numpy.random.sample(size) * 0.2 a_b = b_b + numpy.random.sample(size) * 0.05 b_d = numpy.random.sample(size) * 0.5 a_d = b_d + numpy.random.sample(size) * 0.1 BulgeHalfLightRadius = numpy.random.sample(size) * 0.2 DiskHalfLightRadius = numpy.random.sample(size) * 0.5 pa_bulge = numpy.random.sample(size) * 360.0 pa_disk = numpy.random.sample(size) * 360.0 av_b = numpy.random.sample(size) * 0.4 av_d = numpy.random.sample(size) * 0.4 rv_b = numpy.random.sample(size) * 0.1 + 3.0 rv_d = numpy.random.sample(size) * 0.1 + 3.0 u_ab = numpy.random.sample(size) * 4.0 + 17.0 g_ab = numpy.random.sample(size) * 4.0 + 17.0 r_ab = numpy.random.sample(size) * 4.0 + 17.0 i_ab = numpy.random.sample(size) * 4.0 + 17.0 z_ab = numpy.random.sample(size) * 4.0 + 17.0 y_ab = numpy.random.sample(size) * 4.0 + 17.0 redshift = numpy.random.sample(size) * 2.0 t0_mjd = mjd - numpy.random.sample(size) * 1000.0 agn_tau = numpy.random.sample(size) * 1000.0 + 1000.0 agnSeed = numpy.random.random_integers(low=2, high=4000, size=size) agn_sfu = numpy.random.sample(size) agn_sfg = numpy.random.sample(size) agn_sfr = numpy.random.sample(size) agn_sfi = numpy.random.sample(size) agn_sfz = numpy.random.sample(size) agn_sfy = numpy.random.sample(size) rrStar = numpy.random.sample(size) * numpy.radians(radius) thetaStar = numpy.random.sample(size) * 2.0 * numpy.pi if displacedRA is None: raStar = centerRA + rrStar * numpy.cos(thetaStar) else: raStar = centerRA + numpy.radians(displacedRA) if displacedDec is None: decStar = centerDec + rrStar * numpy.sin(thetaStar) else: decStar = centerDec + numpy.radians(displacedDec) raStar = numpy.degrees(raStar) decStar = numpy.degrees(decStar) magnormStar = numpy.random.sample(size) * 4.0 + 17.0 mudecl = numpy.random.sample(size) * 0.0001 mura = numpy.random.sample(size) * 0.0001 galacticAv = numpy.random.sample(size) * 0.05 * 3.1 vrad = numpy.random.sample(size) * 1.0 parallax = 0.00045 + numpy.random.sample(size) * 0.00001 period = numpy.random.sample(size) * 20.0 amp = numpy.random.sample(size) * 5.0 #write the data to the tables. for i in range(size): cmd = '''INSERT INTO galaxy_bulge VALUES (%i, %i, %f, %f, %f, %f, %f, '%s', %f, %f, %f, %i, '%s', %f, %f, %f, %f, %f, %f, %f, %f, %f, %f)''' %\ (i, i, bra[i], bdec[i], ra[i], dec[i], magnorm_bulge[i], galaxy_seds[i%len(galaxy_seds)], a_b[i], b_b[i], pa_bulge[i], 4, 'CCM', av_b[i], rv_b[i], u_ab[i], g_ab[i], r_ab[i], i_ab[i], z_ab[i], y_ab[i], redshift[i], BulgeHalfLightRadius[i]) c.execute(cmd) varParam = { 'varMethodName': 'applyAgn', 'pars': { 'agn_tau': round(agn_tau[i], 4), 't0_mjd': round(t0_mjd[i], 4), 'agn_sfu': round(agn_sfu[i], 4), 'agn_sfg': round(agn_sfg[i], 4), 'agn_sfr': round(agn_sfr[i], 4), 'agn_sfi': round(agn_sfi[i], 4), 'agn_sfz': round(agn_sfz[i], 4), 'agn_sfy': round(agn_sfy[i], 4), 'seed': int(agnSeed[i]) } } paramStr = json.dumps(varParam) cmd = '''INSERT INTO galaxy VALUES (%i, %i, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, '%s', '%s', '%s', '%s', %f, %f, %f, %i, %f, %f, %f, %i, '%s', %f, %f, '%s', %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f)''' %\ (i, i, ra[i], dec[i], bra[i], bdec[i], dra[i], ddec[i], agnra[i], agndec[i], magnorm_bulge[i], magnorm_disk[i], magnorm_agn[i], galaxy_seds[i%len(galaxy_seds)], galaxy_seds[i%len(galaxy_seds)], agn_sed, paramStr, a_b[i], b_b[i], pa_bulge[i], 4, a_d[i], b_d[i], pa_disk[i], 1, 'CCM', av_b[i], rv_b[i], 'CCM', av_d[i], rv_d[i], u_ab[i], g_ab[i], r_ab[i], i_ab[i], z_ab[i], y_ab[i], redshift[i], BulgeHalfLightRadius[i], DiskHalfLightRadius[i]) c.execute(cmd) cmd = '''INSERT INTO galaxy_agn VALUES (%i, %i, %f, %f, %f, %f, %f, '%s', '%s', %f, %f, %f, %f, %f, %f, %f)''' %\ (i, i, agnra[i], agndec[i], ra[i], dec[i], magnorm_agn[i], agn_sed, paramStr, u_ab[i], g_ab[i], r_ab[i], i_ab[i], z_ab[i], y_ab[i], redshift[i]) c.execute(cmd) varParam = { 'varMethodName': 'testVar', 'pars': { 'period': period[i], 'amplitude': amp[i] } } paramStr = json.dumps(varParam) cmd = '''INSERT INTO starsALL_forceseek VALUES (%i, %f, %f, %f, %f, %f, %f, %f, '%s', '%s', %f)''' %\ (i, raStar[i], decStar[i], magnormStar[i], mudecl[i], mura[i], galacticAv[i], vrad[i], paramStr, star_seds[i%len(star_seds)], parallax[i]) c.execute(cmd) conn.commit() conn.close() return obs_metadata
def lsst_location(): site = Site('LSST') obs_loc_lsst = EarthLocation(lat=site.latitude, lon=site.longitude, height=site.height) sat_obs_lsst = satellite.SatelliteObserver(obs_loc_lsst) return sat_obs_lsst
def __init__(self, mjd_start=59853.5, readtime=2., filtername=None, f_change_time=140., shutter_time=1., nside=default_nside, sun_limit=-13., quickTest=True, alt_limit=20., seed=-1, cloud_limit=0.699, cloud_step=15., scheduled_downtime=None, unscheduled_downtime=None, seeing_model=None, cloud_model=None, environment=None, filters=None): """ Parameters ---------- mjd_start : float (59853.5) The Modified Julian Date to set the observatory to. readtime : float (2.) The time it takes to read out the camera (seconds). settle : float (2.) The time it takes the telescope to settle after slewing (seconds) filtername : str (None) The filter to start the observatory loaded with f_change_time : float (120.) The time it takes to change filters (seconds) shutter_time : float (1.) The time it takes to open or close the shutter. nside : int (32) The healpixel nside to make sky calculations on. sun_limit : float (-12.) The altitude limit for the sun (degrees) quickTest : bool (True) Load only a small pre-computed sky array rather than a full year. seed : float Random seed to potentially pass to unscheduled downtime cloud_limit : float (0.699) Close dome for cloud values over this (traditionally measured in 8ths of the sky?) cloud_step : float (15.) Minutes to close if clouds exceed cloud_limit scheduled_downtime : ScheduledDowntime (None) The scheduled downtime interface. If None (default) use sims_ocs module. unscheduled_downtime : UnscheduledDowntime (None) The unscheduled downtime interface. If None (default) use sims_ocs module. seeing_model : SeeingModel (None) The seeing model interface. If None (default) use sims_ocs module. cloud_model : CloudModel (None) The cloud model interface. If None (default) use sims_ocs module. environment : Environment (None) The environment interface. If None (default) use sims_ocs module. filters : Filters (None) The Filters interface. If None (default) use sims_ocs module. """ # Make it easy to see what version the object is self.version = version self.mjd_start = mjd_start + 0 self.mjd = mjd_start self.f_change_time = f_change_time self.readtime = readtime self.shutter_time = shutter_time self.sun_limit = np.radians(sun_limit) self.alt_limit = np.radians(alt_limit) # Load up the sky brightness model self.sky = sb.SkyModelPre(speedLoad=quickTest) # Should realy set this by inspecting the map. self.sky_nside = 32 # Start out parked self.ra = None self.dec = None self.filtername = None # Set up all sky coordinates hpids = np.arange(hp.nside2npix(self.sky_nside)) self.ra_all_sky, self.dec_all_sky = _hpid2RaDec(self.sky_nside, hpids) self.status = None self.site = Site(name='LSST') self.obs = ephem.Observer() self.obs.lat = self.site.latitude_rad self.obs.lon = self.site.longitude_rad self.obs.elevation = self.site.height self.obs.horizon = 0. self.sun = ephem.Sun() self.moon = ephem.Moon() # Generate sunset times so we can label nights by integers self.generate_sunsets() self.night = self.mjd2night(self.mjd) # Make my dummy time handler dth = dummy_time_handler(mjd_start) # Make a slewtime interpolator self.slew_interp = Slewtime_pre() # Compute downtimes self.down_nights = [] if scheduled_downtime is not None: sdt = scheduled_downtime else: sdt = ScheduledDowntime() sdt.initialize() if unscheduled_downtime is not None: usdt = unscheduled_downtime else: usdt = UnscheduledDowntime() usdt.initialize(random_seed=seed) for downtime in sdt.downtimes: self.down_nights.extend(range(downtime[0], downtime[0]+downtime[1], 1)) for downtime in usdt.downtimes: self.down_nights.extend(range(downtime[0], downtime[0]+downtime[1], 1)) self.down_nights.sort() if seeing_model is not None: self.seeing_model = seeing_model else: self.seeing_model = SeeingSim(dth) if cloud_model is not None: self.cloud_model = cloud_model else: self.cloud_model = CloudModel(dth) self.cloud_model.read_data() self.cloud_limit = cloud_limit self.cloud_step = cloud_step/60./24.
def generate_nights(mjd_start, duration=3653., rough_step=2, verbose=False): """Generate the sunset and twilight times for a range of dates Parameters ---------- mjd_start : float The starting mjd duration : float (3653) How long to compute times for (days) rough_step : float (2.) Time step for computing first pass rough sunrise times (hours) """ # Let's find the nights first, find the times where the sun crosses the meridian. site = Site('LSST') location = EarthLocation(lat=site.latitude, lon=site.longitude, height=site.height) # go on 1/10th of a day steps t_step = rough_step / 24. pad_around = 30. / 24. t_sparse = Time(np.arange(mjd_start - pad_around, duration + mjd_start + pad_around + t_step, t_step), format='mjd', location=location) sun = get_sun(t_sparse) aa = AltAz(location=location, obstime=t_sparse) sun_aa_sparse = sun.transform_to(aa) moon = get_moon(t_sparse) moon_aa_sparse = moon.transform_to(aa) # Indices right before sunset mjd_sunset_rough = alt_passing_interp(t_sparse.mjd, sun_aa_sparse.alt.deg, goal_alt=0., rising=False) names = [ 'night', 'sunset', 'sun_n12_setting', 'sun_n18_setting', 'sun_n18_rising', 'sun_n12_rising', 'sunrise', 'moonrise', 'moonset' ] types = [int] types.extend([float] * (len(names) - 1)) alt_info_array = np.zeros(mjd_sunset_rough.size, dtype=list(zip(names, types))) alt_info_array['sunset'] = mjd_sunset_rough # label the nights alt_info_array['night'] = np.arange(mjd_sunset_rough.size) night_1_index = np.searchsorted(alt_info_array['sunset'], mjd_start) alt_info_array['night'] += 1 - alt_info_array['night'][night_1_index] # OK, now I have sunset times sunrises = alt_passing_interp(t_sparse.mjd, sun_aa_sparse.alt.deg, goal_alt=0., rising=True) # Make sure sunrise happens after sunset insert_indices = np.searchsorted( alt_info_array['sunset'], sunrises, side='left') - 1 good_indices = np.where(insert_indices > 0)[0] alt_info_array['sunrise'][ insert_indices[good_indices]] = sunrises[good_indices] # Should probably write the function to get rin of the copy-pasta point = alt_passing_interp(t_sparse.mjd, sun_aa_sparse.alt.deg, goal_alt=-12., rising=False) insert_indices = np.searchsorted( alt_info_array['sunset'], point, side='left') - 1 good_indices = np.where(insert_indices > 0)[0] alt_info_array['sun_n12_setting'][ insert_indices[good_indices]] = point[good_indices] point = alt_passing_interp(t_sparse.mjd, sun_aa_sparse.alt.deg, goal_alt=-12., rising=True) insert_indices = np.searchsorted( alt_info_array['sunset'], point, side='left') - 1 good_indices = np.where(insert_indices > 0)[0] alt_info_array['sun_n12_rising'][ insert_indices[good_indices]] = point[good_indices] point = alt_passing_interp(t_sparse.mjd, sun_aa_sparse.alt.deg, goal_alt=-18., rising=True) insert_indices = np.searchsorted( alt_info_array['sunset'], point, side='left') - 1 good_indices = np.where(insert_indices > 0)[0] alt_info_array['sun_n18_rising'][ insert_indices[good_indices]] = point[good_indices] point = alt_passing_interp(t_sparse.mjd, sun_aa_sparse.alt.deg, goal_alt=-18., rising=False) insert_indices = np.searchsorted( alt_info_array['sunset'], point, side='left') - 1 good_indices = np.where(insert_indices > 0)[0] alt_info_array['sun_n18_setting'][ insert_indices[good_indices]] = point[good_indices] point = alt_passing_interp(t_sparse.mjd, moon_aa_sparse.alt.deg, goal_alt=0., rising=True) insert_indices = np.searchsorted( alt_info_array['sunset'], point, side='left') - 1 good_indices = np.where(insert_indices > 0)[0] alt_info_array['moonrise'][ insert_indices[good_indices]] = point[good_indices] point = alt_passing_interp(t_sparse.mjd, moon_aa_sparse.alt.deg, goal_alt=0., rising=False) insert_indices = np.searchsorted( alt_info_array['sunset'], point, side='left') - 1 good_indices = np.where(insert_indices > 0)[0] alt_info_array['moonset'][ insert_indices[good_indices]] = point[good_indices] # Crop off some regions that might not have been filled good = np.where(alt_info_array['night'] > 0)[0] alt_info_array = alt_info_array[good[:-1]] # Put bounds so we don't go to far from rough fit refined_mjds = np.empty_like(alt_info_array) refined_mjds['night'] = alt_info_array['night'] names_dict = { 'sunset': 0., 'sun_n12_setting': 12., 'sun_n18_setting': 18., 'sun_n18_rising': 18., 'sun_n12_rising': 12., 'sunrise': 0 } # Need to keep the runtime reasonable options = {'maxiter': 5} for key in names_dict: if verbose: print(key) bounds = Bounds(alt_info_array[key] - rough_step / 10. / 24., alt_info_array[key] + rough_step / 10. / 24.) new_mjds = minimize(alt_sun_sum, alt_info_array[key], bounds=bounds, args=(location, names_dict[key]), options=options) refined_mjds[key] = new_mjds.x for key in ['moonrise', 'moonset']: if verbose: print(key) bounds = Bounds(alt_info_array[key] - rough_step / 10. / 24., alt_info_array[key] + rough_step / 10. / 24.) new_mjds = minimize(alt_moon_sum, alt_info_array[key], bounds=bounds, args=(location, 0.), options=options) refined_mjds[key] = new_mjds.x # Note, there is the possibility that some moonrise/moonset times changed nights upon refinement. I suppose # I could do another seatchsorted pass here just to be extra sure nothing changed. return alt_info_array, refined_mjds
def __init__(self, nside=None, mjd_start=59853.5, seed=42, quickTest=True, alt_min=5., lax_dome=True, cloud_limit=0.3, sim_ToO=None, seeing_db=None, cloud_db=None, cloud_offset_year=0): """ Parameters ---------- nside : int (None) The healpix nside resolution mjd_start : float (59853.5) The MJD to start the observatory up at alt_min : float (5.) The minimum altitude to compute models at (degrees). lax_dome : bool (True) Passed to observatory model. If true, allows dome creep. cloud_limit : float (0.3) The limit to stop taking observations if the cloud model returns something equal or higher sim_ToO : sim_targetoO object (None) If one would like to inject simulated ToOs into the telemetry stream. seeing_db : filename of the seeing data database (None) If one would like to use an alternate seeing database cloud_offset_year : float, opt Offset into the cloud database by 'offset_year' years. Default 0. cloud_db : filename of the cloud data database (None) If one would like to use an alternate seeing database """ if nside is None: nside = set_default_nside() self.nside = nside self.cloud_limit = cloud_limit self.alt_min = np.radians(alt_min) self.lax_dome = lax_dome self.mjd_start = mjd_start # Conditions object to update and return on request self.conditions = Conditions(nside=self.nside) self.sim_ToO = sim_ToO # Create an astropy location self.site = Site('LSST') self.location = EarthLocation(lat=self.site.latitude, lon=self.site.longitude, height=self.site.height) # Load up all the models we need mjd_start_time = Time(self.mjd_start, format='mjd') # Downtime self.down_nights = [] self.sched_downtime_data = ScheduledDowntimeData(mjd_start_time) self.unsched_downtime_data = UnscheduledDowntimeData(mjd_start_time) sched_downtimes = self.sched_downtime_data() unsched_downtimes = self.unsched_downtime_data() down_starts = [] down_ends = [] for dt in sched_downtimes: down_starts.append(dt['start'].mjd) down_ends.append(dt['end'].mjd) for dt in unsched_downtimes: down_starts.append(dt['start'].mjd) down_ends.append(dt['end'].mjd) self.downtimes = np.array(list(zip(down_starts, down_ends)), dtype=list( zip(['start', 'end'], [float, float]))) self.downtimes.sort(order='start') # Make sure there aren't any overlapping downtimes diff = self.downtimes['start'][1:] - self.downtimes['end'][0:-1] while np.min(diff) < 0: # Should be able to do this wihtout a loop, but this works for i, dt in enumerate(self.downtimes[0:-1]): if self.downtimes['start'][i + 1] < dt['end']: new_end = np.max([dt['end'], self.downtimes['end'][i + 1]]) self.downtimes[i]['end'] = new_end self.downtimes[i + 1]['end'] = new_end good = np.where( self.downtimes['end'] - np.roll(self.downtimes['end'], 1) != 0) self.downtimes = self.downtimes[good] diff = self.downtimes['start'][1:] - self.downtimes['end'][0:-1] self.seeing_data = SeeingData(mjd_start_time, seeing_db=seeing_db) self.seeing_model = SeeingModel() self.seeing_indx_dict = {} for i, filtername in enumerate(self.seeing_model.filter_list): self.seeing_indx_dict[filtername] = i self.cloud_data = CloudData(mjd_start_time, cloud_db=cloud_db, offset_year=cloud_offset_year) sched_logger.info( f"Using {self.cloud_data.cloud_db} as cloud database with start year {self.cloud_data.start_time.iso}" ) self.sky_model = sb.SkyModelPre(speedLoad=quickTest) self.observatory = ExtendedObservatoryModel() self.observatory.configure_from_module() # Make it so it respects my requested rotator angles self.observatory.params.rotator_followsky = True self.filterlist = ['u', 'g', 'r', 'i', 'z', 'y'] self.seeing_FWHMeff = {} for key in self.filterlist: self.seeing_FWHMeff[key] = np.zeros(hp.nside2npix(self.nside), dtype=float) self.almanac = Almanac(mjd_start=mjd_start) # Let's make sure we're at an openable MJD good_mjd = False to_set_mjd = mjd_start while not good_mjd: good_mjd, to_set_mjd = self.check_mjd(to_set_mjd) self.mjd = to_set_mjd self.obsID_counter = 0
def obs2sqlite(observations_in, location='LSST', outfile='observations.sqlite', slewtime_limit=5., full_sky=False, radians=True): """ Utility to take an array of observations and dump it to a sqlite file, filling in useful columns along the way. observations_in: numpy array with at least columns of ra : RA in degrees dec : dec in degrees mjd : MJD in day filter : string with the filter name exptime : the exposure time in seconds slewtime_limit : float Consider all slewtimes larger than this to be closed-dome time not part of a slew. """ # Set the location to be LSST if location == 'LSST': telescope = Site('LSST') # Check that we have the columns we need needed_cols = ['ra', 'dec', 'mjd', 'filter'] in_cols = observations_in.dtype.names for col in needed_cols: if needed_cols not in in_cols: ValueError('%s column not found in observtion array' % col) n_obs = observations_in.size sm = None # make sure they are in order by MJD observations_in.sort(order='mjd') # Take all the columns that are in the input and add any missing names = ['filter', 'ra', 'dec', 'mjd', 'exptime', 'alt', 'az', 'skybrightness', 'seeing', 'night', 'slewtime', 'fivesigmadepth', 'airmass', 'sunAlt', 'moonAlt'] types = ['|S1'] types.extend([float]*(len(names)-1)) observations = np.zeros(n_obs, dtype=list(zip(names, types))) # copy over the ones we have for col in in_cols: observations[col] = observations_in[col] # convert output to be in degrees like expected if radians: observations['ra'] = np.degrees(observations['ra']) observations['dec'] = np.degrees(observations['dec']) if 'exptime' not in in_cols: observations['exptime'] = 30. # Fill in the slewtime. Note that filterchange time gets included in slewtimes if 'slewtime' not in in_cols: # Assume MJD is midpoint of exposures mjd_sec = observations_in['mjd']*24.*3600. observations['slewtime'][1:] = mjd_sec[1:]-mjd_sec[0:-1] - observations['exptime'][0:-1]*0.5 - observations['exptime'][1:]*0.5 closed = np.where(observations['slewtime'] > slewtime_limit*60.) observations['slewtime'][closed] = 0. # Let's just use the stupid-fast to get alt-az if 'alt' not in in_cols: alt, az = stupidFast_RaDec2AltAz(np.radians(observations['ra']), np.radians(observations['dec']), telescope.latitude_rad, telescope.longitude_rad, observations['mjd']) observations['alt'] = np.degrees(alt) observations['az'] = np.degrees(az) # Fill in the airmass if 'airmass' not in in_cols: observations['airmass'] = 1./np.cos(np.pi/2. - np.radians(observations['alt'])) # Fill in the seeing if 'seeing' not in in_cols: # XXX just fill in a dummy val observations['seeing'] = 0.8 if 'night' not in in_cols: m2n = mjd2night() observations['night'] = m2n(observations['mjd']) # Sky Brightness if 'skybrightness' not in in_cols: if full_sky: sm = SkyModel(mags=True) for i, obs in enumerate(observations): sm.setRaDecMjd(obs['ra'], obs['dec'], obs['mjd'], degrees=True) observations['skybrightness'][i] = sm.returnMags()[obs['filter']] else: # Let's try using the pre-computed sky brighntesses sm = sb.SkyModelPre(preload=False) full = sm.returnMags(observations['mjd'][0]) nside = hp.npix2nside(full['r'].size) imax = float(np.size(observations)) for i, obs in enumerate(observations): indx = raDec2Hpid(nside, obs['ra'], obs['dec']) observations['skybrightness'][i] = sm.returnMags(obs['mjd'], indx=[indx])[obs['filter']] sunMoon = sm.returnSunMoon(obs['mjd']) observations['sunAlt'][i] = sunMoon['sunAlt'] observations['moonAlt'][i] = sunMoon['moonAlt'] progress = i/imax*100 text = "\rprogress = %.2f%%"%progress sys.stdout.write(text) sys.stdout.flush() observations['sunAlt'] = np.degrees(observations['sunAlt']) observations['moonAlt'] = np.degrees(observations['moonAlt']) # 5-sigma depth for fn in np.unique(observations['filter']): good = np.where(observations['filter'] == fn) observations['fivesigmadepth'][good] = m5_flat_sed(fn, observations['skybrightness'][good], observations['seeing'][good], observations['exptime'][good], observations['airmass'][good]) conn = sqlite3.connect(outfile) df = pd.DataFrame(observations) df.to_sql('observations', conn)
def runSlices(opsimName, metadata, simdata, fields, bins, args, opsDb, verbose=False): # Set up the movie slicer. movieslicer = setupMovieSlicer(simdata, bins) # Set up formatting for output suffix. sliceformat = '%s0%dd' % ('%', int(np.log10(len(movieslicer))) + 1) # Get the telescope latitude info. lat_tele = Site(name='LSST').latitude_rad # Run through the movie slicer slicePoints and generate plots at each point. for i, ms in enumerate(movieslicer): t = time.time() slicenumber = sliceformat % (i) if verbose: print(slicenumber) # Set up metrics. if args.movieStepsize != 0: tstep = args.movieStepsize else: tstep = ms['slicePoint']['binRight'] - bins[i] if tstep > 1: tstep = 40. / 24. / 60. / 60. # Add simple view of time to plot label. times_from_start = ms['slicePoint']['binRight'] - (int(bins[0]) + 0.16 - 0.5) # Opsim years are 365 days (not 365.25) years = int(times_from_start / 365) days = times_from_start - years * 365 plotlabel = 'Year %d Day %.4f' % (years, days) # Set up metrics. metricList, plotDictList = setupMetrics( opsimName, metadata, plotlabel=plotlabel, t0=ms['slicePoint']['binRight'], tStep=tstep, years=years, verbose=verbose) # Identify the subset of simdata in the movieslicer 'data slice' simdatasubset = simdata[ms['idxs']] # Set up opsim slicer on subset of simdata provided by movieslicer opslicer = slicers.OpsimFieldSlicer( simDataFieldIdColName='opsimFieldId', fieldIdColName='opsimFieldId') # Set up metricBundles to combine metrics, plotdicts and slicer. bundles = [] sqlconstraint = '' for metric, plotDict in zip(metricList, plotDictList): bundles.append( metricBundles.MetricBundle(metric, opslicer, constraint=sqlconstraint, metadata=metadata, runName=opsimName, plotDict=plotDict)) # Remove (default) stackers from bundles, because we've already run them above on the original data. for mb in bundles: mb.stackerList = [] bundledict = metricBundles.makeBundlesDictFromList(bundles) # Set up metricBundleGroup to handle metrics calculation + plotting bg = metricBundles.MetricBundleGroup(bundledict, opsDb, outDir=args.outDir, resultsDb=None, saveEarly=False) # 'Hack' bundleGroup to just go ahead and run the metrics, without querying the database. simData = simdatasubset bg.fieldData = fields bg.setCurrent(sqlconstraint) bg.runCurrent(constraint=sqlconstraint, simData=simData) # Plot data each metric, for this slice of the movie, adding slicenumber as a suffix for output plots. # Plotting here, rather than automatically via sliceMetric method because we're going to rotate the sky, # and add extra legend info and figure text (for FilterColors metric). ph = plots.PlotHandler(outDir=args.outDir, figformat='png', dpi=72, thumbnail=False, savefig=False) obsnow = np.where(simdatasubset['observationStartMJD'] == simdatasubset['observationStartMJD'].max())[0] raCen = np.radians( np.mean(simdatasubset[obsnow]['observationStartLST'])) # Calculate horizon location. horizonlon, horizonlat = addHorizon(lat_telescope=lat_tele) # Create the plot for each metric and save it (after some additional manipulation). for mb in bundles: ph.setMetricBundles([mb]) fignum = ph.plot(plotFunc=plots.BaseSkyMap(), plotDicts={'raCen': raCen}) fig = plt.figure(fignum) ax = plt.gca() # Add horizon and zenith. plt.plot(horizonlon, horizonlat, 'k.', alpha=0.3, markersize=1.8) plt.plot(0, lat_tele, 'k+') # For the FilterColors metric, add some extra items. if mb.metric.name == 'FilterColors': # Add the time stamp info (plotlabel) with a fancybox. plt.figtext(0.75, 0.9, '%s' % (plotlabel), bbox=dict(boxstyle='Round, pad=0.7', fc='w', ec='k', alpha=0.5)) # Add a legend for the filters. filterstacker = stackers.FilterColorStacker() for i, f in enumerate(['u', 'g', 'r', 'i', 'z', 'y']): plt.figtext(0.92, 0.55 - i * 0.035, f, color=filterstacker.filter_rgb_map[f]) # Add a moon. moonRA = np.radians(np.mean(simdatasubset[obsnow]['moonRA'])) lon = -(moonRA - raCen - np.pi) % (np.pi * 2) - np.pi moonDec = np.radians(np.mean(simdatasubset[obsnow]['moonDec'])) # Note that moonphase is 0-100 (translate to 0-1). 0=new. moonPhase = np.mean(simdatasubset[obsnow]['moonPhase']) / 100. alpha = np.max([moonPhase, 0.15]) circle = Circle((lon, moonDec), radius=0.05, color='k', alpha=alpha) ax.add_patch(circle) # Add some explanatory text. ecliptic = Line2D([], [], color='r', label="Ecliptic plane") galaxy = Line2D([], [], color='b', label="Galactic plane") horizon = Line2D([], [], color='k', alpha=0.3, label="20 deg elevation limit") moon = Line2D([], [], color='k', linestyle='', marker='o', markersize=8, alpha=alpha, label="\nMoon (Dark=Full)\n (Light=New)") zenith = Line2D([], [], color='k', linestyle='', marker='+', markersize=5, label="Zenith") plt.legend( handles=[horizon, zenith, galaxy, ecliptic, moon], loc=[0.1, -0.35], ncol=3, frameon=False, title= 'Aitoff plot showing HA/Dec of simulated survey pointings', numpoints=1, fontsize='small') # Save figure. plt.savefig(os.path.join( args.outDir, mb.metric.name + '_' + slicenumber + '_SkyMap.png'), format='png', dpi=72) plt.close('all') dt, t = dtime(t) if verbose: print('Ran and plotted slice %s of movieslicer in %f s' % (slicenumber, dt))
def generate_ddf(ddf_name, nyears=10, space=2): previous_ddf = generate_dd_surveys() survey_names = np.array([survey.survey_name for survey in previous_ddf]) survey_indx = np.where(survey_names == ddf_name)[0].max() ddf_ra = previous_ddf[survey_indx].ra * u.rad ddf_dec = previous_ddf[survey_indx].dec * u.rad site = Site('LSST') location = EarthLocation(lat=site.latitude, lon=site.longitude, height=site.height) mjd = np.arange(59853.5, 59853.5 + 365.25 * nyears, 20. / 60 / 24.) times = Time(mjd, format='mjd', location=location) airmass_limit = 2.5 # demand airmass lower than this twilight_limit = -18. # Sun below this altitude in degrees dist_to_moon_limit = 30. # minimum distance to keep from moon degrees zenith_limit = 10. # Need to be this far away from zenith to start (20 min = 5 deg) g_m5_limit = 23.5 # mags season_gap = 20. # days. Count any gap longer than this as it's own season season_length_limit = 80 # Days. Demand at least this many days in a season # How long to keep attempting a DDF expire_dict = {1: 36. / 24., 2: 0.5} sun_coords = get_sun(times) moon_coords = get_moon(times) sched_downtime_data = ScheduledDowntimeData(Time(mjd[0], format='mjd')) observatory_up = np.ones(mjd.size, dtype=bool) for dt in sched_downtime_data(): indx = np.where((mjd >= dt['start'].mjd) & (mjd <= dt['end'].mjd))[0] observatory_up[indx] = False lst = times.sidereal_time('mean') sun_altaz = sun_coords.transform_to(AltAz(location=location)) # generate a night label for each timestep sun_rise = np.where((sun_altaz.alt[0:-1] < 0) & (sun_altaz.alt[1:] > 0))[0] night = np.zeros(mjd.size, dtype=int) night[sun_rise] = 1 night = np.cumsum(night) + 1 # 1-index for night sun_down = np.where(sun_altaz.alt < twilight_limit * u.deg)[0] ddf_coord = SkyCoord(ra=ddf_ra, dec=ddf_dec) ddf_altaz = ddf_coord.transform_to(AltAz(location=location, obstime=times)) ddf_airmass = 1. / np.cos(np.radians(90. - ddf_altaz.az.deg)) zenith = AltAz(alt=90. * u.deg, az=0. * u.deg) ddf_zenth_dist = zenith.separation(ddf_altaz) nside = 32 ddf_indx = raDec2Hpid(nside, ddf_coord.ra.deg, ddf_coord.dec.deg) sm = SkyModelPre() g_sb = mjd * 0 + np.nan indices = np.where((sun_altaz.alt < twilight_limit * u.deg) & (ddf_airmass > airmass_limit))[0] # In theory, one could reach into the sky brightness model and do a much faster interpolation # There might be an airmass limit on the sky brightness. for indx in sun_down: g_sb[indx] = sm.returnMags(mjd[indx], indx=[ddf_indx], filters='g', badval=np.nan)['g'] dist_to_moon = ddf_coord.separation(moon_coords) seeing_model = SeeingModel() ddf_approx_fwhmEff = seeing_model(0.7, ddf_airmass) # I think this should pluck out the g-filter. Really should be labled ddf_approx_fwhmEff = ddf_approx_fwhmEff['fwhmEff'][1].ravel() ddf_m5 = m5_flat_sed('g', g_sb, ddf_approx_fwhmEff, 30., ddf_airmass, nexp=1.) # demand sun down past twilight, ddf is up, and observatory is open, and not too close to the moon good = np.where((ddf_airmass < airmass_limit) & (sun_altaz.alt < twilight_limit * u.deg) & (ddf_airmass > 0) & (observatory_up == True) & (dist_to_moon > dist_to_moon_limit * u.deg) & (ddf_zenth_dist > zenith_limit * u.deg) & (ddf_m5 > g_m5_limit)) potential_nights = np.unique(night[good]) night_gap = potential_nights[1:] - potential_nights[0:-1] big_gap = np.where(night_gap > season_gap)[0] + 1 season = potential_nights * 0 season[big_gap] = 1 season = np.cumsum(season) u_seasons = np.unique(season) season_lengths = [] for se in u_seasons: in_se = np.where(season == se) season_lengths.append( np.max(potential_nights[in_se]) - np.min(potential_nights[in_se])) season_lengths = np.array(season_lengths) good_seasons = u_seasons[np.where(season_lengths > season_length_limit)[0]] gn = np.isin(season, good_seasons) potential_nights = potential_nights[gn] season = season[gn] obs_attempts = [] for sea in np.unique(season): night_indx = np.where(season == sea) obs_attempts.append( place_obs(potential_nights[night_indx], space=space)) obs_attempts = np.concatenate(obs_attempts) mjd_observe = [] m5_approx = [] for indx in np.where(obs_attempts > 0)[0]: in_night_indx = np.where(night == potential_nights[indx])[0] best_depth_indx = np.min( np.where( ddf_m5[in_night_indx] == np.nanmax(ddf_m5[in_night_indx]))[0]) mjd_start = mjd[in_night_indx[best_depth_indx]] m5_approx.append(ddf_m5[in_night_indx[best_depth_indx]]) mjd_end = mjd_start + expire_dict[obs_attempts[indx]] mjd_observe.append((mjd_start, mjd_end)) result = np.zeros(len(mjd_observe), dtype=[('mjd_start', '<f8'), ('mjd_end', '<f8'), ('label', '<U10')]) mjd_observe = np.array(mjd_observe) result['mjd_start'] = mjd_observe[:, 0] result['mjd_end'] = mjd_observe[:, 1] result['label'] = ddf_name return result #, ddf_ra, ddf_dec #, previous_ddf[survey_indx].observations, m5_approx
# imports from os import path from os import environ import numpy as np import pandas as pd import sqlite3 import astropy import astropy.units as u from astropy.time import Time from astropy.coordinates import get_moon, get_sun, EarthLocation from lsst.sims.utils import Site from scipy.signal import argrelextrema # constants SITE = Site('LSST') LOCATION = EarthLocation(lat=SITE.latitude, lon=SITE.longitude,height=SITE.height) START_MJD = 59853 SURVEY_DURATION = 366*20 SYNODIC_MONTH_DAYS = 29.530589 # From Lang's *Astrophysical Data*, p. 57 DOWNTIME_DURATION = 14 REF_DOWNTIME_DB = path.join(environ['SIMS_DOWNTIMEMODEL_DIR'], 'data', 'scheduled_downtime.db') def compute_full_moon_nights(location, start_mjd, duration=SURVEY_DURATION): # Use UTC midnight, shifted to the site using the longitude # Should be good to within ~15 minutes mjds = np.arange(start_mjd, start_mjd + duration) - LOCATION.lon.deg/360 times = Time(mjds, format='mjd', location=LOCATION)
bp_dict, hw_dict = BandpassDict.loadBandpassesFromFiles() opsimdb = os.path.join('/Users/danielsf/physics/lsst_150412', 'Development', 'garage', 'OpSimData', 'minion_1016_sqlite.db') obs_gen = ObservationMetaDataGenerator(opsimdb) obs_list = obs_gen.getObservationMetaData(moonAlt=(-90.0, -50.0), altitude=(55.0, 57.0), fieldDec=(-10.0, 10.0)) assert len(obs_list) > 0 obs_root = obs_list[0] obs_root.site = Site(name='LSST', pressure=0.0, humidity=0.0) phosim_header = DefaultPhoSimHeaderMap phosim_header['nsnap'] = 1 phosim_header['vistime'] = 30.0 galaxy_dir = os.path.join(getPackageDir('sims_sed_library'), 'galaxySED') galaxy_sed_list = os.listdir(galaxy_dir) magnorm_interp = {} from lsst.sims.photUtils import PhotometricParameters, Bandpass phot_params = PhotometricParameters(nexp=1, exptime=30.0, gain=1) imsim = Bandpass() imsim.imsimBandpass()
def __init__(self, mjd_start=59580.035, readtime=2., filtername=None, f_change_time=140., nside=default_nside, sun_limit=-13., quickTest=True, alt_limit=20., seed=-1, cloud_limit=7., cloud_step=15.): """ Parameters ---------- mjd_start : float (59580.035) The Modified Julian Date to set the observatory to. readtime : float (2.) The time it takes to read out the camera (seconds). settle : float (2.) The time it takes the telescope to settle after slewing (seconds) filtername : str (None) The filter to start the observatory loaded with f_change_time : float (120.) The time it takes to change filters (seconds) nside : int (32) The healpixel nside to make sky calculations on. sun_limit : float (-12.) The altitude limit for the sun (degrees) quickTest : bool (True) Load only a small pre-computed sky array rather than a full year. seed : float Random seed to potentially pass to unscheduled downtime cloud_limit : float (7) Close dome for cloud values over this (traditionally measured in 8ths of the sky) cloud_step : float (15.) Minutes to close if clouds exceed cloud_limit """ self.mjd_start = mjd_start + 0 self.mjd = mjd_start self.f_change_time = f_change_time self.readtime = readtime self.sun_limit = np.radians(sun_limit) self.alt_limit = np.radians(alt_limit) # Load up the sky brightness model self.sky = sb.SkyModelPre(preload=False, speedLoad=quickTest) # Should realy set this by inspecting the map. self.sky_nside = 32 # Start out parked self.ra = None self.dec = None self.filtername = None # Set up all sky coordinates hpids = np.arange(hp.nside2npix(self.sky_nside)) self.ra_all_sky, self.dec_all_sky = _hpid2RaDec(self.sky_nside, hpids) self.status = None self.site = Site(name='LSST') self.obs = ephem.Observer() self.obs.lat = self.site.latitude_rad self.obs.lon = self.site.longitude_rad self.obs.elevation = self.site.height self.obs.horizon = 0. self.sun = ephem.Sun() # Generate sunset times so we can label nights by integers self.generate_sunsets() self.night = self.mjd2night(self.mjd) # Make a slewtime interpolator self.slew_interp = Slewtime_pre() # Compute downtimes self.down_nights = [] sdt = ScheduledDowntime() sdt.initialize() usdt = UnscheduledDowntime() usdt.initialize(random_seed=seed) for downtime in sdt.downtimes: self.down_nights.extend( range(downtime[0], downtime[0] + downtime[1], 1)) for downtime in usdt.downtimes: self.down_nights.extend( range(downtime[0], downtime[0] + downtime[1], 1)) self.down_nights.sort() # Instatiate a seeing model env_config = Environment() filter_config = Filters() self.seeing_model = SeeingModel_no_time() self.seeing_model.initialize(env_config, filter_config) self.cloud_model = CloudModel_no_time() self.cloud_model.initialize() self.cloud_limit = cloud_limit self.cloud_step = cloud_step / 60. / 24.
# dome is open and what the seeing is udt = UnscheduledDowntime() udt.initialize() sdt = ScheduledDowntime() sdt.initialize() # consolidate a list of nights where things are down. I need to do weather too I guess. nights_down = [] #seeing_model = SeeingModel(None) # I guess I should load up the ephem and make sure the sun isn't up. sun = ephem.Sun() site = Site(name='LSST') obs = ephem.Observer() obs.lat = site.latitude_rad obs.lon = site.longitude_rad obs.elevation = site.height obs.horizon = 0. # find the rising and setting sun times mjd_start = mjd0 mjd_end = mjd_max step = 0.25 mjds = np.arange(mjd_start, mjd_end + step, step) setting = mjds * 0. risings = mjds * 0.
def testOverrideLSSTdefaults(self): """ Test that, even if LSST is specified, we are capable of overriding defaults """ site = Site(name='LSST', longitude=26.0) self.assertEqual(site.name, 'LSST') self.assertEqual(site.longitude, 26.0) self.assertEqual(site.longitude_rad, np.radians(26.0)) self.assertEqual(site.latitude, self.latitude) self.assertEqual(site.latitude_rad, np.radians(self.latitude)) self.assertEqual(site.temperature, self.temperature) self.assertEqual(site.pressure, self.pressure) self.assertEqual(site.humidity, self.humidity) self.assertEqual(site.lapseRate, self.lapseRate) self.assertEqual(site.height, self.height) site = Site(name='LSST', latitude=88.0) self.assertEqual(site.name, 'LSST') self.assertEqual(site.longitude, self.longitude) self.assertEqual(site.longitude_rad, np.radians(self.longitude)) self.assertEqual(site.latitude, 88.0) self.assertEqual(site.latitude_rad, np.radians(88.0)) self.assertEqual(site.temperature, self.temperature) self.assertEqual(site.temperature_kelvin, self.temperature + 273.15) self.assertEqual(site.pressure, self.pressure) self.assertEqual(site.humidity, self.humidity) self.assertEqual(site.lapseRate, self.lapseRate) self.assertEqual(site.height, self.height) site = Site(name='LSST', height=4.0) self.assertEqual(site.name, 'LSST') self.assertEqual(site.longitude, self.longitude) self.assertEqual(site.longitude_rad, np.radians(self.longitude)) self.assertEqual(site.latitude, self.latitude) self.assertEqual(site.latitude_rad, np.radians(self.latitude)) self.assertEqual(site.temperature, self.temperature) self.assertEqual(site.temperature_kelvin, self.temperature + 273.15) self.assertEqual(site.pressure, self.pressure) self.assertEqual(site.humidity, self.humidity) self.assertEqual(site.lapseRate, self.lapseRate) self.assertEqual(site.height, 4.0) site = Site(name='LSST', temperature=7.0) self.assertEqual(site.name, 'LSST') self.assertEqual(site.longitude, self.longitude) self.assertEqual(site.longitude_rad, np.radians(self.longitude)) self.assertEqual(site.latitude, self.latitude) self.assertEqual(site.latitude_rad, np.radians(self.latitude)) self.assertEqual(site.temperature, 7.0) self.assertEqual(site.temperature_kelvin, 280.15) self.assertEqual(site.pressure, self.pressure) self.assertEqual(site.humidity, self.humidity) self.assertEqual(site.lapseRate, self.lapseRate) self.assertEqual(site.height, self.height) site = Site(name='LSST', pressure=14.0) self.assertEqual(site.name, 'LSST') self.assertEqual(site.longitude, self.longitude) self.assertEqual(site.longitude_rad, np.radians(self.longitude)) self.assertEqual(site.latitude, self.latitude) self.assertEqual(site.latitude_rad, np.radians(self.latitude)) self.assertEqual(site.temperature, self.temperature) self.assertEqual(site.temperature_kelvin, self.temperature + 273.15) self.assertEqual(site.pressure, 14.0) self.assertEqual(site.humidity, self.humidity) self.assertEqual(site.lapseRate, self.lapseRate) self.assertEqual(site.height, self.height) site = Site(name='LSST', humidity=2.1) self.assertEqual(site.name, 'LSST') self.assertEqual(site.longitude, self.longitude) self.assertEqual(site.longitude_rad, np.radians(self.longitude)) self.assertEqual(site.latitude, self.latitude) self.assertEqual(site.latitude_rad, np.radians(self.latitude)) self.assertEqual(site.temperature, self.temperature) self.assertEqual(site.temperature_kelvin, self.temperature + 273.15) self.assertEqual(site.pressure, self.pressure) self.assertEqual(site.humidity, 2.1) self.assertEqual(site.lapseRate, self.lapseRate) self.assertEqual(site.height, self.height) site = Site(name='LSST', lapseRate=3.2) self.assertEqual(site.name, 'LSST') self.assertEqual(site.longitude, self.longitude) self.assertEqual(site.longitude_rad, np.radians(self.longitude)) self.assertEqual(site.latitude, self.latitude) self.assertEqual(site.latitude_rad, np.radians(self.latitude)) self.assertEqual(site.temperature, self.temperature) self.assertEqual(site.temperature_kelvin, self.temperature + 273.15) self.assertEqual(site.pressure, self.pressure) self.assertEqual(site.humidity, self.humidity) self.assertEqual(site.lapseRate, 3.2) self.assertEqual(site.height, self.height)