def _setupPointGrid(self): """ Setup the points for the interpolation functions. """ # Switch to Dublin Julian Date for pyephem self.Observatory.date = mjd2djd(self.mjd) sun = ephem.Sun() sun.compute(self.Observatory) self.sunAlt = sun.alt self.sunAz = sun.az self.sunRA = sun.ra self.sunDec = sun.dec # Compute airmass the same way as ESO model self.airmass = 1./np.cos(np.pi/2.-self.alts) self.points['airmass'] = self.airmass self.points['nightTimes'] = 2 self.points['alt'] = self.alts self.points['az'] = self.azs if self.twilight: self.points['sunAlt'] = self.sunAlt self.azRelSun = wrapRA(self.azs - self.sunAz) self.points['azRelSun'] = self.azRelSun if self.moon: moon = ephem.Moon() moon.compute(self.Observatory) self.moonPhase = moon.phase self.moonAlt = moon.alt self.moonAz = moon.az self.moonRA = moon.ra self.moonDec = moon.dec # Calc azimuth relative to moon self.azRelMoon = calcAzRelMoon(self.azs, self.moonAz) self.moonTargSep = haversine(self.azs, self.alts, self.moonAz, self.moonAlt) self.points['moonAltitude'] += np.degrees(self.moonAlt) self.points['azRelMoon'] += self.azRelMoon self.moonSunSep = self.moonPhase/100.*180. self.points['moonSunSep'] += self.moonSunSep if self.zodiacal: self.eclipLon = np.zeros(self.npts) self.eclipLat = np.zeros(self.npts) for i, temp in enumerate(self.ra): eclip = ephem.Ecliptic(ephem.Equatorial(self.ra[i], self.dec[i], epoch='2000')) self.eclipLon[i] += eclip.lon self.eclipLat[i] += eclip.lat # Subtract off the sun ecliptic longitude sunEclip = ephem.Ecliptic(sun) self.sunEclipLon = sunEclip.lon self.points['altEclip'] += self.eclipLat self.points['azEclipRelSun'] += wrapRA(self.eclipLon - self.sunEclipLon) self.mask = np.where((self.airmass > self.airmassLimit) | (self.airmass < 1.))[0] self.goodPix = np.where((self.airmass <= self.airmassLimit) & (self.airmass >= 1.))[0]
def testSunMoon(self): """ Test that the sun moon interpolation is good enough """ if self.data_present: sm = self.sm telescope = utils.Site('LSST') Observatory = ephem.Observer() Observatory.lat = telescope.latitude_rad Observatory.lon = telescope.longitude_rad Observatory.elevation = telescope.height sun = ephem.Sun() moon = ephem.Moon() mjd1 = sm.info['mjds'][0] mjd2 = sm.info['mjds'][3] mjds = np.linspace(mjd1, mjd2, 20) # Demand Moon and Sun Positions match to within 3 arcmin arcmin_places = np.abs(np.floor(np.log10(3. / 60. / 180. * np.pi))).astype(int) for mjd in mjds: Observatory.date = mjd2djd(mjd) sun.compute(Observatory) moon.compute(Observatory) pre_calced = sm.returnSunMoon(mjd) self.assertLess(np.abs(pre_calced['sunAlt'] - sun.alt), arcmin_places) sun_dist = haversine(sun.ra, sun.dec, pre_calced['sunRA'], pre_calced['sunDec']) self.assertAlmostEqual(sun_dist, 0., places=arcmin_places) self.assertLess(np.abs(pre_calced['moonAlt'] - moon.alt), arcmin_places) moon_dist = haversine(moon.ra, moon.dec, pre_calced['moonRA'], pre_calced['moonDec']) self.assertAlmostEqual(moon_dist, 0., places=arcmin_places) self.assertAlmostEqual(np.radians(pre_calced['moonSunSep']), np.radians(moon.phase / 100. * 180.), places=arcmin_places)
def _setupPointGrid(self): """ Setup the points for the interpolation functions. """ # Switch to Dublin Julian Date for pyephem self.Observatory.date = mjd2djd(self.mjd) sun = ephem.Sun() sun.compute(self.Observatory) self.sunAlt = sun.alt self.sunAz = sun.az self.sunRA = sun.ra self.sunDec = sun.dec # Compute airmass the same way as ESO model self.airmass = 1. / np.cos(np.pi / 2. - self.alts) self.points['airmass'] = self.airmass self.points['nightTimes'] = 2 self.points['alt'] = self.alts self.points['az'] = self.azs if self.twilight: self.points['sunAlt'] = self.sunAlt self.azRelSun = wrapRA(self.azs - self.sunAz) self.points['azRelSun'] = self.azRelSun if self.moon: moon = ephem.Moon() moon.compute(self.Observatory) self.moonPhase = moon.phase self.moonAlt = moon.alt self.moonAz = moon.az self.moonRA = moon.ra self.moonDec = moon.dec # Calc azimuth relative to moon self.azRelMoon = calcAzRelMoon(self.azs, self.moonAz) self.moonTargSep = haversine(self.azs, self.alts, self.moonAz, self.moonAlt) self.points['moonAltitude'] += np.degrees(self.moonAlt) self.points['azRelMoon'] += self.azRelMoon self.moonSunSep = self.moonPhase / 100. * 180. self.points['moonSunSep'] += self.moonSunSep if self.zodiacal: self.eclipLon = np.zeros(self.npts) self.eclipLat = np.zeros(self.npts) for i, temp in enumerate(self.ra): eclip = ephem.Ecliptic( ephem.Equatorial(self.ra[i], self.dec[i], epoch='2000')) self.eclipLon[i] += eclip.lon self.eclipLat[i] += eclip.lat # Subtract off the sun ecliptic longitude sunEclip = ephem.Ecliptic(sun) self.sunEclipLon = sunEclip.lon self.points['altEclip'] += self.eclipLat self.points['azEclipRelSun'] += wrapRA(self.eclipLon - self.sunEclipLon) self.mask = np.where((self.airmass > self.airmassLimit) | (self.airmass < 1.))[0] self.goodPix = np.where((self.airmass <= self.airmassLimit) & (self.airmass >= 1.))[0]
mjds = np.append(mjds, data['mjd']) mjds = np.unique(mjds) # Generate starID table starids = np.arange(ra.size) f = open('starTable.dat', 'w') for i,rai in enumerate(ra): print >>f, '%i,%f,%f,0' % (i,ra[i],dec[i]) f.close() # Generate mjd table f = open('mjdTable.dat', 'w') mjdID = np.arange(mjds.size) for mjdid,mjd in zip(mjdID,mjds): Observatory.date = mjd2djd(mjd) sun.compute(Observatory) moon.compute(Observatory) print >>f, '%i,%f,%f,%f,%f' % (mjdid, mjd, sun.alt, moon.alt, moon.phase) f.close() # now to loop through and write the obs table and the mjd table names = ['mjd', 'ra','dec', 'm','alt', 'dm', 'sky', 'band'] types = [float]*7 types.append('|S1') obsidMax = 0 f = open('obsTable.dat', 'w') maxJ = float(len(allFiles))
def generate_lookahead_tables(mjd0=59560.2, mjd_max=59621.2, timestep=5., timestep_max=20., outfile='generated_sky.npz', outpath=None, nside=32, sunLimit=-12., fieldID=False, airmass_limit=1.5, dm=0.3, verbose=True): """ Use the sky brightness model and the astronomical sky model to generate map of whether the sky will be observable at a given point in time and space, based on airmass, sky brightness, and moon location. Each feature gets its own map, where a 0 means a field or healpixel is not observable, and a 1 means it is. For now these are always 0 or 1 but they are typed as floats to accomodate future improvements """ sunLimit = np.radians(sunLimit) # Set the time steps timestep = timestep / 60. / 24. # Convert to days timestep_max = timestep_max / 60. / 24. # Convert to days # Switch the indexing to opsim field ID if requested # Look at the mjds and toss ones where the sun is up mjds = np.arange(mjd0, mjd_max + timestep, timestep) sunAlts = np.zeros(mjds.size, dtype=float) telescope = utils.Site('LSST') Observatory = ephem.Observer() Observatory.lat = telescope.latitude_rad Observatory.lon = telescope.longitude_rad Observatory.elevation = telescope.height sun = ephem.Sun() for i, mjd in enumerate(mjds): Observatory.date = mjd2djd(mjd) sun.compute(Observatory) sunAlts[i] = sun.alt mjds = mjds[np.where(sunAlts <= np.radians(sunLimit))] if fieldID: field_data = np.loadtxt('fieldID.dat', delimiter='|', skiprows=1, dtype=list( zip(['id', 'ra', 'dec'], [int, float, float]))) ra = field_data['ra'] dec = field_data['dec'] else: hpindx = np.arange(hp.nside2npix(nside)) ra, dec = utils.hpid2RaDec(nside, hpindx) if verbose: print('using %i points on the sky' % ra.size) print('using %i mjds' % mjds.size) # Set up the sky brightness model sm = sb.SkyModel(mags=True) filter_names = [u'u', u'g', u'r', u'i', u'z', u'y'] # Initialize the relevant lists sky_brightness = {u'airmass': np.zeros((len(mjds), len(ra)), dtype = float),\ u'mjds': np.zeros((len(mjds), len(ra)), dtype = float),\ u'moonangle': np.zeros((len(mjds), len(ra)), dtype = float) } vmjd = np.zeros(len(mjds)) for filter_name in filter_names: sky_brightness[filter_name] = np.zeros((len(mjds), len(ra)), dtype=float) length = mjds[-1] - mjds[0] for i, mjd in enumerate(mjds): progress = (mjd - mjd0) / length * 100 text = "\rprogress = %.1f%%" % progress sys.stdout.write(text) sys.stdout.flush() sm.setRaDecMjd(ra, dec, mjd, degrees=True) if sm.sunAlt <= sunLimit: mags = sm.returnMags() for key in filter_names: sky_brightness[key][ i] = mags[key] < 21.3 #placeholder skybrightness airmasscomp = np.bitwise_and(1.5 > sm.airmass, sm.airmass > 1.0) sky_brightness[u'airmass'][i] = airmasscomp moonangles = palpy.dsepVector(np.full_like(ra,sm.moonRA), np.full_like(dec,sm.moonDec),\ np.deg2rad(ra), np.deg2rad(dec)) sky_brightness[u'moonangle'][ i] = moonangles > 0.698 #placeholder moon angle limit, ~40 degrees vmjd[i] = mjd print('') # for key in dict_of_lists: # dict_of_lists[key] = np.array(dict_of_lists[key]) # # print(len(dict_of_lists[key])) # for key in sky_brightness: # sky_brightness[key] = np.array(sky_brightness[key]) np.savez_compressed(outfile, mjds=vmjd, look_ahead=sky_brightness)
def setRaDecMjd(self, lon, lat, mjd, degrees=False, azAlt=False, solarFlux=130.): """ Set the sky parameters by computing the sky conditions on a given MJD and sky location. Ra and Dec in raidans or degrees. input ra, dec or az,alt w/ altAz=True solarFlux: solar flux in s.f.u. Between 50 and 310. """ # Wrap in array just in case single points were passed if not type(lon).__module__ == np.__name__: if np.size(lon) == 1: lon = np.array([lon]) lat = np.array([lat]) else: lon = np.array(lon) lat = np.array(lat) if degrees: self.ra = np.radians(lon) self.dec = np.radians(lat) else: self.ra = lon self.dec = lat self.mjd = mjd if azAlt: self.azs = self.ra.copy() self.alts = self.dec.copy() self.ra, self.dec = _raDecFromAltAz(self.alts, self.azs, self.Observatory.lon, self.Observatory.lat, self.mjd) else: self.alts, self.azs, pa = _altAzPaFromRaDec( self.ra, self.dec, self.Observatory.lon, self.Observatory.lat, self.mjd) self.npts = self.ra.size self._initPoints() self.solarFlux = solarFlux self.points['solarFlux'] = self.solarFlux # Switch to Dublin Julian Date for pyephem self.Observatory.date = mjd2djd(self.mjd) sun = ephem.Sun() sun.compute(self.Observatory) self.sunAlt = sun.alt self.sunAz = sun.az # Compute airmass the same way as ESO model self.airmass = 1. / np.cos(np.pi / 2. - self.alts) self.points['airmass'] = self.airmass self.points['nightTimes'] = 2 self.points['alt'] = self.alts self.points['az'] = self.azs if self.twilight: self.points['sunAlt'] = self.sunAlt self.points['azRelSun'] = wrapRA(self.azs - self.sunAz) if self.moon: moon = ephem.Moon() moon.compute(self.Observatory) self.moonPhase = moon.phase self.moonAlt = moon.alt self.moonAz = moon.az # Calc azimuth relative to moon self.azRelMoon = wrapRA(self.azs - self.moonAz) over = np.where(self.azRelMoon > np.pi) self.azRelMoon[over] = 2. * np.pi - self.azRelMoon[over] self.points['moonAltitude'] += np.degrees(self.moonAlt) self.points['azRelMoon'] += self.azRelMoon self.points['moonSunSep'] += self.moonPhase / 100. * 180. if self.zodiacal: self.eclipLon = np.zeros(self.npts) self.eclipLat = np.zeros(self.npts) for i, temp in enumerate(self.ra): eclip = ephem.Ecliptic( ephem.Equatorial(self.ra[i], self.dec[i], epoch='2000')) self.eclipLon[i] += eclip.lon self.eclipLat[i] += eclip.lat # Subtract off the sun ecliptic longitude sunEclip = ephem.Ecliptic(sun) self.sunEclipLon = sunEclip.lon self.points['altEclip'] += self.eclipLat self.points['azEclipRelSun'] += wrapRA(self.eclipLon - self.sunEclipLon)
data.sort(order='mjd') umjd = np.unique(data['mjd']) left = np.searchsorted(data['mjd'], umjd) right = np.searchsorted(data['mjd'], umjd, side='right') altaz = np.zeros(data.size, dtype=zip(['alt','az'], [float]*2)) moonAlt = np.zeros(data.size, dtype=float) print 'computing alts and azs' for j, (le, ri, mjd) in enumerate(zip(left,right,umjd)): Observatory.date = mjd2djd(mjd) sun.compute(Observatory) obs_metadata = ObservationMetaData(pointingRA=np.degrees(sun.ra), pointingDec=np.degrees(sun.dec), rotSkyPos=np.degrees(0), mjd=mjd) alt, az, pa = _altAzPaFromRaDec(data['ra'][le:ri], data['dec'][le:ri], obs_metadata) az = wrapRA(az - sun.az) altaz['alt'][le:ri] += alt altaz['az'][le:ri] += az moon.compute(Observatory) moonAlt[le:ri] += moon.alt print 'making maps' good = np.where(moonAlt < 0) magMap[:,i] = _healbin(altaz['az'][good],altaz['alt'][good], data['sky'][good],
def setRaDecMjd(self,lon,lat,mjd,degrees=False,azAlt=False,solarFlux=130.): """ Set the sky parameters by computing the sky conditions on a given MJD and sky location. Ra and Dec in raidans or degrees. input ra, dec or az,alt w/ altAz=True solarFlux: solar flux in s.f.u. Between 50 and 310. """ # Wrap in array just in case single points were passed if not type(lon).__module__ == np.__name__ : if np.size(lon) == 1: lon = np.array([lon]) lat = np.array([lat]) else: lon = np.array(lon) lat = np.array(lat) if degrees: self.ra = np.radians(lon) self.dec = np.radians(lat) else: self.ra = lon self.dec = lat self.mjd = mjd if azAlt: self.azs = self.ra.copy() self.alts = self.dec.copy() self.ra,self.dec = _raDecFromAltAz(self.alts,self.azs, self.Observatory.lon, self.Observatory.lat, self.mjd) else: self.alts,self.azs,pa = _altAzPaFromRaDec(self.ra, self.dec, self.Observatory.lon, self.Observatory.lat, self.mjd) self.npts = self.ra.size self._initPoints() self.solarFlux = solarFlux self.points['solarFlux'] = self.solarFlux # Switch to Dublin Julian Date for pyephem self.Observatory.date = mjd2djd(self.mjd) sun = ephem.Sun() sun.compute(self.Observatory) self.sunAlt = sun.alt self.sunAz = sun.az # Compute airmass the same way as ESO model self.airmass = 1./np.cos(np.pi/2.-self.alts) self.points['airmass'] = self.airmass self.points['nightTimes'] = 2 self.points['alt'] = self.alts self.points['az'] = self.azs if self.twilight: self.points['sunAlt'] = self.sunAlt self.points['azRelSun'] = wrapRA(self.azs - self.sunAz) if self.moon: moon = ephem.Moon() moon.compute(self.Observatory) self.moonPhase = moon.phase self.moonAlt = moon.alt self.moonAz = moon.az # Calc azimuth relative to moon self.azRelMoon = wrapRA(self.azs - self.moonAz) over = np.where(self.azRelMoon > np.pi) self.azRelMoon[over] = 2.*np.pi - self.azRelMoon[over] self.points['moonAltitude'] += np.degrees(self.moonAlt) self.points['azRelMoon'] += self.azRelMoon self.points['moonSunSep'] += self.moonPhase/100.*180. if self.zodiacal: self.eclipLon = np.zeros(self.npts) self.eclipLat = np.zeros(self.npts) for i,temp in enumerate(self.ra): eclip = ephem.Ecliptic(ephem.Equatorial(self.ra[i],self.dec[i], epoch='2000')) self.eclipLon[i] += eclip.lon self.eclipLat[i] += eclip.lat # Subtract off the sun ecliptic longitude sunEclip = ephem.Ecliptic(sun) self.sunEclipLon = sunEclip.lon self.points['altEclip'] += self.eclipLat self.points['azEclipRelSun'] += wrapRA(self.eclipLon - self.sunEclipLon)
def generate_sky(mjd0=59560.2, mjd_max=59565.2, timestep=5., timestep_max=15., outfile=None, outpath=None, nside=32, sunLimit=-12., fieldID=False, airmass_overhead=1.5, dm=0.2, airmass_limit=2.5, moon_dist_limit=10., planet_dist_limit=2., alt_limit=86.5, requireStride=3, verbose=True): """ Pre-compute the sky brighntess for a series of mjd dates at the LSST site. Parameters ---------- mjd0 : float (9560.2) The starting MJD time duration : float The length of time to generate sky maps for (years) timestep : float (5.) The timestep between sky maps (minutes) timestep_max : float (20.) The maximum alowable timestep (minutes) outfile : str The name of the output file to save the results in nside : in (32) The nside to run the healpixel map at sunLimit : float (-12) The maximum altitude of the sun to try and generate maps for. MJDs with a higher sun altitude are dropped fieldID : bool (False) If True, computes sky magnitudes at OpSim field locations. If False computes at healpixel centers. airmass_overhead : float The airmass region to demand sky models are well matched before dropping and assuming the timestep can be interpolated dm : float If a skymap can be interpolated from neighboring maps with precision dm, that mjd is dropped. airmass_limit : float Pixels with an airmass greater than airmass_limit are masked moon_dist_limit : float Pixels (fields) closer than moon_dist_limit (degrees) are masked planet_dist_limit : float (2.) Pixels (fields) closer than planet_dist_limit (degrees) to Venus, Mars, Jupiter, or Saturn are masked alt_limit : float (86.5) Altitude limit of the telescope (degrees). Altitudes higher than this are masked. requireStride : int (3) Require every nth mjd. Makes it possible to easily select an evenly spaced number states of a pixel. Returns ------- dict_of_lists : dict includes key-value pairs: mjds : the MJD at every computation. Not evenly spaced as no computations. airmass : the airmass maps for each MJD masks : The boolean mask map for each MJD (True means the pixel should be masked) sunAlts : The sun altitude at each MJD sky_brightness : dict Has keys for each u,g,r,i,z,y filter. Each one is a 2-d array with dimensions of healpix ID and mjd (matched to the mjd list above). """ sunLimit_rad = np.radians(sunLimit) alt_limit_rad = np.radians(alt_limit) # Set the time steps timestep = timestep / 60. / 24. # Convert to days timestep_max = timestep_max / 60. / 24. # Convert to days # Switch the indexing to opsim field ID if requested # Look at the mjds and toss ones where the sun is up mjds = np.arange(mjd0, mjd_max + timestep, timestep) sunAlts = np.zeros(mjds.size, dtype=float) if outfile is None: outfile = '%i_%i.npz' % (mjd0, mjd_max) if outpath is not None: outfile = os.path.join(outpath, outfile) telescope = utils.Site('LSST') Observatory = ephem.Observer() Observatory.lat = telescope.latitude_rad Observatory.lon = telescope.longitude_rad Observatory.elevation = telescope.height sun = ephem.Sun() # Planets we want to avoid planets = [ephem.Venus(), ephem.Mars(), ephem.Jupiter(), ephem.Saturn()] # Compute the sun altitude for all the possible MJDs for i, mjd in enumerate(mjds): Observatory.date = mjd2djd(mjd) sun.compute(Observatory) sunAlts[i] = sun.alt mjds = mjds[np.where(sunAlts <= sunLimit_rad)] required_mjds = mjds[::3] if fieldID: field_data = np.loadtxt('fieldID.dat', delimiter='|', skiprows=1, dtype=list( zip(['id', 'ra', 'dec'], [int, float, float]))) ra = field_data['ra'] dec = field_data['dec'] else: hpindx = np.arange(hp.nside2npix(nside)) ra, dec = utils.hpid2RaDec(nside, hpindx) ra_rad = np.radians(ra) dec_rad = np.radians(dec) if verbose: print('using %i points on the sky' % ra.size) print('using %i mjds' % mjds.size) # Set up the sky brightness model sm = sb.SkyModel(mags=True, airmass_limit=airmass_limit) filter_names = ['u', 'g', 'r', 'i', 'z', 'y'] # Initialize the relevant lists dict_of_lists = { 'airmass': [], 'sunAlts': [], 'mjds': [], 'airmass_masks': [], 'planet_masks': [], 'moonAlts': [], 'moonRAs': [], 'moonDecs': [], 'sunRAs': [], 'sunDecs': [], 'moonSunSep': [], 'moon_masks': [], 'zenith_masks': [] } sky_brightness = {} for filter_name in filter_names: sky_brightness[filter_name] = [] length = mjds[-1] - mjds[0] last_5_mags = [] last_5_mjds = [] full_masks = [] for mjd in mjds: progress = (mjd - mjd0) / length * 100 text = "\rprogress = %.1f%%" % progress sys.stdout.write(text) sys.stdout.flush() sm.setRaDecMjd(ra, dec, mjd, degrees=True) if sm.sunAlt <= sunLimit_rad: mags = sm.returnMags() for key in filter_names: sky_brightness[key].append(mags[key]) dict_of_lists['airmass'].append(sm.airmass) dict_of_lists['sunAlts'].append(sm.sunAlt) dict_of_lists['mjds'].append(mjd) dict_of_lists['sunRAs'].append(sm.sunRA) dict_of_lists['sunDecs'].append(sm.sunDec) dict_of_lists['moonRAs'].append(sm.moonRA) dict_of_lists['moonDecs'].append(sm.moonDec) dict_of_lists['moonSunSep'].append(sm.moonSunSep) dict_of_lists['moonAlts'].append(sm.moonAlt) last_5_mjds.append(mjd) last_5_mags.append(mags) if len(last_5_mjds) > 5: del last_5_mjds[0] del last_5_mags[0] masks = { 'moon': None, 'airmass': None, 'planet': None, 'zenith': None } for mask in masks: masks[mask] = np.zeros(np.size(ra), dtype=bool) masks[mask].fill(False) # Apply airmass masking limit masks['airmass'][np.where((sm.airmass > airmass_limit) | (sm.airmass < 1.))] = True # Apply moon distance limit masks['moon'][np.where( sm.moonTargSep <= np.radians(moon_dist_limit))] = True # Apply altitude limit masks['zenith'][np.where(sm.alts >= alt_limit_rad)] = True # Apply the planet distance limits Observatory.date = mjd2djd(mjd) for planet in planets: planet.compute(Observatory) distances = utils.haversine(ra_rad, dec_rad, planet.ra, planet.dec) masks['planet'][np.where( distances <= np.radians(planet_dist_limit))] = True full_mask = np.zeros(np.size(ra), dtype=bool) full_mask.fill(False) for key in masks: dict_of_lists[key + '_masks'].append(masks[key]) full_mask[masks[key]] = True full_masks.append(full_mask) if len(dict_of_lists['airmass']) > 3: if dict_of_lists['mjds'][-2] not in required_mjds: # Check if we can interpolate the second to last sky brightnesses overhead = np.where( (dict_of_lists['airmass'][-1] <= airmass_overhead) & (dict_of_lists['airmass'][-2] <= airmass_overhead) & (~full_masks[-1]) & (~full_masks[-2])) if (np.size(overhead[0]) > 0) & (dict_of_lists['mjds'][-1] - dict_of_lists['mjds'][-3] < timestep_max): can_interp = True for mjd2 in last_5_mjds: mjd1 = dict_of_lists['mjds'][-3] mjd3 = dict_of_lists['mjds'][-1] if (mjd2 > mjd1) & (mjd2 < mjd3): indx = np.where(last_5_mjds == mjd2)[0] # Linear interpolation weights wterm = (mjd2 - mjd1) / (mjd3 - mjd1) w1 = 1. - wterm w2 = wterm for filter_name in filter_names: interp_sky = w1 * sky_brightness[ filter_name][-3][overhead] interp_sky += w2 * sky_brightness[ filter_name][-1][overhead] diff = np.abs(last_5_mags[int( indx)][filter_name][overhead] - interp_sky) if np.size(diff[~np.isnan(diff)]) > 0: if np.max(diff[~np.isnan(diff)]) > dm: can_interp = False if can_interp: for key in dict_of_lists: del dict_of_lists[key][-2] for key in sky_brightness: del sky_brightness[key][-2] print('') for key in dict_of_lists: dict_of_lists[key] = np.array(dict_of_lists[key]) for key in sky_brightness: sky_brightness[key] = np.array(sky_brightness[key]) import lsst.sims.skybrightness_pre version = lsst.sims.skybrightness_pre.version.__version__ fingerprint = lsst.sims.skybrightness_pre.version.__fingerprint__ # Generate a header to save all the kwarg info for how this run was computed header = { 'mjd0': mjd0, 'mjd_max': mjd_max, 'timestep': timestep, 'timestep_max': timestep_max, 'outfile': outfile, 'outpath': outpath, 'nside': nside, 'sunLimit': sunLimit, 'fieldID': fieldID, 'airmas_overhead': airmass_overhead, 'dm': dm, 'airmass_limit': airmass_limit, 'moon_dist_limit': moon_dist_limit, 'planet_dist_limit': planet_dist_limit, 'alt_limit': alt_limit, 'ra': ra, 'dec': dec, 'verbose': verbose, 'required_mjds': required_mjds, 'version': version, 'fingerprint': fingerprint } np.savez(outfile, dict_of_lists=dict_of_lists, header=header) # Convert sky_brightness to a true array so it's easier to save types = [float] * len(sky_brightness.keys()) result = np.zeros(sky_brightness[list(sky_brightness.keys())[0]].shape, dtype=list(zip(sky_brightness.keys(), types))) for key in sky_brightness.keys(): result[key] = sky_brightness[key] np.save(outfile[:-3] + 'npy', result)
robustRMS(validationArr['frameZP'][good])) print('------') rmsArray.append((filterName, dark, gray, bright)) # OK, want to look at residuals as a function of time-of-year and time-of-night. # Maybe just do this for dark time darkTime = np.where((resid != 0.) & (validationArr['moonAlt'] != -666) & (validationArr['moonAlt'] < 0) & (validationArr['sunAlt'] < -20.))[0] names = ['sinceSet', 'toSet'] mjdInfo = np.zeros(darkTime.size, dtype=list(zip(names, types))) sun = ephem.Sun() djds = mjd2djd(validationArr['mjd'][darkTime]) for i, djd in enumerate(djds): Observatory.date = djd mjdInfo['sinceSet'][i] = djd - Observatory.previous_setting(sun) mjdInfo['toSet'][i] = Observatory.next_setting(sun) - djd fig, ax = plt.subplots(1) residuals = resid[darkTime] - validationArr['frameZP'][darkTime] ax.plot(mjdInfo['sinceSet'] * 24., residuals, 'ko', alpha=0.2) ax.set_xlabel('Time Since Sunset (hours)') ax.set_ylabel('Observation-Model (mags)') ax.set_title('Zenith Dark Time Residuals, %s' % filterName) ax.set_ylim([-0.4, 1]) fig.savefig('Plots/residTON_%s.pdf' % filterName) plt.close(fig)
def generate_sky(mjd0=59560.2, duration=0.01, timestep=5., timestep_max=20., outfile='generated_sky.npz', nside=32, sunLimit=-12., fieldID=False, airmass_limit=1.5, dm=0.3, verbose=True): """ Use the sky brightness model to generate a number of useful numpy arrays that can be used to look-up sky brighntess and other pre-computed info """ sunLimit = np.radians(sunLimit) # Set the time steps mjd_max = mjd0 + duration*365.25 timestep = timestep / 60. / 24. # Convert to days timestep_max = timestep_max / 60. / 24. # Convert to days # Switch the indexing to opsim field ID if requested # Look at the mjds and toss ones where the sun is up mjds = np.arange(mjd0, mjd_max+timestep, timestep) sunAlts = np.zeros(mjds.size, dtype=float) telescope = utils.Site('LSST') Observatory = ephem.Observer() Observatory.lat = telescope.latitude_rad Observatory.lon = telescope.longitude_rad Observatory.elevation = telescope.height sun = ephem.Sun() for i, mjd in enumerate(mjds): Observatory.date = mjd2djd(mjd) sun.compute(Observatory) sunAlts[i] = sun.alt mjds = mjds[np.where(sunAlts <= np.radians(sunLimit))] if fieldID: field_data = np.loadtxt('fieldID.dat', delimiter='|', skiprows=1, dtype=list(zip(['id', 'ra', 'dec'], [int, float, float]))) ra = field_data['ra'] dec = field_data['dec'] else: hpindx = np.arange(hp.nside2npix(nside)) ra, dec = utils.hpid2RaDec(nside, hpindx) if verbose: print('using %i points on the sky' % ra.size) print('using %i mjds' % mjds.size) # Set up the sky brightness model sm = sb.SkyModel(mags=True) filter_names = ['u', 'g', 'r', 'i', 'z', 'y'] # Initialize the relevant lists dict_of_lists = {'airmass': [], 'sunAlts': [], 'mjds': []} sky_brightness = {} for filter_name in filter_names: sky_brightness[filter_name] = [] length = mjds[-1] - mjds[0] for mjd in mjds: progress = (mjd-mjd0)/length*100 text = "\rprogress = %.1f%%"%progress sys.stdout.write(text) sys.stdout.flush() sm.setRaDecMjd(ra, dec, mjd, degrees=True) if sm.sunAlt <= sunLimit: mags = sm.returnMags() for key in filter_names: sky_brightness[key].append(mags[key]) dict_of_lists['airmass'].append(sm.airmass) dict_of_lists['sunAlts'].append(sm.sunAlt) dict_of_lists['mjds'].append(mjd) # XXX don't toss things now. if False: # Check if we can interpolate the second to last sky brightnesses overhead = np.where((dict_of_lists['airmass'][-1] <= airmass_limit) & (dict_of_lists['airmass'][-2] <= airmass_limit)) # XXX -- might need to also excude things near the moon if np.size(overhead[0]) > 0: can_interp = True mjd1 = dict_of_lists['mjds'][-3] mjd2 = dict_of_lists['mjds'][-2] mjd3 = dict_of_lists['mjds'][-1] # Linear interpolation weights wterm = (mjd2 - mjd1) / (mjd3-mjd1) w1 = 1. - wterm w2 = wterm for filter_name in filter_names: interp_sky = w1 * sky_brightness[filter_name][-3][overhead] interp_sky += w2 * sky_brightness[filter_name][-1][overhead] diff = np.abs(sky_brightness[filter_name][-2][overhead]-interp_sky) if np.size(diff[~np.isnan(diff)]) > 0: if np.max(diff[~np.isnan(diff)]) > dm: can_interp = False # If the timestep is getting big, don't interp even if you can if (dict_of_lists['mjds'][-3] - dict_of_lists['mjds'][-2]) > timestep_max: can_interp = False if can_interp: for key in dict_of_lists: del dict_of_lists[key][-2] for key in sky_brightness: del sky_brightness[key][-2] print('') for key in dict_of_lists: dict_of_lists[key] = np.array(dict_of_lists[key]) for key in sky_brightness: sky_brightness[key] = np.array(sky_brightness[key]) np.savez(outfile, dict_of_lists = dict_of_lists, sky_brightness=sky_brightness)
print 'Twilight time adopted frame ZP rms = %f mag' % robustRMS(validationArr['frameZP'][good]) print '------' rmsArray.append((filterName, dark,gray,bright)) # OK, want to look at residuals as a function of time-of-year and time-of-night. #Maybe just do this for dark time darkTime = np.where( (resid != 0.) & (validationArr['moonAlt'] != -666) & (validationArr['moonAlt'] < 0) & (validationArr['sunAlt'] < -20.))[0] names = ['sinceSet', 'toSet'] mjdInfo = np.zeros(darkTime.size, dtype=zip(names,types)) sun = ephem.Sun() djds = mjd2djd(validationArr['mjd'][darkTime]) for i,djd in enumerate(djds): Observatory.date = djd mjdInfo['sinceSet'][i] = djd-Observatory.previous_setting(sun) mjdInfo['toSet'][i] = Observatory.next_setting(sun)-djd fig,ax = plt.subplots(1) residuals=resid[darkTime]-validationArr['frameZP'][darkTime] ax.plot(mjdInfo['sinceSet']*24., residuals, 'ko', alpha=0.2) ax.set_xlabel('Time Since Sunset (hours)') ax.set_ylabel('Observation-Model (mags)') ax.set_title('Zenith Dark Time Residuals, %s' % filterName) ax.set_ylim([-0.4,1]) fig.savefig('Plots/residTON_%s.pdf' % filterName)