def hp2screen(inmap, mjd, height=500, alt_limit=10., npts=600, grid_x=None, grid_y=None): """ Convert a healpy map to a flat screen at height h """ nside = hp.npix2nside(inmap.size) unmasked = np.where(inmap != hp.UNSEEN)[0] ra, dec = _hpid2RaDec(nside, unmasked) alt, az = stupidFast_RaDec2AltAz(ra, dec, lat, lon, mjd) good = np.where(np.degrees(alt) > alt_limit) r = height / np.tan(alt[good]) x = r * np.cos(az[good]) y = r * np.sin(az[good]) z = inmap[unmasked][good] if grid_x is None: grid_x, grid_y = np.mgrid[x.min():x.max():600j, y.min():y.max():600j] screen_grid = interpolate.griddata(np.vstack((x, y)).T, z, (grid_x, grid_y), method='nearest') # Maybe compute the alt-az of the grid_x, grid_y so that it'll be fast to convert back to ra, dec? # Pretty clear this should be a class rather than a bunch of functions. return grid_x, grid_y, screen_grid
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 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)
def hp2screen(inmap, mjd, height=500, alt_limit=10., npts=600, grid_x=None, grid_y=None): """ Convert a healpy map to a flat screen at height h """ nside = hp.npix2nside(inmap.size) unmasked = np.where(inmap != hp.UNSEEN)[0] ra, dec = _hpid2RaDec(nside, unmasked) alt, az = stupidFast_RaDec2AltAz(ra, dec, lat, lon, mjd) good = np.where(np.degrees(alt) > alt_limit) r = height/np.tan(alt[good]) x = r*np.cos(az[good]) y = r*np.sin(az[good]) z = inmap[unmasked][good] if grid_x is None: grid_x, grid_y = np.mgrid[x.min():x.max():600j, y.min():y.max():600j] screen_grid = interpolate.griddata(np.vstack((x, y)).T, z, (grid_x, grid_y), method='nearest') # Maybe compute the alt-az of the grid_x, grid_y so that it'll be fast to convert back to ra, dec? # Pretty clear this should be a class rather than a bunch of functions. return grid_x, grid_y, screen_grid
oldPC = 0 for i, mjd, djd in zip(indices, mjds, mjds-doff): lsstObs.date = djd sun.compute(lsstObs) if sun.alt > sun_alt_limit: results['mask'][i] = 0 else: moon.compute(djd) moon_mask_indices = healTree.query_ball_point(treexyz(moon.ra, moon.dec), moon_avoid) venus.compute(djd) venus_mask_indices = healTree.query_ball_point(treexyz(venus.ra, venus.dec), venus_avoid) results['mask'][i][moon_mask_indices] = 0 results['mask'][i][venus_mask_indices] = 0 #alt,az,pa = _altAzPaFromRaDec(ra, dec, ObservationMetaData(mjd=mjd,site=site)) alt, az = sb.stupidFast_RaDec2AltAz(ra, dec, site.latitude_rad, site.longitude_rad, mjd) zenith_mask = np.where(alt > np.radians(90.-zenith_avoid)) results['mask'][i][zenith_mask] = 0 # Let's only compute airmass for good ones high_enough = np.where((alt > np.radians(alt_limit))) too_low = np.where((alt <= np.radians(alt_limit))) results['airmass'][i][high_enough] = 1./np.cos(np.pi/2.-alt[high_enough]) results['mask'][i][too_low] = 0 sm.setRaDecMjd(ra[high_enough], dec[high_enough], mjd) skyMags = sm.returnMags() for key in list(filterDict.keys()): results[key][i][high_enough] = skyMags[:, filterDict[key]] percentComplete = int(float(i)/loopSize*100)
lsstObs.date = djd sun.compute(lsstObs) if sun.alt > sun_alt_limit: results['mask'][i] = 0 else: moon.compute(djd) moon_mask_indices = healTree.query_ball_point( treexyz(moon.ra, moon.dec), moon_avoid) venus.compute(djd) venus_mask_indices = healTree.query_ball_point( treexyz(venus.ra, venus.dec), venus_avoid) results['mask'][i][moon_mask_indices] = 0 results['mask'][i][venus_mask_indices] = 0 #alt,az,pa = _altAzPaFromRaDec(ra, dec, ObservationMetaData(mjd=mjd,site=site)) alt, az = sb.stupidFast_RaDec2AltAz(ra, dec, site.latitude_rad, site.longitude_rad, mjd) zenith_mask = np.where(alt > np.radians(90. - zenith_avoid)) results['mask'][i][zenith_mask] = 0 # Let's only compute airmass for good ones high_enough = np.where((alt > np.radians(alt_limit))) too_low = np.where((alt <= np.radians(alt_limit))) results['airmass'][i][high_enough] = 1. / np.cos(np.pi / 2. - alt[high_enough]) results['mask'][i][too_low] = 0 sm.setRaDecMjd(ra[high_enough], dec[high_enough], mjd) skyMags = sm.returnMags() for key in list(filterDict.keys()): results[key][i][high_enough] = skyMags[:, filterDict[key]]
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)