def testLmstLast(self): """ Test calculation of local mean and apparent sidereal time """ gmst, gast = utils.calcGmstGast(self.mjd) ll = [1.2, 2.2] for longitude in ll: hours = numpy.degrees(longitude)/15.0 if hours > 24.0: hours -= 24.0 controlLmst = gmst + hours controlLast = gast + hours controlLmst %= 24.0 controlLast %= 24.0 testLmst, testLast = utils.calcLmstLast(self.mjd, longitude) self.assertTrue(numpy.abs(testLmst - controlLmst).max() < self.tolerance) self.assertTrue(numpy.abs(testLast - controlLast).max() < self.tolerance) #test non-vectorized version for longitude in ll: for mm in self.mjd: gmst, gast = utils.calcGmstGast(mm) hours = numpy.degrees(longitude)/15.0 if hours > 24.0: hours -= 24.0 controlLmst = gmst + hours controlLast = gast + hours controlLmst %= 24.0 controlLast %= 24.0 testLmst, testLast = utils.calcLmstLast(mm, longitude) self.assertTrue(numpy.abs(testLmst - controlLmst) < self.tolerance) self.assertTrue(numpy.abs(testLast - controlLast) < self.tolerance)
def testLmstLast(self): """ Test calculation of local mean and apparent sidereal time """ gmst, gast = utils.calcGmstGast(self.mjd) ll = [1.2, 2.2] # test passing a float for longitude and a numpy array for mjd for longitude in ll: hours = np.degrees(longitude) / 15.0 if hours > 24.0: hours -= 24.0 controlLmst = gmst + hours controlLast = gast + hours controlLmst %= 24.0 controlLast %= 24.0 testLmst, testLast = utils.calcLmstLast(self.mjd, longitude) self.assertLess(np.abs(testLmst - controlLmst).max(), self.tolerance) self.assertLess(np.abs(testLast - controlLast).max(), self.tolerance) self.assertIsInstance(testLmst, np.ndarray) self.assertIsInstance(testLast, np.ndarray) # test passing two floats for longitude in ll: for mm in self.mjd: gmst, gast = utils.calcGmstGast(mm) hours = np.degrees(longitude) / 15.0 if hours > 24.0: hours -= 24.0 controlLmst = gmst + hours controlLast = gast + hours controlLmst %= 24.0 controlLast %= 24.0 testLmst, testLast = utils.calcLmstLast(mm, longitude) self.assertLess(np.abs(testLmst - controlLmst), self.tolerance) self.assertLess(np.abs(testLast - controlLast), self.tolerance) self.assertIsInstance(testLmst, np.float) self.assertIsInstance(testLast, np.float) # test passing two numpy arrays ll = self.rng.random_sample(len(self.mjd)) * 2.0 * np.pi testLmst, testLast = utils.calcLmstLast(self.mjd, ll) self.assertIsInstance(testLmst, np.ndarray) self.assertIsInstance(testLast, np.ndarray) for ix, (longitude, mm) in enumerate(zip(ll, self.mjd)): controlLmst, controlLast = utils.calcLmstLast(mm, longitude) self.assertAlmostEqual(controlLmst, testLmst[ix], 10) self.assertAlmostEqual(controlLast, testLast[ix], 10)
def testPAStacker(self): """ Test the parallacticAngleStacker""" data = np.zeros(100, dtype=list(zip( ['observationStartMJD', 'fieldDec', 'fieldRA', 'observationStartLST'], [float] * 4))) data['observationStartMJD'] = np.arange(100) * .2 + 50000 site = Site(name='LSST') data['observationStartLST'], last = calcLmstLast(data['observationStartMJD'], site.longitude_rad) data['observationStartLST'] = data['observationStartLST']*180./12. stacker = stackers.ParallacticAngleStacker(degrees=True) data = stacker.run(data) # Check values are in good range assert(data['PA'].max() <= 180) assert(data['PA'].min() >= -180) # Check compared to the util check_pa = [] ras = np.radians(data['fieldRA']) decs = np.radians(data['fieldDec']) for ra, dec, mjd in zip(ras, decs, data['observationStartMJD']): alt, az, pa = _altAzPaFromRaDec(ra, dec, ObservationMetaData(mjd=mjd, site=site)) check_pa.append(pa) check_pa = np.degrees(check_pa) np.testing.assert_array_almost_equal(data['PA'], check_pa, decimal=0)
def testAltAzToRaDec(self): """ Test conversion of Alt, Az t Ra, Dec """ numpy.random.seed(32) raIn = numpy.random.sample(len(self.mjd))*2.0*numpy.pi decIn = (numpy.random.sample(len(self.mjd))-0.5)*numpy.pi longitude = 1.467 latitude = -0.234 lst, last = utils.calcLmstLast(self.mjd, longitude) hourAngle = numpy.radians(last*15.0) - raIn controlAz, azd, azdd, \ controlAlt, eld, eldd, \ pa, pad, padd = palpy.altazVector(hourAngle, decIn, latitude) raOut, decOut, = utils.altAzToRaDec(controlAlt, controlAz, longitude, latitude, self.mjd) self.assertTrue(numpy.abs(numpy.cos(raOut) - numpy.cos(raIn)).max() < self.tolerance) self.assertTrue(numpy.abs(numpy.sin(raOut) - numpy.sin(raIn)).max() < self.tolerance) self.assertTrue(numpy.abs(numpy.cos(decOut) - numpy.cos(decIn)).max() < self.tolerance) self.assertTrue(numpy.abs(numpy.sin(decOut) - numpy.sin(decIn)).max() < self.tolerance) #test non-vectorized version for alt, az, r, d, m in zip(controlAlt, controlAz, raIn, decIn, self.mjd): raOut, decOut = utils.altAzToRaDec(alt, az, longitude, latitude, m) self.assertTrue(numpy.abs(numpy.cos(raOut) - numpy.cos(r)) < self.tolerance) self.assertTrue(numpy.abs(numpy.sin(raOut) - numpy.sin(r)) < self.tolerance) self.assertTrue(numpy.abs(numpy.cos(decOut) - numpy.cos(d)) < self.tolerance) self.assertTrue(numpy.abs(numpy.sin(decOut) - numpy.sin(d)) < self.tolerance)
def return_status(self): """ Return a dict full of the current info about the observatory and sky. XXX-- Need to document all these with units!!! """ result = {} result['mjd'] = self.mjd result['night'] = self.night result['lmst'], last = calcLmstLast(self.mjd, self.site.longitude_rad) result['skybrightness'] = self.sky.returnMags(self.mjd) result['slewtimes'] = self.slewtime_map() result['airmass'] = self.sky.returnAirmass(self.mjd) delta_t = (self.mjd - self.mjd_start) * 24. * 3600. result['clouds'] = self.cloud_model.get_cloud(delta_t) for filtername in ['u', 'g', 'r', 'i', 'z', 'y']: fwhm_500, fwhm_geometric, fwhm_effective = self.seeing_model.calculate_seeing( delta_t, filtername, result['airmass']) result['FWHMeff_%s' % filtername] = fwhm_effective # arcsec result['FWHM_geometric_%s' % filtername] = fwhm_geometric result['filter'] = self.filtername result['RA'] = self.ra result['dec'] = self.dec result['next_twilight_start'] = self.next_twilight_start(self.mjd) result['next_twilight_end'] = self.next_twilight_end(self.mjd) result['last_twilight_end'] = self.last_twilight_end(self.mjd) sunMoon_info = self.sky.returnSunMoon(self.mjd) # Pretty sure these are radians result['sunAlt'] = np.max(sunMoon_info['sunAlt']) result['moonAlt'] = np.max(sunMoon_info['moonAlt']) self.status = result return result
def stupidFast_altAz2RaDec(alt, az, lat, lon, mjd): """ Convert alt, az to RA, Dec without taking into account abberation, precesion, diffraction, ect. Parameters ---------- alt : numpy.array Altitude, same length as `ra` and `dec`. Radians. az : numpy.array Azimuth, same length as `ra` and `dec`. Must be same length as `alt`. Radians. lat : float Latitude of the observatory in radians. lon : float Longitude of the observatory in radians. mjd : float Modified Julian Date. Returns ------- ra : array_like RA, in radians. dec : array_like Dec, in radians. """ lmst, last = calcLmstLast(mjd, lon) lmst = lmst/12.*np.pi # convert to rad dec = np.arcsin(np.sin(lat)*np.sin(alt) + np.cos(lat)*np.cos(alt)*np.cos(az)) ha = np.arctan2(-np.sin(az)*np.cos(alt), -np.cos(az)*np.sin(lat)*np.cos(alt)+np.sin(alt)*np.cos(lat)) ra = (lmst-ha) raneg = np.where(ra < 0) ra[raneg] = ra[raneg] + 2.*np.pi return ra, dec
def controlRaDecToAltAz(raRad, decRad, longRad, latRad, mjd): """ Converts RA and Dec to altitude and azimuth @param [in] raRad is the RA in radians @param [in] decRad is the Dec in radians @param [in] longRad is the longitude of the observer in radians (positive east of the prime meridian) @param [in[ latRad is the latitude of the observer in radians (positive north of the equator) @param [in] mjd is the universal time expressed as an MJD @param [out] altitude in radians @param [out[ azimuth in radians see: http://www.stargazing.net/kepler/altaz.html#twig04 """ lst = utils.calcLmstLast(mjd, longRad) last = lst[1] haRad = numpy.radians(last*15.) - raRad sinDec = numpy.sin(decRad) cosLat = numpy.cos(latRad) sinLat = numpy.sin(latRad) sinAlt = sinDec*sinLat+numpy.cos(decRad)*cosLat*numpy.cos(haRad) altRad = numpy.arcsin(sinAlt) azRad = numpy.arccos((sinDec - sinAlt*sinLat)/(numpy.cos(altRad)*cosLat)) azRadOut = numpy.where(numpy.sin(haRad)>=0.0, 2.0*numpy.pi-azRad, azRad) return altRad, azRadOut
def testPAStacker(self): """ Test the parallacticAngleStacker""" data = np.zeros(100, dtype=list( zip([ 'observationStartMJD', 'fieldDec', 'fieldRA', 'observationStartLST' ], [float] * 4))) data['observationStartMJD'] = np.arange(100) * .2 + 50000 site = Site(name='LSST') data['observationStartLST'], last = calcLmstLast( data['observationStartMJD'], site.longitude_rad) data['observationStartLST'] = data['observationStartLST'] * 180. / 12. stacker = stackers.ParallacticAngleStacker(degrees=True) data = stacker.run(data) # Check values are in good range assert (data['PA'].max() <= 180) assert (data['PA'].min() >= -180) # Check compared to the util check_pa = [] ras = np.radians(data['fieldRA']) decs = np.radians(data['fieldDec']) for ra, dec, mjd in zip(ras, decs, data['observationStartMJD']): alt, az, pa = _altAzPaFromRaDec( ra, dec, ObservationMetaData(mjd=mjd, site=site)) check_pa.append(pa) check_pa = np.degrees(check_pa) np.testing.assert_array_almost_equal(data['PA'], check_pa, decimal=0)
def testAltAzFromRaDec(self): """ Test conversion from RA, Dec to Alt, Az """ nSamples = 100 ra = self.rng.random_sample(nSamples)*2.0*np.pi dec = (self.rng.random_sample(nSamples)-0.5)*np.pi lon_rad = 1.467 lat_rad = -0.234 controlAlt, controlAz = controlAltAzFromRaDec(ra, dec, lon_rad, lat_rad, self.mjd) obs = utils.ObservationMetaData(mjd=utils.ModifiedJulianDate(UTC=self.mjd), site=utils.Site(longitude=np.degrees(lon_rad), latitude=np.degrees(lat_rad), name='LSST')) # verify parallactic angle against an expression from # http://www.astro.washington.edu/groups/APO/Mirror.Motions/Feb.2000.Image.Jumps/report.html#Image%20motion%20directions # ra_obs, dec_obs = utils._observedFromICRS(ra, dec, obs_metadata=obs, epoch=2000.0, includeRefraction=True) lmst, last = utils.calcLmstLast(obs.mjd.UT1, lon_rad) hourAngle = np.radians(last * 15.0) - ra_obs controlSinPa = np.sin(hourAngle) * np.cos(lat_rad) / np.cos(controlAlt) testAlt, testAz, testPa = utils._altAzPaFromRaDec(ra, dec, obs) distance = utils.arcsecFromRadians(utils.haversine(controlAz, controlAlt, testAz, testAlt)) self.assertLess(distance.max(), 0.0001) self.assertLess(np.abs(np.sin(testPa) - controlSinPa).max(), self.tolerance) # test non-vectorized version for r, d in zip(ra, dec): controlAlt, controlAz = controlAltAzFromRaDec(r, d, lon_rad, lat_rad, self.mjd) testAlt, testAz, testPa = utils._altAzPaFromRaDec(r, d, obs) lmst, last = utils.calcLmstLast(obs.mjd.UT1, lon_rad) r_obs, dec_obs = utils._observedFromICRS(r, d, obs_metadata=obs, epoch=2000.0, includeRefraction=True) hourAngle = np.radians(last * 15.0) - r_obs controlSinPa = np.sin(hourAngle) * np.cos(lat_rad) / np.cos(controlAlt) distance = utils.arcsecFromRadians(utils.haversine(controlAz, controlAlt, testAz, testAlt)) self.assertLess(distance, 0.0001) self.assertLess(np.abs(np.sin(testPa) - controlSinPa), self.tolerance)
def observation_add_data(self, observation): """ Fill in the metadata for a completed observation """ current_time = Time(self.mjd, format='mjd') observation['clouds'] = self.cloud_data(current_time) observation['airmass'] = 1. / np.cos(np.pi / 2. - observation['alt']) # Seeing fwhm_500 = self.seeing_data(current_time) seeing_dict = self.seeing_model(fwhm_500, observation['airmass']) observation['FWHMeff'] = seeing_dict['fwhmEff'][self.seeing_indx_dict[ observation['filter'][0]]] observation['FWHM_geometric'] = seeing_dict['fwhmGeom'][ self.seeing_indx_dict[observation['filter'][0]]] observation['FWHM_500'] = fwhm_500 observation['night'] = self.night observation['mjd'] = self.mjd hpid = _raDec2Hpid(self.sky_model.nside, observation['RA'], observation['dec']) observation['skybrightness'] = self.sky_model.returnMags( self.mjd, indx=[hpid], extrapolate=True)[observation['filter'][0]] observation['fivesigmadepth'] = m5_flat_sed( observation['filter'][0], observation['skybrightness'], observation['FWHMeff'], observation['exptime'] / observation['nexp'], observation['airmass'], nexp=observation['nexp']) lmst, last = calcLmstLast(self.mjd, self.site.longitude_rad) observation['lmst'] = lmst sun_moon_info = self.almanac.get_sun_moon_positions(self.mjd) observation['sunAlt'] = sun_moon_info['sun_alt'] observation['sunAz'] = sun_moon_info['sun_az'] observation['sunRA'] = sun_moon_info['sun_RA'] observation['sunDec'] = sun_moon_info['sun_dec'] observation['moonAlt'] = sun_moon_info['moon_alt'] observation['moonAz'] = sun_moon_info['moon_az'] observation['moonRA'] = sun_moon_info['moon_RA'] observation['moonDec'] = sun_moon_info['moon_dec'] observation['moonDist'] = _angularSeparation(observation['RA'], observation['dec'], observation['moonRA'], observation['moonDec']) observation['solarElong'] = _angularSeparation(observation['RA'], observation['dec'], observation['sunRA'], observation['sunDec']) observation['moonPhase'] = sun_moon_info['moon_phase'] observation['ID'] = self.obsID_counter self.obsID_counter += 1 return observation
def _raDecFromAltAz(altRad, azRad, obs, includeRefraction=True): """ Convert altitude and azimuth to RA and Dec @param [in] altRad is the altitude in radians. Can be a numpy array or a single value. @param [in] azRad is the azimuth in radians. Cant be a numpy array or a single value. @param [in] obs is an ObservationMetaData characterizing the site of the telescope and the MJD of the observation @param [in] includeRefraction is a boolean that turns refraction on and off (default True) @param [out] RA in radians (in the International Celestial Reference System) @param [out] Dec in radians (in the International Celestial Reference System) Note: This method is only accurate to within 0.01 arcsec near azimuth = 0 or pi """ are_arrays = _validate_inputs([altRad, azRad], ['altRad', 'azRad'], "raDecFromAltAz") lst = calcLmstLast(obs.mjd.UT1, obs.site.longitude_rad) last = lst[1] sinAlt = np.sin(altRad) cosLat = np.cos(obs.site.latitude_rad) sinLat = np.sin(obs.site.latitude_rad) decObs = np.arcsin(sinLat * sinAlt + cosLat * np.cos(altRad) * np.cos(azRad)) costheta = (sinAlt - np.sin(decObs) * sinLat) / (np.cos(decObs) * cosLat) if are_arrays: haRad0 = np.arccos(costheta) # Make sure there were no NaNs nanSpots = np.where(np.isnan(haRad0))[0] if np.size(nanSpots) > 0: haRad0[nanSpots] = 0.5 * np.pi * \ (1.0 - np.sign(costheta[nanSpots])) else: haRad0 = np.arccos(costheta) if np.isnan(haRad0): if np.sign(costheta) > 0.0: haRad0 = 0.0 else: haRad0 = np.pi haRad = np.where(np.sin(azRad) >= 0.0, -1.0 * haRad0, haRad0) raObs = np.radians(last * 15.) - haRad raRad, decRad = _icrsFromObserved(raObs, decObs, obs_metadata=obs, epoch=2000.0, includeRefraction=includeRefraction) return raRad, decRad
def _raDecFromAltAz(altRad, azRad, obs, includeRefraction=True): """ Convert altitude and azimuth to RA and Dec @param [in] altRad is the altitude in radians. Can be a numpy array or a single value. @param [in] azRad is the azimuth in radians. Cant be a numpy array or a single value. @param [in] obs is an ObservationMetaData characterizing the site of the telescope and the MJD of the observation @param [in] includeRefraction is a boolean that turns refraction on and off (default True) @param [out] RA in radians (in the International Celestial Reference System) @param [out] Dec in radians (in the International Celestial Reference System) Note: This method is only accurate to within 0.01 arcsec near azimuth = 0 or pi """ with np.errstate(invalid='ignore', divide='ignore'): are_arrays = _validate_inputs( [altRad, azRad], ['altRad', 'azRad'], "raDecFromAltAz") lst = calcLmstLast(obs.mjd.UT1, obs.site.longitude_rad) last = lst[1] sinAlt = np.sin(altRad) cosLat = np.cos(obs.site.latitude_rad) sinLat = np.sin(obs.site.latitude_rad) decObs = np.arcsin(sinLat * sinAlt + cosLat * np.cos(altRad) * np.cos(azRad)) costheta = (sinAlt - np.sin(decObs) * sinLat) / (np.cos(decObs) * cosLat) if are_arrays: haRad0 = np.arccos(costheta) # Make sure there were no NaNs nanSpots = np.where(np.isnan(haRad0))[0] if np.size(nanSpots) > 0: haRad0[nanSpots] = 0.5 * np.pi * \ (1.0 - np.sign(costheta[nanSpots])) else: haRad0 = np.arccos(costheta) if np.isnan(haRad0): if np.sign(costheta) > 0.0: haRad0 = 0.0 else: haRad0 = np.pi haRad = np.where(np.sin(azRad) >= 0.0, -1.0 * haRad0, haRad0) raObs = np.radians(last * 15.) - haRad raRad, decRad = _icrsFromObserved(raObs, decObs, obs_metadata=obs, epoch=2000.0, includeRefraction=includeRefraction) return raRad, decRad
def testExceptions(self): """ Test to make sure that methods complain when incorrect data types are passed. """ mjdFloat = 52000.0 mjd2 = numpy.array([52000.0, 53000.0]) mjd3 = numpy.array([53000.0, 53000.0, 54000.0]) longFloat = 1.2 longList = numpy.array([1.2, 1.4]) latFloat = 0.5 latList = numpy.array([0.5, 0.6]) raFloat = 1.1 raList = numpy.array([0.2, 0.3]) decFloat = 1.1 decList = numpy.array([0.2, 0.3]) self.assertRaises(RuntimeError, utils.calcLmstLast, mjdFloat, longList) self.assertRaises(RuntimeError, utils.calcLmstLast, mjd3, longList) ans = utils.calcLmstLast(mjdFloat, longFloat) ans = utils.calcLmstLast(mjd2, longList) self.assertRaises(RuntimeError, utils.raDecToAltAzPa, raList, decList, longList, latFloat, mjd2) self.assertRaises(RuntimeError, utils.raDecToAltAzPa, raList, decList, longFloat, latList, mjd2) self.assertRaises(RuntimeError, utils.raDecToAltAzPa, raList, decFloat, longFloat, latFloat, mjdFloat) self.assertRaises(RuntimeError, utils.raDecToAltAzPa, raFloat, decList, longFloat, latFloat, mjdFloat) self.assertRaises(RuntimeError, utils.raDecToAltAzPa, raFloat, decFloat, longFloat, latFloat, mjd2) self.assertRaises(RuntimeError, utils.raDecToAltAzPa, raList, decList, longFloat, latFloat, mjd3) ans = utils.raDecToAltAzPa(raFloat, decFloat, longFloat, latFloat, mjdFloat) ans = utils.raDecToAltAzPa(raList, decList, longFloat, latFloat, mjdFloat) ans = utils.raDecToAltAzPa(raList, decList, longFloat, latFloat, mjd2) self.assertRaises(RuntimeError, utils.altAzToRaDec, raList, decList, longList, latFloat, mjd2) self.assertRaises(RuntimeError, utils.altAzToRaDec, raList, decList, longFloat, latList, mjd2) self.assertRaises(RuntimeError, utils.altAzToRaDec, raList, decFloat, longFloat, latFloat, mjdFloat) self.assertRaises(RuntimeError, utils.altAzToRaDec, raFloat, decList, longFloat, latFloat, mjdFloat) self.assertRaises(RuntimeError, utils.altAzToRaDec, raFloat, decFloat, longFloat, latFloat, mjd2) self.assertRaises(RuntimeError, utils.altAzToRaDec, raList, decList, longFloat, latFloat, mjd3) ans = utils.altAzToRaDec(raFloat, decFloat, longFloat, latFloat, mjdFloat) ans = utils.altAzToRaDec(raList, decList, longFloat, latFloat, mjdFloat) ans = utils.altAzToRaDec(raList, decList, longFloat, latFloat, mjd2)
def _approx_RaDec2AltAz(ra, dec, lat, lon, mjd, lmst=None, return_pa=False): """ Convert Ra,Dec to Altitude and Azimuth. Coordinate transformation is killing performance. Just use simple equations to speed it up and ignore aberration, precession, nutation, nutrition, etc. Parameters ---------- ra : array_like RA, in radians. dec : array_like Dec, in radians. Must be same length as `ra`. lat : float Latitude of the observatory in radians. lon : float Longitude of the observatory in radians. mjd : float Modified Julian Date. lmst : float (None) The local mean sidereal time (computed if not given). (hours) Returns ------- alt : numpy.array Altitude, same length as `ra` and `dec`. Radians. az : numpy.array Azimuth, same length as `ra` and `dec`. Radians. """ if lmst is None: lmst, last = calcLmstLast(mjd, lon) lmst = lmst / 12. * np.pi # convert to rad ha = lmst - ra sindec = np.sin(dec) sinlat = np.sin(lat) coslat = np.cos(lat) sinalt = sindec * sinlat + np.cos(dec) * coslat * np.cos(ha) sinalt = np.clip(sinalt, -1, 1) alt = np.arcsin(sinalt) cosaz = (sindec - np.sin(alt) * sinlat) / (np.cos(alt) * coslat) cosaz = np.clip(cosaz, -1, 1) az = np.arccos(cosaz) if np.size(ha) < 2: if np.sin(ha) > 0: az = 2. * np.pi - az else: signflip = np.where(np.sin(ha) > 0) az[signflip] = 2. * np.pi - az[signflip] if return_pa: pa = _approx_altaz2pa(alt, az, lat) return alt, az, pa return alt, az
def testRaDecToAltAz(self): """ Test conversion from RA, Dec to Alt, Az """ numpy.random.seed(32) ra = numpy.random.sample(len(self.mjd))*2.0*numpy.pi dec = (numpy.random.sample(len(self.mjd))-0.5)*numpy.pi longitude = 1.467 latitude = -0.234 controlAlt, controlAz = controlRaDecToAltAz(ra, dec, \ longitude, latitude, \ self. mjd) #verify parallactic angle against an expression from #http://www.astro.washington.edu/groups/APO/Mirror.Motions/Feb.2000.Image.Jumps/report.html#Image%20motion%20directions # lmst, last = utils.calcLmstLast(self.mjd, longitude) hourAngle = numpy.radians(last*15.0) - ra controlSinPa = numpy.sin(hourAngle)*numpy.cos(latitude)/numpy.cos(controlAlt) testAlt, testAz, testPa = utils.raDecToAltAzPa(ra, dec, \ longitude, latitude, \ self.mjd) self.assertTrue(numpy.abs(testAz - controlAz).max() < self.tolerance) self.assertTrue(numpy.abs(testAlt - controlAlt).max() < self.tolerance) self.assertTrue(numpy.abs(numpy.sin(testPa) - controlSinPa).max() < self.tolerance) #test non-vectorized version for r,d,m in zip(ra, dec, self.mjd): controlAlt, controlAz = controlRaDecToAltAz(r, d, longitude, latitude, m) testAlt, testAz, testPa = utils.raDecToAltAzPa(r, d, longitude, latitude, m) lmst, last = utils.calcLmstLast(m, longitude) hourAngle = numpy.radians(last*15.0) - r controlSinPa = numpy.sin(hourAngle)*numpy.cos(latitude)/numpy.cos(controlAlt) self.assertTrue(numpy.abs(testAz - controlAz) < self.tolerance) self.assertTrue(numpy.abs(testAlt - controlAlt) < self.tolerance) self.assertTrue(numpy.abs(numpy.sin(testPa) - controlSinPa) < self.tolerance)
def _altAzPaFromRaDec(raRad, decRad, obs, includeRefraction=True): """ Convert RA, Dec, longitude, latitude and MJD into altitude, azimuth and parallactic angle using PALPY @param [in] raRad is RA in radians. Can be a numpy array or a single value. Assumed to be in the International Celestial Reference System. @param [in] decRad is Dec in radians. Can be a numpy array or a single value. Assumed to be in the International Celestial Reference System. @param [in] obs is an ObservationMetaData characterizing the site of the telescope and the MJD of the observation @param [in] includeRefraction is a boolean that turns refraction on and off (default True) @param [out] altitude in radians @param [out] azimuth in radians @param [out] parallactic angle in radians WARNING: This method does not account for apparent motion due to parallax. This method is only useful for mapping positions on a theoretical focal plan to positions on the celestial sphere. """ are_arrays = _validate_inputs([raRad, decRad], ['ra', 'dec'], "altAzPaFromRaDec") raObs, decObs = \ _observedFromICRS(raRad, decRad, obs_metadata=obs, epoch=2000.0, includeRefraction=includeRefraction) lst = calcLmstLast(obs.mjd.UT1, obs.site.longitude_rad) last = lst[1] haRad = np.radians(last * 15.0) - raObs if are_arrays: az, azd, azdd, \ alt, altd, altdd, \ pa, pad, padd = palpy.altazVector( haRad, decObs, obs.site.latitude_rad) else: az, azd, azdd, \ alt, altd, altdd, \ pa, pad, padd = palpy.altaz(haRad, decObs, obs.site.latitude_rad) return alt, az, pa
def _altAzPaFromRaDec(raRad, decRad, obs, includeRefraction=True): """ Convert RA, Dec, longitude, latitude and MJD into altitude, azimuth and parallactic angle using PALPY @param [in] raRad is RA in radians. Can be a numpy array or a single value. Assumed to be in the International Celestial Reference System. @param [in] decRad is Dec in radians. Can be a numpy array or a single value. Assumed to be in the International Celestial Reference System. @param [in] obs is an ObservationMetaData characterizing the site of the telescope and the MJD of the observation @param [in] includeRefraction is a boolean that turns refraction on and off (default True) @param [out] altitude in radians @param [out] azimuth in radians @param [out] parallactic angle in radians WARNING: This method does not account for apparent motion due to parallax. This method is only useful for mapping positions on a theoretical focal plan to positions on the celestial sphere. """ are_arrays = _validate_inputs([raRad, decRad], ['ra', 'dec'], "altAzPaFromRaDec") raObs, decObs = \ _observedFromICRS(raRad, decRad, obs_metadata=obs, epoch=2000.0, includeRefraction=includeRefraction) lst = calcLmstLast(obs.mjd.UT1, obs.site.longitude_rad) last = lst[1] haRad = np.radians(last * 15.0) - raObs if are_arrays: az, azd, azdd, \ alt, altd, altdd, \ pa, pad, padd = palpy.altazVector( haRad, decObs, obs.site.latitude_rad) else: az, azd, azdd, \ alt, altd, altdd, \ pa, pad, padd = palpy.altaz(haRad, decObs, obs.site.latitude_rad) return alt, az, pa
def controlAltAzFromRaDec(raRad_in, decRad_in, longRad, latRad, mjd): """ Converts RA and Dec to altitude and azimuth @param [in] raRad is the RA in radians (observed geocentric) @param [in] decRad is the Dec in radians (observed geocentric) @param [in] longRad is the longitude of the observer in radians (positive east of the prime meridian) @param [in[ latRad is the latitude of the observer in radians (positive north of the equator) @param [in] mjd is the universal time expressed as an MJD @param [out] altitude in radians @param [out[ azimuth in radians see: http://www.stargazing.net/kepler/altaz.html#twig04 """ obs = utils.ObservationMetaData(mjd=utils.ModifiedJulianDate(UTC=mjd), site=utils.Site(longitude=np.degrees(longRad), latitude=np.degrees(latRad), name='LSST')) if hasattr(raRad_in, '__len__'): raRad, decRad = utils._observedFromICRS(raRad_in, decRad_in, obs_metadata=obs, epoch=2000.0, includeRefraction=True) else: raRad, decRad = utils._observedFromICRS(raRad_in, decRad_in, obs_metadata=obs, epoch=2000.0, includeRefraction=True) lst = utils.calcLmstLast(obs.mjd.UT1, longRad) last = lst[1] haRad = np.radians(last * 15.) - raRad sinDec = np.sin(decRad) cosLat = np.cos(latRad) sinLat = np.sin(latRad) sinAlt = sinDec*sinLat + np.cos(decRad)*cosLat*np.cos(haRad) altRad = np.arcsin(sinAlt) azRad = np.arccos((sinDec - sinAlt*sinLat) / (np.cos(altRad)*cosLat)) azRadOut = np.where(np.sin(haRad) >= 0.0, 2.0 * np.pi - azRad, azRad) if isinstance(altRad, float): return altRad, float(azRadOut) return altRad, azRadOut
def raDec2AltAz(ra, dec, lat, lon, mjd, altonly=False): """Convert RA/Dec (and telescope site lat/lon) to alt/az. This uses simple equations and ignores aberation, precession, nutation, etc. Parameters ---------- ra : array_like RA, in radians. dec : array_like Dec, in radians. Must be same length as `ra`. lat : float Latitude of the observatory in radians. lon : float Longitude of the observatory in radians. mjd : float Modified Julian Date. altonly : bool, opt Calculate altitude only. Returns ------- alt : numpy.array Altitude, same length as `ra` and `dec`. Radians. az : numpy.array Azimuth, same length as `ra` and `dec`. Radians. """ lmst, last = calcLmstLast(mjd, lon) lmst = lmst / 12. * np.pi # convert to rad ha = lmst - ra sindec = np.sin(dec) sinlat = np.sin(lat) coslat = np.cos(lat) sinalt = sindec * sinlat + np.cos(dec) * coslat * np.cos(ha) # make sure sinalt is in the expected range. sinalt = np.where(sinalt < -1, -1, sinalt) sinalt = np.where(sinalt > 1, 1, sinalt) alt = np.arcsin(sinalt) if altonly: az = None else: cosaz = (sindec-np.sin(alt)*sinlat)/(np.cos(alt)*coslat) cosaz = np.where(cosaz < -1, -1, cosaz) cosaz = np.where(cosaz > 1, 1, cosaz) az = np.arccos(cosaz) signflip = np.where(np.sin(ha) > 0) az[signflip] = 2.*np.pi-az[signflip] return alt, az
def raDec2AltAz(ra, dec, lat, lon, mjd, altonly=False): """Convert RA/Dec (and telescope site lat/lon) to alt/az. This uses simple equations and ignores aberation, precession, nutation, etc. Parameters ---------- ra : array_like RA, in radians. dec : array_like Dec, in radians. Must be same length as `ra`. lat : float Latitude of the observatory in radians. lon : float Longitude of the observatory in radians. mjd : float Modified Julian Date. altonly : bool, opt Calculate altitude only. Returns ------- alt : numpy.array Altitude, same length as `ra` and `dec`. Radians. az : numpy.array Azimuth, same length as `ra` and `dec`. Radians. """ lmst, last = calcLmstLast(mjd, lon) lmst = lmst / 12. * np.pi # convert to rad ha = lmst - ra sindec = np.sin(dec) sinlat = np.sin(lat) coslat = np.cos(lat) sinalt = sindec * sinlat + np.cos(dec) * coslat * np.cos(ha) # make sure sinalt is in the expected range. sinalt = np.where(sinalt < -1, -1, sinalt) sinalt = np.where(sinalt > 1, 1, sinalt) alt = np.arcsin(sinalt) if altonly: az = None else: cosaz = (sindec - np.sin(alt) * sinlat) / (np.cos(alt) * coslat) cosaz = np.where(cosaz < -1, -1, cosaz) cosaz = np.where(cosaz > 1, 1, cosaz) az = np.arccos(cosaz) signflip = np.where(np.sin(ha) > 0) az[signflip] = 2. * np.pi - az[signflip] return alt, az
def stupidFast_RaDec2AltAz(ra, dec, mjd, lmst=None): """ Convert Ra,Dec to Altitude and Azimuth. Coordinate transformation is killing performance. Just use simple equations to speed it up and ignore abberation, precesion, nutation, nutrition, etc. Parameters ---------- ra : array_like RA, in radians. dec : array_like Dec, in radians. Must be same length as `ra`. lat : float Latitude of the observatory in radians. lon : float Longitude of the observatory in radians. mjd : float Modified Julian Date. Returns ------- alt : numpy.array Altitude, same length as `ra` and `dec`. Radians. az : numpy.array Azimuth, same length as `ra` and `dec`. Radians. """ lat = -0.517781017 lon = -1.2320792 if lmst is None: lmst, last = calcLmstLast(mjd, lon) lmst = lmst / 12. * np.pi # convert to rad ha = lmst - ra sindec = np.sin(dec) sinlat = np.sin(lat) coslat = np.cos(lat) sinalt = sindec * sinlat + np.cos(dec) * coslat * np.cos(ha) sinalt = inrange(sinalt) alt = np.arcsin(sinalt) cosaz = (sindec - np.sin(alt) * sinlat) / (np.cos(alt) * coslat) cosaz = inrange(cosaz) az = np.arccos(cosaz) signflip = np.where(np.sin(ha) > 0) az[signflip] = 2. * np.pi - az[signflip] return alt, az
def _approx_RaDec2AltAz(ra, dec, lat, lon, mjd, lmst=None): """ Convert Ra,Dec to Altitude and Azimuth. Coordinate transformation is killing performance. Just use simple equations to speed it up and ignore aberration, precession, nutation, nutrition, etc. Parameters ---------- ra : array_like RA, in radians. dec : array_like Dec, in radians. Must be same length as `ra`. lat : float Latitude of the observatory in radians. lon : float Longitude of the observatory in radians. mjd : float Modified Julian Date. lmst : float (None) The local mean sidereal time (computed if not given). (hours) Returns ------- alt : numpy.array Altitude, same length as `ra` and `dec`. Radians. az : numpy.array Azimuth, same length as `ra` and `dec`. Radians. """ if lmst is None: lmst, last = calcLmstLast(mjd, lon) lmst = lmst/12.*np.pi # convert to rad ha = lmst-ra sindec = np.sin(dec) sinlat = np.sin(lat) coslat = np.cos(lat) sinalt = sindec*sinlat+np.cos(dec)*coslat*np.cos(ha) sinalt = np.clip(sinalt, -1, 1) alt = np.arcsin(sinalt) cosaz = (sindec-np.sin(alt)*sinlat)/(np.cos(alt)*coslat) cosaz = np.clip(cosaz, -1, 1) az = np.arccos(cosaz) signflip = np.where(np.sin(ha) > 0) az[signflip] = 2.*np.pi-az[signflip] return alt, az
def _approx_altAz2RaDec(alt, az, lat, lon, mjd, lmst=None): """ Convert alt, az to RA, Dec without taking into account aberration, precession, diffraction, etc. Parameters ---------- alt : numpy.array Altitude, same length as `ra` and `dec`. Radians. az : numpy.array Azimuth, same length as `ra` and `dec`. Must be same length as `alt`. Radians. lat : float Latitude of the observatory in radians. lon : float Longitude of the observatory in radians. mjd : float Modified Julian Date. lmst : float (None) The local mean sidereal time (computed if not given). (hours) Returns ------- ra : array_like RA, in radians. dec : array_like Dec, in radians. """ if lmst is None: lmst, last = calcLmstLast(mjd, lon) lmst = lmst / 12. * np.pi # convert to rad sindec = np.sin(lat) * np.sin(alt) + np.cos(lat) * np.cos(alt) * np.cos(az) sindec = np.clip(sindec, -1, 1) dec = np.arcsin(sindec) ha = np.arctan2( -np.sin(az) * np.cos(alt), -np.cos(az) * np.sin(lat) * np.cos(alt) + np.sin(alt) * np.cos(lat)) ra = (lmst - ha) raneg = np.where(ra < 0) ra[raneg] = ra[raneg] + 2. * np.pi raover = np.where(ra > 2. * np.pi) ra[raover] -= 2. * np.pi return ra, dec
def hour_angle(ra, lsst_lon, mjd, lmst=None): """ evaluates the hour angle of fields. Parameters ---------- ra : numpy.array RA, in radians. lsst_lon : float Longitude of the LSST site Returns ------- ha : numpy.array Hour angle ranging from -12 to 12. Hours. """ if lmst is None: lmst, last = calcLmstLast(mjd, lsst_lon) ha = lmst-ra * 12./np.pi ha = np.where(ha < -12, ha +24, ha) ha = np.where(ha > 12, ha - 24, ha) return ha
def _approx_altAz2RaDec(alt, az, lat, lon, mjd, lmst=None): """ Convert alt, az to RA, Dec without taking into account aberration, precession, diffraction, etc. Parameters ---------- alt : numpy.array Altitude, same length as `ra` and `dec`. Radians. az : numpy.array Azimuth, same length as `ra` and `dec`. Must be same length as `alt`. Radians. lat : float Latitude of the observatory in radians. lon : float Longitude of the observatory in radians. mjd : float Modified Julian Date. lmst : float (None) The local mean sidereal time (computed if not given). (hours) Returns ------- ra : array_like RA, in radians. dec : array_like Dec, in radians. """ if lmst is None: lmst, last = calcLmstLast(mjd, lon) lmst = lmst/12.*np.pi # convert to rad sindec = np.sin(lat)*np.sin(alt) + np.cos(lat)*np.cos(alt)*np.cos(az) sindec = np.clip(sindec, -1, 1) dec = np.arcsin(sindec) ha = np.arctan2(-np.sin(az)*np.cos(alt), -np.cos(az)*np.sin(lat)*np.cos(alt)+np.sin(alt)*np.cos(lat)) ra = (lmst-ha) raneg = np.where(ra < 0) ra[raneg] = ra[raneg] + 2.*np.pi raover = np.where(ra > 2.*np.pi) ra[raover] -= 2.*np.pi return ra, dec
def stupidFast_RaDec2AltAz(ra, dec, lat, lon, mjd): """ Convert Ra,Dec to Altitude and Azimuth. Coordinate transformation is killing performance. Just use simple equations to speed it up and ignore abberation, precesion, nutation, nutrition, etc. Parameters ---------- ra : array_like RA, in radians. dec : array_like Dec, in radians. Must be same length as `ra`. lat : float Latitude of the observatory in radians. lon : float Longitude of the observatory in radians. mjd : float Modified Julian Date. Returns ------- alt : numpy.array Altitude, same length as `ra` and `dec`. Radians. az : numpy.array Azimuth, same length as `ra` and `dec`. Radians. """ lmst, last = calcLmstLast(mjd, lon) lmst = lmst/12.*np.pi # convert to rad ha = lmst-ra sindec = np.sin(dec) sinlat = np.sin(lat) coslat = np.cos(lat) alt = np.arcsin(sindec*sinlat+np.cos(dec)*coslat*np.cos(ha)) az = np.arccos((sindec-np.sin(alt)*sinlat)/(np.cos(alt)*coslat)) signflip = np.where(np.sin(ha) > 0) az[signflip] = 2.*np.pi-az[signflip] return alt, az
def stupidFast_altAz2RaDec(alt, az, lat, lon, mjd): """ Convert alt, az to RA, Dec without taking into account abberation, precesion, diffraction, ect. Parameters ---------- alt : numpy.array Altitude, same length as `ra` and `dec`. Radians. az : numpy.array Azimuth, same length as `ra` and `dec`. Must be same length as `alt`. Radians. lat : float Latitude of the observatory in radians. lon : float Longitude of the observatory in radians. mjd : float Modified Julian Date. Returns ------- ra : array_like RA, in radians. dec : array_like Dec, in radians. """ lmst, last = calcLmstLast(mjd, lon) lmst = lmst / 12. * np.pi # convert to rad sindec = np.sin(lat) * np.sin(alt) + np.cos(lat) * np.cos(alt) * np.cos(az) sindec = inrange(sindec) dec = np.arcsin(sindec) ha = np.arctan2( -np.sin(az) * np.cos(alt), -np.cos(az) * np.sin(lat) * np.cos(alt) + np.sin(alt) * np.cos(lat)) ra = (lmst - ha) raneg = np.where(ra < 0) ra[raneg] = ra[raneg] + 2. * np.pi return ra, dec
telescope = Site('LSST') nside = 32 lat, ra = hp.pix2ang(nside, np.arange(hp.nside2npix(nside))) dec = np.pi / 2 - lat kwargs = dict(twilight=False, zodiacal=False, moon=True, scatteredStar=False, mergedSpec=False) sm = sb.SkyModel(observatory='LSST', mags=True) # , **kwargs) mjd = 49353.177645 sm.setRaDecMjd(ra, dec, mjd) mag = sm.returnMags() lmst, last = calcLmstLast(mjd, telescope.longitude_rad) moonRA, moonDec = _raDecFromAltAz(sm.moonAlt, sm.moonAz, ObservationMetaData(mjd=mjd, site=telescope)) alt, az, pa = _altAzPaFromRaDec(ra, dec, ObservationMetaData(mjd=mjd, site=telescope)) angDist2Moon = np.degrees(haversine(az, alt, sm.moonAz, sm.moonAlt)) ang2 = np.degrees(haversine(ra, dec, moonRA, moonDec)) alt = np.degrees(alt) mags = -0.5 * (np.nanmin(mag['u']) - mag['u']) #extent = (0,130, 0,90) extent = (20, 120, 20, 90)
def testExceptions(self): """ Test to make sure that methods complain when incorrect data types are passed. """ mjdFloat = 52000.0 mjd2 = np.array([52000.0, 53000.0]) mjd3 = np.array([53000.0, 53000.0, 54000.0]) longFloat = 1.2 longArr = np.array([1.2, 1.4]) self.assertRaises(RuntimeError, utils.calcLmstLast, mjdFloat, longArr) self.assertRaises(RuntimeError, utils.calcLmstLast, mjd3, longArr) self.assertRaises(RuntimeError, utils.calcLmstLast, list(mjd2), longArr) self.assertRaises(RuntimeError, utils.calcLmstLast, mjd2, list(longArr)) self.assertRaises(RuntimeError, utils.calcLmstLast, mjdFloat, longArr) utils.calcLmstLast(mjd2, longFloat) utils.calcLmstLast(mjdFloat, longFloat) utils.calcLmstLast(int(mjdFloat), longFloat) utils.calcLmstLast(mjdFloat, int(longFloat)) utils.calcLmstLast(int(mjdFloat), int(longFloat)) utils.calcLmstLast(mjd2, longArr)
def _altAzPaFromRaDec(raRad, decRad, obs): """ Convert RA, Dec, longitude, latitude and MJD into altitude, azimuth and parallactic angle using PALPY @param [in] raRad is RA in radians. Can be a numpy array or a single value. Assumed to be in the International Celestial Reference System. @param [in] decRad is Dec in radians. Can be a numpy array or a single value. Assumed to be in the International Celestial Reference System. @param [in] obs is an ObservationMetaData characterizing the site of the telescope and the MJD of the observation @param [out] altitude in radians @param [out] azimuth in radians @param [out] parallactic angle in radians """ raIsArray = False decIsArray = False if isinstance(raRad, np.ndarray): raIsArray = True if isinstance(decRad, np.ndarray): decIsArray = True if raIsArray and not decIsArray: raise RuntimeError('passed numpy array of RA to altAzPaFromRaDec; but only one Dec') if decIsArray and not raIsArray: raise RuntimeError('passed numpy array of Dec to altAzPaFromRaDec; but only one RA') if raIsArray and decIsArray and len(raRad) != len(decRad): raise RuntimeError('in altAzPaFromRaDec length of RA numpy array does not match length of Dec numpy array') if not hasattr(raRad, '__len__'): raObs_temp, decObs_temp = _observedFromICRS(np.array([raRad]), np.array([decRad]), obs_metadata=obs, includeRefraction=True, epoch=2000.0) raObs = raObs_temp[0] decObs = decObs_temp[0] else: raObs, decObs = _observedFromICRS(raRad, decRad, obs_metadata=obs, epoch=2000.0, includeRefraction=True) lst = calcLmstLast(obs.mjd.UT1, obs.site.longitude_rad) last = lst[1] haRad = np.radians(last*15.0) - raObs if isinstance(haRad, np.ndarray): az, azd, azdd, \ alt, altd, altdd, \ pa, pad, padd = palpy.altazVector(haRad, decObs, obs.site.latitude_rad) else: az, azd, azdd, \ alt, altd, altdd, \ pa, pad, padd = palpy.altaz(haRad, decObs, obs.site.latitude_rad) return alt, az, pa
def _raDecFromAltAz(altRad, azRad, obs): """ Convert altitude and azimuth to RA and Dec @param [in] altRad is the altitude in radians. Can be a numpy array or a single value. @param [in] azRad is the azimuth in radians. Cant be a numpy array or a single value. @param [in] obs is an ObservationMetaData characterizing the site of the telescope and the MJD of the observation @param [out] RA in radians (in the International Celestial Reference System) @param [out] Dec in radians (in the International Celestial Reference System) Note: This method is only accurate to within 0.01 arcsec near azimuth = 0 or pi """ altIsArray = False azIsArray = False if isinstance(altRad, np.ndarray): altIsArray = True if isinstance(azRad, np.ndarray): azIsArray = True if altIsArray and not azIsArray: raise RuntimeError('passed a numpy array of alt to raDecFromAltAz, but only one az') if azIsArray and not altIsArray: raise RuntimeError('passed a numpy array of az to raDecFromAltAz, but only one alt') if azIsArray and altIsArray and len(altRad)!=len(azRad): raise RuntimeError('in raDecFromAltAz, length of alt numpy array does not match length of az numpy array') lst = calcLmstLast(obs.mjd.UT1, obs.site.longitude_rad) last = lst[1] sinAlt = np.sin(altRad) cosLat = np.cos(obs.site.latitude_rad) sinLat = np.sin(obs.site.latitude_rad) decObs = np.arcsin(sinLat*sinAlt+ cosLat*np.cos(altRad)*np.cos(azRad)) costheta = (sinAlt - np.sin(decObs)*sinLat)/(np.cos(decObs)*cosLat) if altIsArray: haRad0 = np.arccos(costheta) # Make sure there were no NaNs nanSpots = np.where(np.isnan(haRad0))[0] if np.size(nanSpots) > 0: haRad0[nanSpots] = 0.5*np.pi*(1.0-np.sign(costheta[nanSpots])) else: haRad0 = np.arccos(costheta) if np.isnan(haRad0): if np.sign(costheta)>0.0: haRad0 = 0.0 else: haRad0 = np.pi haRad = np.where(np.sin(azRad)>=0.0, -1.0*haRad0, haRad0) raObs = np.radians(last*15.) - haRad if not hasattr(raObs, '__len__'): raRad, decRad = _icrsFromObserved(np.array([raObs]), np.array([decObs]), obs_metadata=obs, epoch=2000.0, includeRefraction=True) return raRad[0], decRad[0] raRad, decRad = _icrsFromObserved(raObs, decObs, obs_metadata=obs, epoch=2000.0, includeRefraction=True) return raRad, decRad
# umjd = medDB(full_select='select DISTINCT(mjd) from medskybrightness;', dtypes=float) skyMaps = np.load('sky_maps.npz') umjd = skyMaps['umjd'].copy() nstart = 5506 + 67 # partly cloudy frame #nstart = 6447 # very cloudy frame # nstart = 982 # clear, with moon previous = single_frame(umjd[nstart - 1]) nside = hp.npix2nside(previous.size) mjd = umjd[nstart] site = Site('LSST') dec, ra = hp.pix2ang(nside, np.arange(previous.size)) dec = np.pi / 2. - dec lmst, last = calcLmstLast(mjd, site.longitude_rad) lmst = lmst / 12. * 180. alt, az = stupidFast_RaDec2AltAz(ra, dec, site.latitude_rad, site.longitude_rad, mjd) frame = single_frame(mjd, filter_name='R') seen = np.where((frame != hp.UNSEEN) & (previous != hp.UNSEEN)) unseen = np.where((frame == hp.UNSEEN) | (previous == hp.UNSEEN)) frame = fixBias(frame) previous = fixBias(previous) diff = frame - previous diff[unseen] = hp.UNSEEN diff_frac = diff / previous
umjd = skyMaps['umjd'].copy() nstart = 5506+67 # partly cloudy frame #nstart = 6447 # very cloudy frame # nstart = 982 # clear, with moon previous = single_frame(umjd[nstart-1]) nside = hp.npix2nside(previous.size) mjd = umjd[nstart] site = Site('LSST') dec, ra = hp.pix2ang(nside, np.arange(previous.size)) dec = np.pi/2. - dec lmst, last = calcLmstLast(mjd, site.longitude_rad) lmst = lmst/12.*180. alt, az = stupidFast_RaDec2AltAz(ra, dec, site.latitude_rad, site.longitude_rad, mjd) frame = single_frame(mjd, filter_name='R') seen = np.where((frame != hp.UNSEEN) & (previous != hp.UNSEEN)) unseen = np.where((frame == hp.UNSEEN) | (previous == hp.UNSEEN)) frame = fixBias(frame) previous = fixBias(previous) diff = frame - previous diff[unseen] = hp.UNSEEN diff_frac = diff/previous
plt.rcParams.update({'xtick.labelsize': 'large', 'ytick.labelsize': 'large'}) # Let's recreate the delta m_5 plot from figure 3 in: # http://xxx.lanl.gov/pdf/1510.07574.pdf telescope = Site('LSST') nside = 32 lat, ra = hp.pix2ang(nside, np.arange(hp.nside2npix(nside))) dec = np.pi/2-lat kwargs = dict(twilight=False, zodiacal=False, moon=True, scatteredStar=False, mergedSpec=False) sm = sb.SkyModel(observatory='LSST', mags=True) # , **kwargs) mjd = 49353.177645 sm.setRaDecMjd(ra, dec, mjd) mag = sm.returnMags() lmst, last = calcLmstLast(mjd, telescope.longitude_rad) moonRA, moonDec = _raDecFromAltAz(sm.moonAlt, sm.moonAz, ObservationMetaData(mjd=mjd, site=telescope)) alt, az, pa = _altAzPaFromRaDec(ra, dec, ObservationMetaData(mjd=mjd, site=telescope)) angDist2Moon = np.degrees(haversine(az, alt, sm.moonAz, sm.moonAlt)) ang2 = np.degrees(haversine(ra, dec, moonRA, moonDec)) alt = np.degrees(alt) mags = -0.5*(np.nanmin(mag['u'])-mag['u']) #extent = (0,130, 0,90) extent = (20, 120, 20, 90) xs, ys = np.mgrid[extent[0]:extent[1], extent[2]:extent[3]]
def return_conditions(self): """ Returns ------- lsst.sims.featureScheduler.features.conditions object """ self.conditions.mjd = self.mjd self.conditions.night = self.night # Current time as astropy time current_time = Time(self.mjd, format='mjd') # Clouds. XXX--just the raw value self.conditions.bulk_cloud = self.cloud_data(current_time) # use conditions object itself to get aprox altitude of each healpx alts = self.conditions.alt azs = self.conditions.az good = np.where(alts > self.alt_min) # Compute the airmass at each heapix airmass = np.zeros(alts.size, dtype=float) airmass.fill(np.nan) airmass[good] = 1. / np.cos(np.pi / 2. - alts[good]) self.conditions.airmass = airmass # reset the seeing for key in self.seeing_FWHMeff: self.seeing_FWHMeff[key].fill(np.nan) # Use the model to get the seeing at this time and airmasses. FWHM_500 = self.seeing_data(current_time) seeing_dict = self.seeing_model(FWHM_500, airmass[good]) fwhm_eff = seeing_dict['fwhmEff'] for i, key in enumerate(self.seeing_model.filter_list): self.seeing_FWHMeff[key][good] = fwhm_eff[i, :] self.conditions.FWHMeff = self.seeing_FWHMeff # sky brightness self.conditions.skybrightness = self.sky_model.returnMags( self.mjd, airmass_mask=False, planet_mask=False, moon_mask=False, zenith_mask=False) self.conditions.mounted_filters = self.observatory.current_state.mountedfilters self.conditions.current_filter = self.observatory.current_state.filter[ 0] # Compute the slewtimes slewtimes = np.empty(alts.size, dtype=float) slewtimes.fill(np.nan) slewtimes[good] = self.observatory.get_approximate_slew_delay( alts[good], azs[good], self.observatory.current_state.filter, lax_dome=self.lax_dome) # Mask out anything the slewtime says is out of bounds slewtimes[np.where(slewtimes < 0)] = np.nan self.conditions.slewtime = slewtimes # Let's get the sun and moon sun_moon_info = self.almanac.get_sun_moon_positions(self.mjd) # convert these to scalars for key in sun_moon_info: sun_moon_info[key] = sun_moon_info[key].max() self.conditions.moonPhase = sun_moon_info['moon_phase'] self.conditions.moonAlt = sun_moon_info['moon_alt'] self.conditions.moonAz = sun_moon_info['moon_az'] self.conditions.moonRA = sun_moon_info['moon_RA'] self.conditions.moonDec = sun_moon_info['moon_dec'] self.conditions.sunAlt = sun_moon_info['sun_alt'] self.conditions.sunRA = sun_moon_info['sun_RA'] self.conditions.sunDec = sun_moon_info['sun_dec'] self.conditions.lmst, last = calcLmstLast(self.mjd, self.site.longitude_rad) self.conditions.telRA = self.observatory.current_state.ra_rad self.conditions.telDec = self.observatory.current_state.dec_rad self.conditions.telAlt = self.observatory.current_state.alt_rad self.conditions.telAz = self.observatory.current_state.az_rad self.conditions.rotTelPos = self.observatory.current_state.rot_rad # Add in the almanac information self.conditions.night = self.night self.conditions.sunset = self.almanac.sunsets['sunset'][ self.almanac_indx] self.conditions.sun_n12_setting = self.almanac.sunsets[ 'sun_n12_setting'][self.almanac_indx] self.conditions.sun_n18_setting = self.almanac.sunsets[ 'sun_n18_setting'][self.almanac_indx] self.conditions.sun_n18_rising = self.almanac.sunsets[ 'sun_n18_rising'][self.almanac_indx] self.conditions.sun_n12_rising = self.almanac.sunsets[ 'sun_n12_rising'][self.almanac_indx] self.conditions.sunrise = self.almanac.sunsets['sunrise'][ self.almanac_indx] self.conditions.moonrise = self.almanac.sunsets['moonrise'][ self.almanac_indx] self.conditions.moonset = self.almanac.sunsets['moonset'][ self.almanac_indx] # Planet positions from almanac self.conditions.planet_positions = self.almanac.get_planet_positions( self.mjd) # See if there are any ToOs to include if self.sim_ToO is not None: toos = self.sim_ToO(self.mjd) if toos is not None: self.conditions.targets_of_opportunity = toos return self.conditions