def estimate_wcs_from_reference(ref, fname): # Read header of reference hdu = fits.open(ref) hdu[0].header["NAXIS"] = 2 w = wcs.WCS(hdu[0].header) # Check for sidereal tracking # TODO: use fourframe class try: tracked = bool(hdu[0].header['TRACKED']) except KeyError: tracked = False # Get time and position from reference tref = Time(hdu[0].header["MJD-OBS"], format="mjd", scale="utc") pref = SkyCoord(ra=w.wcs.crval[0], dec=w.wcs.crval[1], unit="deg", frame="icrs").transform_to(FK5(equinox=tref)) # Read time from target hdu = fits.open(fname) t = Time(hdu[0].header["MJD-OBS"], format="mjd", scale="utc") # Correct wcs if tracked: dra = 0.0 * u.deg else: dra = (t.sidereal_time("mean", "greenwich") - tref.sidereal_time("mean", "greenwich")) p = FK5(ra=pref.ra + dra, dec=pref.dec, equinox=t).transform_to(ICRS) w.wcs.crval = np.array([p.ra.degree, p.dec.degree]) return w
def __init__(self, ff, mjd, x0, y0): """Define an observation""" # Store self.mjd = mjd self.x0 = x0 self.y0 = y0 # Get times self.nfd = Time(self.mjd, format='mjd', scale='utc').isot # Correct for rotation tobs = Time(ff.mjd + 0.5 * ff.texp / 86400.0, format='mjd', scale='utc') tobs.delta_ut1_utc = 0 hobs = tobs.sidereal_time("mean", longitude=0.0).degree tmid = Time(self.mjd, format='mjd', scale='utc') tmid.delta_ut1_utc = 0 hmid = tmid.sidereal_time("mean", longitude=0.0).degree # Compute ra/dec world = ff.w.wcs_pix2world(np.array([[self.x0, self.y0]]), 1) if ff.tracked: self.ra = world[0, 0] else: self.ra = world[0, 0] + hobs - hmid self.de = world[0, 1]
def test_sidereal_lat_independent(iers_b, kind, jds, lat1, lat2, lon): jd1, jd2 = jds t1 = Time(jd1, jd2, scale="ut1", format="jd", location=(lon, lat1)) t2 = Time(jd1, jd2, scale="ut1", format="jd", location=(lon, lat2)) try: assert_almost_equal(t1.sidereal_time(kind), t2.sidereal_time(kind), atol=1 * u.uas) except iers.IERSRangeError: assume(False)
def JD2LST(self, JD, longitude=None, loc=None): """ use astropy to convert from JD to LST provide either: loc : ephem Observer instance longitude : float, longitude in degrees East """ if loc is not None: t = Time(JD, format="jd") lst = t.sidereal_time('apparent', longitude=loc.lon * 180 / np.pi) elif longitude is not None: t = Time(JD, format="jd") lst = t.sidereal_time('apparent', longitude=longitude) return lst.value
def print_pyephem_parallactic_angle(): lat = 19.826218*u.deg lon = -155.471999*u.deg time = Time('2015-01-01 00:00:00') LST = time.sidereal_time('mean', longitude=lon) desired_HA_1 = 3*u.hourangle desired_HA_2 = 19*u.hourangle # = -5*u.hourangle obs = ephem.Observer() obs.lat = '19:49:34.3848' obs.lon = '-155:28:19.1964' obs.elevation = 0 obs.date = time.datetime pyephem_target1 = ephem.FixedBody() pyephem_target1._ra = ephem.degrees((LST - desired_HA_1).to(u.rad).value) pyephem_target1._dec = ephem.degrees((-30*u.deg).to(u.rad).value) pyephem_target1.compute(obs) pyephem_q1 = (float(pyephem_target1.parallactic_angle())*u.rad).to(u.deg) pyephem_target2 = ephem.FixedBody() pyephem_target2._ra = ephem.degrees((LST - desired_HA_2).to(u.rad).value) pyephem_target2._dec = ephem.degrees((-30*u.deg).to(u.rad).value) pyephem_target2.compute(obs) pyephem_q2 = (float(pyephem_target2.parallactic_angle())*u.rad).to(u.deg) print(pyephem_q1, pyephem_q2) assert (obs.astropy_to_local_time(obs.local_to_astropy_time(dt)).replace( tzinfo=None) == dt)
def on_new_position(self): t = Time(datetime.datetime.utcnow(), scale='utc', location=vancouver_location) t.delta_ut1_utc = 0 sidereal_degrees = t.sidereal_time('mean').degree self.relative_ra_degrees = sidereal_degrees - self.ha_relative_degrees absolute_ra_degrees = self.relative_ra_degrees - self.ra_zero_pos_degrees absolute_dec_degrees = self.relative_dec_degrees - self.dec_zero_pos_degrees c = SkyCoord(ra=absolute_ra_degrees, dec=absolute_dec_degrees, frame='icrs', unit='deg') ra_output = '%dh%02dm%.2fs' % (c.ra.hms) dec_output = '%dd%2d%.1fs' % (c.dec.dms) #output_str = '%s/%s' % (ra_output, dec_output) #c = SkyCoord(ra=absolute_ra_degrees, dec=absolute_dec_degrees, frame='icrs', unit='deg') #ra_output = '%dh%02dm%.2fs' % (c.ra.hms) #dec_output = '%dd%2d%.1fs' % (c.dec.dms) #output_str = '%s/%s' % (ra_output, dec_output) #self.r.publish(messages.STATUS_DISPLAY_CURRENT_RA_DEC, redis_helpers.toRedis(output_str)) self.r.publish( messages.STATUS_DISPLAY_CURRENT_RA_DEC, redis_helpers.toRedis((absolute_ra_degrees, absolute_dec_degrees)))
def check_moon(file, avoid=30. * u.degree): if not isinstance(avoid, u.Quantity): avoid = float(avoid) * u.degree else: avoid = avoid.to(u.degree) header = fits.getheader(file) mlo = EarthLocation.of_site('Keck Observatory') # Update later obstime = Time(header['DATE-OBS'], format='isot', scale='utc', location=mlo) moon = get_moon(obstime, mlo) if 'RA' in header.keys() and 'DEC' in header.keys(): coord_string = '{} {}'.format(header['RA'], header['DEC']) target = SkyCoord(coord_string, unit=(u.hourangle, u.deg)) else: ## Assume zenith target = SkyCoord(obstime.sidereal_time('apparent'), mlo.latitude) moon_alt = moon.transform_to(AltAz(obstime=obstime, location=mlo)).alt.to(u.deg) if moon_alt < 0 * u.degree: print('Moon is down') return True else: sep = target.separation(moon) print('Moon is up. Separation = {:.1f} deg'.format( sep.to(u.degree).value)) return (sep > avoid)
def check_moon(file, avoid=30.*u.degree): if not isinstance(avoid, u.Quantity): avoid = float(avoid)*u.degree else: avoid = avoid.to(u.degree) header = fits.getheader(file) mlo = EarthLocation.of_site('Keck Observatory') # Update later obstime = Time(header['DATE-OBS'], format='isot', scale='utc', location=mlo) moon = get_moon(obstime, mlo) if 'RA' in header.keys() and 'DEC' in header.keys(): coord_string = '{} {}'.format(header['RA'], header['DEC']) target = SkyCoord(coord_string, unit=(u.hourangle, u.deg)) else: ## Assume zenith target = SkyCoord(obstime.sidereal_time('apparent'), mlo.latitude) moon_alt = moon.transform_to(AltAz(obstime=obstime, location=mlo)).alt.to(u.deg) if moon_alt < 0*u.degree: print('Moon is down') return True else: sep = target.separation(moon) print('Moon is up. Separation = {:.1f} deg'.format(sep.to(u.degree).value)) return (sep > avoid)
def gmst2gps(day, GMST, type='mean', iterations=10, precision=1e-14): """ ---------------------------------------------------------------------------- gps=gmst2gps(day, GMST, type='mean', iterations=10, precision=1e-14) returns the GPS time associated with the GMST/GAST on the given day type can be 'mean' or 'apparent' uses a root-find, so not super fast ---------------------------------------------------------------------------- """ assert type in ['mean','apparent'] gmst=Longitude(GMST,unit='h') t=Time(day,scale='utc') iteration=0 siderealday_to_solarday=0.99726958 while iteration < iterations: error=t.sidereal_time(type,'greenwich')-gmst if NP.abs(error/gmst).value <= precision: return t.gps t=t-TimeDelta((error).hour*u.hour)*siderealday_to_solarday iteration+=1 return None
def get_start_time(ra0_deg, length_sec): """Returns optimal start time for field RA and observation length.""" t = Time('2000-01-01 12:00:00', scale='utc', location=('116.764d', '0d')) dt_hours = (24.0 - t.sidereal_time('apparent').hour) / 1.0027379 dt_hours += (ra0_deg / 15.0) start = t + TimeDelta(dt_hours * 3600.0 - length_sec / 2.0, format='sec') return start.value
def local_sidereal_time(self, time, kind='apparent', model=None): if not isinstance(time, Time): time = Time(time) return time.sidereal_time(kind, longitude=self.location.longitude, model=model)
def plot_HAcov(self, plotname='HAcov.png'): """ Show the coverage in HA """ from astropy.coordinates import get_sun, SkyCoord, EarthLocation, AltAz from astropy.time import Time from astropy import units as u telescope = self.mssListObj[0].getTelescope() if telescope == 'LOFAR': telescope_coords = EarthLocation(lat=52.90889 * u.deg, lon=6.86889 * u.deg, height=0 * u.m) elif telescope == 'GMRT': telescope_coords = EarthLocation(lat=19.0948 * u.deg, lon=74.0493 * u.deg, height=0 * u.m) else: raise ('Unknown Telescope.') for ms in self.mssListObj: time = np.mean(ms.getTimeRange()) time = Time(time / 86400, format='mjd') coord_sun = get_sun(time) ra, dec = ms.getPhaseCentre() coord = SkyCoord(ra * u.deg, dec * u.deg) elev = coord.transform_to( AltAz(obstime=time, location=telescope_coords)).alt sun_dist = coord.separation(coord_sun) lst = time.sidereal_time('mean', telescope_coords.longitude) ha = lst - coord.ra # hour angle logger.info( 'Hour angle: %.1f hrs - Elev: %.2f (Sun distance: %.0f)' % (ha.deg / 15., elev.deg, sun_dist.deg))
def sun_position(obs_time): location = EarthLocation(lon=115.2505 * u.deg, lat=42.211833333 * u.deg, height=1365.0 * u.m) solar_system_ephemeris.set('de432s') # GCRS phasecentre = get_body('sun', obs_time, location, ephemeris='jpl') print('SUN: RA:{} Dec:{}'.format(phasecentre.ra.value, phasecentre.dec.value)) # convert phasecentre into ITRS coordinate # ITRF - Alta cAltAz = phasecentre.transform_to( AltAz(obstime=obs_time, location=location)) newAltAzcoordiantes = SkyCoord(alt=cAltAz.alt, az=cAltAz.az, obstime=obs_time, frame='altaz') new_ra_dec = newAltAzcoordiantes.transform_to('icrs') print(new_ra_dec) c_ITRS = phasecentre.transform_to(ITRS(obstime=obs_time, location=location)) local_ha = location.lon - c_ITRS.spherical.lon local_ha.wrap_at(24 * u.hourangle, inplace=True) print("UTC: {} Local Hour Angle: {}".format(obs_time, local_ha.to('deg').value)) obs_time1 = Time(obs_time, scale='utc', location=location) lst = obs_time1.sidereal_time('mean') local_ha1 = lst.to('deg').value - phasecentre.ra.value print("UTC: {} Local Hour Angle: {}".format(obs_time, local_ha1 * u.deg))
def print_pyephem_parallactic_angle(): lat = 19.826218 * u.deg lon = -155.471999 * u.deg time = Time('2015-01-01 00:00:00') LST = time.sidereal_time('mean', longitude=lon) desired_HA_1 = 3 * u.hourangle desired_HA_2 = 19 * u.hourangle # = -5*u.hourangle import ephem obs = ephem.Observer() obs.lat = '19:49:34.3848' obs.lon = '-155:28:19.1964' obs.elevation = 0 obs.date = time.datetime pyephem_target1 = ephem.FixedBody() pyephem_target1._ra = ephem.degrees((LST - desired_HA_1).to(u.rad).value) pyephem_target1._dec = ephem.degrees((-30 * u.deg).to(u.rad).value) pyephem_target1.compute(obs) pyephem_q1 = (float(pyephem_target1.parallactic_angle()) * u.rad).to(u.deg) pyephem_target2 = ephem.FixedBody() pyephem_target2._ra = ephem.degrees((LST - desired_HA_2).to(u.rad).value) pyephem_target2._dec = ephem.degrees((-30 * u.deg).to(u.rad).value) pyephem_target2.compute(obs) pyephem_q2 = (float(pyephem_target2.parallactic_angle()) * u.rad).to(u.deg) print(pyephem_q1, pyephem_q2) assert (obs.astropy_to_local_time( obs.local_to_astropy_time(dt)).replace(tzinfo=None) == dt)
def mjd2ST(t_mjd, lon_deg=-118.283400, lat_deg=37.233386): # Default lat,lon <==> centre of MMA T t = Time(t_mjd, format='mjd', location=(lon_deg * unt.deg, lat_deg * unt.deg)) return t.sidereal_time('apparent').radian
def trajectory(time, lon=-118.3011, lat=28.9733): """ Calculates trayectories for the antenna in a given time. Returns an array of l and b galactic coordinates values in degrees, for a given location. It is asummed that the antenna is looking derectly to the zenit, so in this case the right ascention (RA) is equal to the local sideral time of the location and the declination (DEC) is equal to the latitude. Parameters: time: local time of observation, can be an array or a single time. Prefered format is 'yyyy-mm-dd hh:mm:ss'. WARNING: Make sure that time is in UTC. Optional parameters: lon: Default longitude is given for Isla de Guadalupe at -118.3011 degrees lat: Default latitude is given for Isla de Guadalupe at 28.9733 degrees """ t = Time(time, location=(lon, lat)) RA = np.array(t.sidereal_time('mean').degree) DEC = lat * np.ones(len(RA)) coords = SkyCoord(ra=RA * u.degree, dec=DEC * u.degree) l = coords.galactic.l.degree b = coords.galactic.b.degree return l, b
def get_ha_segments(config_struct,segmentlist,observer,fxdbdy,radec): if "ha_constraint" in config_struct: ha_constraint = config_struct["ha_constraint"].split(",") ha_min = float(ha_constraint[0]) ha_max = float(ha_constraint[1]) else: ha_min, ha_max = -24.0, 24.0 if config_struct["telescope"] == "DECam": if radec.dec.deg <= -30.0: ha_min, ha_max = -5.2, 5.2 else: ha_min, ha_max = -0.644981*np.sqrt(35.0-radec.dec.deg), 0.644981*np.sqrt(35.0-radec.dec.deg) location = astropy.coordinates.EarthLocation(config_struct["longitude"], config_struct["latitude"], config_struct["elevation"]) halist = segments.segmentlist() for seg in segmentlist: mjds = np.linspace(seg[0], seg[1], 100) tt = Time(mjds, format='mjd', scale='utc', location=location) lst = tt.sidereal_time('mean') ha = (lst - radec.ra).hour idx = np.where((ha >= ha_min) & (ha <= ha_max))[0] if len(idx) >= 2: halist.append(segments.segment(mjds[idx[0]],mjds[idx[-1]])) return halist
def test_obs_ra_to_cirs_ra(self): """ This tests that a source with RA = LST and dec = latitude is at the zenith from http://reionization.org/wp-content/uploads/2013/03/HERA_Memo46_lst2ra.html """ from astropy import units from astropy.coordinates import Angle, EarthLocation, SkyCoord from astropy.time import Time # the sidereal time of observation mjd = 55780.1 latitude = Angle('-26d42m11.94986s') longitude = Angle('116d40m14.93485s') obs_time = Time(mjd, format='mjd', location = (longitude, latitude)) lst_apparent = obs_time.sidereal_time('apparent') print('lst_apparent type is %s' % type(lst_apparent.hour)) print('lst_apparent is %f' % lst_apparent.hour) self.assertEqual(lst_apparent.to_string(), '7h11m46.2716s') # convert observed RA (=LST) to CIRS RA cirs_ra = Astronomy.obs_ra_to_cirs_ra(lst_apparent.hour, Time(mjd, format='mjd'), longitude, latitude) print('CIRS RA - observed RA (= LST): %f' % (cirs_ra-lst_apparent.hour)) self.assertAlmostEqual(cirs_ra, 7.1859741) # check that RA=LST, dec=lat is at zenith loc_obj = EarthLocation.from_geodetic(lon=longitude, lat=latitude) obs_zenith_coord = SkyCoord(ra=cirs_ra, dec=latitude, frame='cirs', unit=("hour","deg"), obstime=Time(mjd, format='mjd'), location = loc_obj) obs_zenith_altaz = obs_zenith_coord.transform_to('altaz') obs_ZD = (obs_zenith_altaz.alt - Angle('90d')).to_string(unit=units.degree, sep=('deg', 'm', 's')) self.assertEqual(obs_ZD, '-0deg00m00.5114s')
def write_fits(img, metadata, fitsobj): imgtime = Time(metadata[0][0] + config.inttime*0.5, scale='utc', format='unix', location=(LOFAR_CS002_LONG, LOFAR_CS002_LAT)) imgtime.format='isot' imgtime.out_subfmt = 'date_hms' filename = '%s_S%0.1f_I%ix%i_W%i_A%0.1f.fits' % (imgtime.datetime.strftime("%Y%m%d%H%M%SUTC"), np.mean(subbands), len(subbands), config.inttime, config.window, config.alpha) filename = os.path.join(config.output, filename) if os.path.exists(filename): logger.info("'%s' exists - skipping", filename) return # CRVAL1 should hold RA in degrees. sidereal_time returns hour angle in # hours. fitsobj.header['CRVAL1'] = imgtime.sidereal_time(kind='apparent').value * 15 fitsobj.header['DATE-OBS'] = str(imgtime) imgtime_end = imgtime + TimeDelta(config.inttime, format='sec') fitsobj.header['END_UTC'] = str(imgtime_end) t = Time.now(); t.format = 'isot' fitsobj.header['DATE'] = str(t) fitsobj.data[0, 0, :, :] = img data = img[np.logical_not(np.isnan(img))] quality = rms.rms(rms.clip(data)) high = data.max() low = data.min() fitsobj.header['DATAMAX'] = high fitsobj.header['DATAMIN'] = low fitsobj.header['HISTORY'][0] = 'AARTFAAC 6 stations superterp' fitsobj.header['HISTORY'][1] = 'RMS {}'.format(quality) fitsobj.header['HISTORY'][2] = 'DYNAMIC RANGE {}:{}'.format(int(round(high)), int(round(quality))) fitsobj.writeto(filename) logger.info("%s %0.3f %i:%i", filename, quality, int(round(high)), int(round(quality)))
def test_source_zenith_icrs(): """Test single source position at zenith constructed using icrs.""" array_location = EarthLocation(lat='-30d43m17.5s', lon='21d25m41.9s', height=1073.) time = Time('2018-03-01 00:00:00', scale='utc', location=array_location) freq = (150e6 * units.Hz) lst = time.sidereal_time('apparent') tee_ra = lst cirs_ra = pyuvsim.tee_to_cirs_ra(tee_ra, time) cirs_source_coord = SkyCoord(ra=cirs_ra, dec=array_location.lat, obstime=time, frame='cirs', location=array_location) icrs_coord = cirs_source_coord.transform_to('icrs') ra = icrs_coord.ra dec = icrs_coord.dec zenith_source = pyuvsim.Source('icrs_zen', ra, dec, freq, [1, 0, 0, 0]) zenith_source_lmn = zenith_source.pos_lmn(time, array_location) nt.assert_true( np.allclose(zenith_source_lmn, np.array([0, 0, 1]), atol=1e-5))
def gmst2gps(day, GMST, type='mean', iterations=10, precision=1e-14): """ ---------------------------------------------------------------------------- gps=gmst2gps(day, GMST, type='mean', iterations=10, precision=1e-14) returns the GPS time associated with the GMST/GAST on the given day type can be 'mean' or 'apparent' uses a root-find, so not super fast ---------------------------------------------------------------------------- """ assert type in ['mean', 'apparent'] gmst = Longitude(GMST, unit='h') t = Time(day, scale='utc') iteration = 0 siderealday_to_solarday = 0.99726958 while iteration < iterations: error = t.sidereal_time(type, 'greenwich') - gmst if NP.abs(error / gmst).value <= precision: return t.gps t = t - TimeDelta((error).hour * u.hour) * siderealday_to_solarday iteration += 1 return None
def test_readMiriadwriteMiraid_check_time_format(): """ test time_array is converted properly from Miriad format """ # test read-in fname = os.path.join(DATA_PATH, 'zen.2457698.40355.xx.HH.uvcA') uvd = UVData() uvd.read(fname) uvd_t = uvd.time_array.min() uvd_l = uvd.lst_array.min() uv = aipy_extracts.UV(fname) uv_t = uv['time'] + uv['inttime'] / (24 * 3600.) / 2 lat, lon, alt = uvd.telescope_location_lat_lon_alt t1 = Time(uv['time'], format='jd', location=(lon, lat)) dt = TimeDelta(uv['inttime'] / 2, format='sec') t2 = t1 + dt delta_lst = t2.sidereal_time('apparent').radian - t1.sidereal_time( 'apparent').radian uv_l = uv['lst'] + delta_lst # assert starting time array and lst array are shifted by half integration nt.assert_almost_equal(uvd_t, uv_t) nt.assert_almost_equal(uvd_l, uv_l, delta=1e-8) # test write-out fout = os.path.join(DATA_PATH, 'ex_miriad') uvd.write_miriad(fout, clobber=True) # assert equal to original miriad time uv2 = aipy_extracts.UV(fout) nt.assert_almost_equal(uv['time'], uv2['time']) nt.assert_almost_equal(uv['lst'], uv2['lst']) if os.path.exists(fout): shutil.rmtree(fout)
def convert_hour_angle_to_ra(data, params, pars, single=False): """ Converts right ascension to hour angle and back again """ greenwich = coord.EarthLocation.of_site('greenwich') t = Time(params['ref_geocent_time'], format='gps', location=greenwich) t = t.sidereal_time('mean', 'greenwich').radian # compute single instance if single: return np.remainder(t - data, 2.0 * np.pi) for i, k in enumerate(pars): if k == 'ra': ra_idx = i # Check if RA exist try: ra_idx except NameError: #print('...... RA is fixed. Not converting RA to hour angle.') pass else: # Iterate over all training samples and convert to hour angle for i in range(data.shape[0]): data[i, ra_idx] = np.remainder(t - data[i, ra_idx], 2.0 * np.pi) return data
def get_lst_for_time(jd_array, latitude, longitude, altitude): """ Get the lsts for a set of jd times at an earth location. Args: jd_array: an array of JD times to get lst for latitude: latitude of location to get lst for in degrees longitude: longitude of location to get lst for in degrees altitude: altitude of location to get lst for in meters Returns: an array of lst times corresponding to the jd_array """ lsts = [] lst_array = np.zeros_like(jd_array) for ind, jd in enumerate(np.unique(jd_array)): t = Time(jd, format='jd', location=(Angle(longitude, unit='deg'), Angle(latitude, unit='deg'))) lst_array[np.where( np.isclose(jd, jd_array, atol=1e-6, rtol=1e-12))] = t.sidereal_time('apparent').radian return lst_array
def _get_parang(self, time): t = Time(str(time), location=EarthLocation(lon=self.m_instrument_lon, lat=self.m_instrument_lat)) # Get sideral time in hours sid_time = t.sidereal_time("apparent").value # Convert to degrees sid_time_deg = sid_time * 15. # Calculate hour angle in degrees hour_angle = sid_time_deg - self.m_target_ra # conversion to radians: hour_angle_rad = np.deg2rad(hour_angle) dec_rad = np.deg2rad(self.m_target_dec) lat_rad = np.deg2rad(self.m_instrument_lat) p_angle = np.arctan2(np.sin(hour_angle_rad), (np.cos(dec_rad) * np.tan(lat_rad) - np.sin(dec_rad) * np.cos(hour_angle_rad))) return np.rad2deg(p_angle)
def checkhadec(coordinates, time, mylocation, hadeclims): '''This function checks for compliance to simple hadec mount limits, in a format compliant to the ROS telescopes database table''' #hadeclims = (limdecmin,limdecmax,limharise,limhaset) observable = 1 #objaltaz = coordinates.transform_to(astropy.coordinates.AltAz(time), location=mylocation) loctime = Time(time, location=mylocation) LST = loctime.sidereal_time("apparent") LHA = coordinates.ra + LST #testing for a valid hour angle if LHA >= 24 * u.hourangle or LHA < 0 * u.hourangle: #print ("hour angle overflow",LHA) LHA = LHA - 24 * u.hourangle #print ("corrected:",LHA) #Testing if object is in hadec blind spot if LHA >= hadeclims[2] * u.deg and LHA <= hadeclims[3] * u.deg: observable = 0 print("Object HA below limits", LHA) return observable if coordinates.dec <= hadeclims[0] * u.deg: observable = 0 print("Object DEC below limits=================================", coordinates.dec) return observable if coordinates.dec >= hadeclims[1] * u.deg: observable = 0 print("Object DEC over limits==================================", coordinates.dec) return observable return observable
def append_altaz(stats_file, img_file_dir): mauna_kea = EarthLocation(lat=19.8206 * u.deg, lon=-155.4681 * u.deg, height=4207 * u.m) # Read in stats table and image files in that table stats_table = Table.read(stats_file) img_files = stats_table['Image'] # Make some empty columns for new data az = np.zeros(len(img_files), dtype=float) alt = np.zeros(len(img_files), dtype=float) HA = [] # Calculate new data from each header for ii in range(len(img_files)): file = img_file_dir + img_files[ii].split("/")[-1] # Read in header data data, hdr = fits.getdata(file, header=True) DEC = hdr['DEC'] RA = hdr['RA'] UTIM = hdr['UTIME'] date = hdr['DATEOBS'] # Define observation parameters time = Time(date[6:] + "-" + date[0:2] + "-" + date[3:5] + " " + UTIM, scale='utc', location=mauna_kea) mauna_kea = EarthLocation(lat=19.8206 * u.deg, lon=-155.4681 * u.deg, height=4207 * u.m) c = SkyCoord(RA * u.hour, DEC * u.deg) # Calculate Alt/Az coordinates (both output in degrees) alt_az = c.transform_to(AltAz(obstime=time, location=mauna_kea)) string = alt_az.to_string('decimal').split(" ") az[ii] = string[0] alt[ii] = string[1] # Calculate local sidereal time and hour angle: lst = time.sidereal_time('apparent') hour_angle = lst - c.ra HA.append(hour_angle.to_string("hour")) HA = np.array(HA) # Make columns to append to table col_az = Column(name='AZ', data=az) col_alt = Column(name='ALT', data=alt) col_HA = Column(name='HA', data=HA) stats_table.add_columns([col_az, col_alt, col_HA]) stats_file_root, stats_file_ext = os.path.splitext(stats_file) stats_table.write(stats_file_root + '_altaz' + stats_file_ext, overwrite=True) return
def setairmass(inim, obs, ra, dec): """ setairmass -- update image headers with the effective airmass obs -- SAO1-m : "sao" ra -- target ra hh:mm:ss dec -- target dec dd:mm:ss location -- Put your observatory information. *** Hourly airmass for Feige 56 *** Epoch 2000.00: RA 12 06 47.3, dec 11 40 13 Epoch 2019.35: RA 12 07 46.6, dec 11 33 45 At midnight: UT date 2019 May 10, Moon 0.33 illum, 59 degr from obj Local UT LMST HA secz par.angl. SunAlt MoonAlt 22 00 11 00 10 40 -1 28 1.186 -33.6 -6.3 52.1 23 00 12 00 11 40 -0 28 1.119 -12.4 -16.3 40.7 0 00 13 00 12 40 0 32 1.121 14.2 ... 29.1 1 00 14 00 13 40 1 32 1.194 34.7 ... 17.7 2 00 15 00 14 40 2 33 1.363 46.2 ... 6.6 3 00 16 00 15 40 3 33 1.701 51.8 ... ... 4 00 17 00 16 41 4 33 2.436 53.9 ... ... 5 00 18 00 17 41 5 33 4.691 53.8 ... ... 6 00 19 00 18 41 6 33 (v.low) 51.8 -15.8 ... 7 00 20 00 19 41 7 33 (down) 47.9 -5.7 ... """ import glob import os, sys from pyraf import iraf from astropy.time import Time from astropy.io import fits from astropy import units as u hdr = fits.getheader(inim) t = Time(hdr['date-obs'], format='isot', scale='utc', location=(126.95333299999999 * u.deg, 37.45704167 * u.deg, 190 * u.m)) st = t.sidereal_time('apparent') # in hourangle set_observatory(obs) st_hms = str(int(st.hms.h)).zfill(2) + ':' + str(int( st.hms.m)).zfill(2) + ':' + str(int(st.hms.s)).zfill(2) iraf.hedit(images=inim, fields='st', value=st_hms, add='yes', verify='yes') iraf.hedit(images=inim, fields='ra', value=ra, add='yes', verify='yes') iraf.hedit(images=inim, fields='dec', value=dec, add='yes') print('OK.') iraf.astutil() iraf.setairmass(images=inim, observatory=obs, equinox='epoch', date="date-obs", exposure="exptime", airmass="airmass", show='yes', ut="date-obs", override='yes')
def radec2altaz(ra, dec, obstime, lat=None, long=None, debug=False): """ calculates the altitude and azimuth, given an ra, dec, time, and observatory location :param ra: right ascension of the target (in degrees) :param dec: declination of the target (in degrees) :param obstime: an astropy.time.Time object containing the time of the observation. Can also contain the observatory location :param lat: The latitude of the observatory. Not needed if given in the obstime object :param long: The longitude of the observatory. Not needed if given in the obstime object :return: """ if lat is None: lat = obstime.lat.degree if long is None: long = obstime.lon.degree obstime = Time(obstime.isot, format='isot', scale='utc', location=(long, lat)) # Find the number of days since J2000 j2000 = Time("2000-01-01T12:00:00.0", format='isot', scale='utc') dt = (obstime - j2000).value # number of days since J2000 epoch # get the UT time tstring = obstime.isot.split("T")[-1] segments = tstring.split(":") ut = float(segments[0]) + float(segments[1]) / 60.0 + float(segments[2]) / 3600 # Calculate Local Sidereal Time lst = obstime.sidereal_time('mean').deg # Calculate the hour angle HA = lst - ra while HA < 0.0 or HA > 360.0: s = -np.sign(HA) HA += s * 360.0 # convert everything to radians dec *= np.pi / 180.0 ra *= np.pi / 180.0 lat *= np.pi / 180.0 long *= np.pi / 180.0 HA *= np.pi / 180.0 # Calculate the altitude alt = np.arcsin(np.sin(dec) * np.sin(lat) + np.cos(dec) * np.cos(lat) * np.cos(HA)) # calculate the azimuth az = np.arccos((np.sin(dec) - np.sin(alt) * np.sin(lat)) / (np.cos(alt) * np.cos(lat))) if np.sin(HA) > 0: az = 2.0 * np.pi - az if debug: print "UT: ", ut print "LST: ", lst print "HA: ", HA * 180.0 / np.pi return alt * 180.0 / np.pi, az * 180.0 / np.pi
def main(): parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--ra', type=float, default=25.0, help='Right Ascension (degrees)') parser.add_argument('--dec', type=float, default=12.0, help='Declination (degrees)') parser.add_argument('--mjd', type=float, default=55000.0, help='Modified Julien Date (days)') parser.add_argument('--scan-offset', type=float, default=15.0, help='Scan offset (hours)') parser.add_argument('--scan-width', type=float, default=4.0, help='Scan width (hours)') parser.add_argument('--scan-steps', type=int, default=100, help='Number of sampling points') parser.add_argument('--astropy-apo', action='store_true', help='User apo observatory from astropy') args = parser.parse_args() if args.astropy_apo: sdss = EarthLocation.of_site('apo') else: sdss = EarthLocation(lat=32.7797556*u.deg, lon=-(105+49./60.+13/3600.)*u.deg, height=2797*u.m) coord = SkyCoord(ra=args.ra*u.degree, dec=args.dec*u.degree, frame='icrs') # scan of time hours = args.scan_offset + np.linspace(-0.5*args.scan_width, 0.5*args.scan_width, args.scan_steps) my_alt = np.zeros((hours.size)) py_alt = np.zeros((hours.size)) py_ha = np.zeros((hours.size)) for i in range(hours.size): mjd_value = args.mjd*u.day + hours[i]*u.hour time = Time(val=mjd_value, scale='tai', format='mjd', location=sdss) # altitude from astropy py_alt[i] = coord.transform_to(AltAz(obstime=time, location=sdss)).alt.to(u.deg).value # this is supposed to be the hour angle from astropy py_ha[i] = time.sidereal_time('apparent').to(u.deg).value - args.ra # simple rotation to get alt,az based on ha my_alt[i], az = hadec2altaz(py_ha[i], args.dec, sdss.latitude.to(u.deg).value) print hours[i], py_ha[i], py_alt[i], my_alt[i] py_ha = np.array(map(normalize_angle, py_ha.tolist())) ii = np.argsort(py_ha) py_ha=py_ha[ii] py_alt=py_alt[ii] my_alt=my_alt[ii] fig = plt.figure(figsize=(8,6)) plt.plot(py_ha, py_alt - my_alt, 'o', c='b') plt.title('Compare hadec2altaz') # plt.title('(ra,dec) = (%.2f,%.2f)' % (args.ra, args.dec)) plt.xlabel('Hour Angle [deg]') plt.ylabel('astropy_alt - rotation_alt [deg]') plt.grid(True) plt.show()
def ra2ha(ra): """ convert right ascension to hour angle at the current time """ ra = Angle(ra, u.hourangle) utc_now = Time(datetime.utcnow(), scale='utc', location=SITE_LOCATION) lst = utc_now.sidereal_time('apparent') return (lst - ra).wrap_at(12 * u.hourangle)
def ha2ra(ha): """ convert hour angle to right ascension at the current time """ ha = Angle(ha, u.hourangle) utc_now = Time(datetime.utcnow(), scale='utc', location=SITE_LOCATION) lst = utc_now.sidereal_time('apparent') return (lst - ha).wrap_at(24 * u.hourangle)
def sunset_time(a = -12): phi = 33.7485 l = 51.4257 now = datetime.datetime.now() t = Time(Time.now(), scale='utc', location = (str(l) + 'd', str(phi) + 'd')) ra, dec = get_sun(t).ra.deg, get_sun(t).dec.deg ST = t.sidereal_time('apparent').hour * 15 H_now = ST - ra H_set = degrees(acos((sin(radians(a))-sin(radians(phi) * sin(radians(dec)))) / (cos(radians(phi)) * cos(radians(dec))))) delta = H_set - H_now return now.hour + now.minute / 60 + now.second / 3600 + delta / 15
def set_lsts_from_time_array(self): """Set the lst_array based from the time_array.""" lsts = [] curtime = self.time_array[0] for ind, jd in enumerate(self.time_array): if ind == 0 or not np.isclose(jd, curtime, atol=1e-6, rtol=1e-12): curtime = jd latitude, longitude, altitude = self.telescope_location_lat_lon_alt_degrees t = Time(jd, format='jd', location=(longitude, latitude)) lsts.append(t.sidereal_time('apparent').radian) self.lst_array = np.array(lsts)
def main(): """ This script performs distortion correction and centering. See the script description for detail. """ #Read in the coordinates of the image center try: file = open(p.data_cal + 'center.txt', "r") except (FileNotFoundError): print( 'center.txt is not found. Position calibration is not performed.') return center = ast.literal_eval(file.read()) file.close() center_ra = center['ra'] center_de = center['dec'] ori = round(center['orientation'], 1) #Compute zenith RA and Dec based on the observing location and time hdu = fits.open(p.data_cal + p.reference, fix=False) time = Time(hdu[0].header['DATE-OBS']) #UTC observing date and time hdu.close() zenith_ra = time.sidereal_time('mean', longitude=p.long).degree zenith_de = p.lat #Compute the offset of the image centroid dab = DistanceAndBearing(center_de, center_ra, zenith_de, zenith_ra) offset_distance = round(90 - dab[0], 2) offset_bearing = dab[1] print(f'Zenith is offset from the center by {offset_distance} degrees') #Mask - read in the fisheye mask center coordinates and radius mask = fits.open(p.mask, uint=False)[0].header xc, yc = mask['CENTERX'], mask['CENTERY'] #Position calibration for f in glob(p.data_cal + '*sky*.fit'): image = fits.open(f, uint=False, mode='update') #correct for fisheye lens distorsion - need to be implemented pass #align image centroid with the zenith - need to be implemented pass #correct for orientation; put north up imgdata = image[0].data.astype('float32') image[0].data = rotate(imgdata, ori, center=(xc, yc), mode='edge') image[0].header['history'] = f'Image is rotated by {ori} degrees' image[0].header['history'] = f'Image is processed by {p.processor}' image.flush() image.close()
def get_sid_trans(date, longitude): '''Initialize matplotlib transform for local time - sidereal time conversion''' midnight = Time(date) #midnight UTC sidmid = midnight.sidereal_time('mean', longitude) #offset from local time offset = sidmid.hour / 24 #used to convert to origin of plot_date coordinates p0 = midnight.plot_date #A mean sidereal day is 23 hours, 56 minutes, 4.0916 seconds (23.9344699 hours or 0.99726958 mean solar days) scale = 366.25 / 365.25 return Affine2D().translate(-p0, 0).scale(scale).translate(p0 + offset, 0)
def Sidereal(value):#overall gps time ti sidereal time result= float() tunix = value +315964800 # gps time to unix time hour = Time(tunix, format='unix', location=('-68.131389', '-16.353333')) # defines object "hour" needed in astropy Side = str( hour.sidereal_time('mean') ) #trasform to sidereal time if Side[1]=='h': A = Side result = (float(A[0])*3600)+(float(A[2:4])*60)+(float(A[5:7])) if Side[2]=='h': A = Side result = (float(A[0:2])*3600)+(float(A[3:5])*60)+(float(A[6:8])) return int(result)
def examine_exposure(info, cframe, cframe_keys): # Process CFrame header keywords for keyword in cframe_keys: info[keyword] = cframe.header[keyword] obs_ra = cframe.header['RADEG'] obs_dec = cframe.header['DECDEG'] taibeg = cframe.header['TAI-BEG'] taiend = cframe.header['TAI-END'] taimid = 0.5*(taibeg+taiend) dec = Angle(obs_dec, u.degree) ra = Angle(obs_ra, u.degree) time = Time(taimid/86400.0, format='mjd', scale='tai', location=apo) try: lst = time.sidereal_time('apparent') except IndexError: ## workaround for problem with recent observations relative to astropy release ## http://astropy.readthedocs.org/en/v0.4.2/time/index.html#transformation-offsets from astropy.utils.iers import IERS_A, IERS_A_URL from astropy.utils.data import download_file iers_a_file = download_file(IERS_A_URL, cache=True) iers_a = IERS_A.open(iers_a_file) time.delta_ut1_utc = time.get_delta_ut1_utc(iers_a) lst = time.sidereal_time('apparent') ha = (lst - ra) if ha > np.pi*u.radian: ha -= 2*np.pi*u.radian elif ha < -np.pi*u.radian: ha += 2*np.pi*u.radian info['mean_ha'] = ha.to(u.degree).value alt, az = equatorial_to_horizontal(ra, dec, apolat, ha) info['mean_alt'] = alt.to(u.degree).value
def __init__(self,ff,mjd,x0,y0): """Define an observation""" # Store self.mjd=mjd self.x0=x0 self.y0=y0 # Get times self.nfd=Time(self.mjd,format='mjd',scale='utc').isot # Correct for rotation tobs=Time(ff.mjd+0.5*ff.texp/86400.0,format='mjd',scale='utc') tobs.delta_ut1_utc=0 hobs=tobs.sidereal_time("mean",longitude=0.0).degree tmid=Time(self.mjd,format='mjd',scale='utc') tmid.delta_ut1_utc=0 hmid=tmid.sidereal_time("mean",longitude=0.0).degree # Compute ra/dec world=ff.w.wcs_pix2world(np.array([[self.x0,self.y0]]),1) self.ra=world[0,0]+hobs-hmid self.de=world[0,1]
def set_lsts_from_time_array(uvd): lsts = [] curtime = uvd.time_array[0] for ind, jd in enumerate(uvd.time_array): if ind == 0 or not np.isclose(jd, curtime, atol=1e-6, rtol=1e-12): # print 'Curtime/jd: ', curtime, jd curtime = jd latitude, longitude, altitude = uvd.telescope_location_lat_lon_alt_degrees # print 'Loc: ', latitude, longitude, altitude t = Time(jd, format='jd', location=(longitude, latitude)) # print 't: ', t t.delta_ut1_utc = iers_a.ut1_utc(t) # print 't.delta_ut1_utc: ', t.delta_ut1_utc print "LST: ", t.sidereal_time('apparent') lsts.append(t) return lsts
def test_add_obs(self): t1 = Time('2016-01-10 01:15:23', scale='utc') t2 = t1 + TimeDelta(120.0, format='sec') # t1.delta_ut1_utc = mc.iers_a.ut1_utc(t1) # t2.delta_ut1_utc = mc.iers_a.ut1_utc(t2) from math import floor obsid = floor(t1.gps) t1.location = EarthLocation.from_geodetic(observations.HERA_LON, observations.HERA_LAT) expected = [observations.Observation(obsid=obsid, start_time_jd=t1.jd, stop_time_jd=t2.jd, lst_start_hr=t1.sidereal_time('apparent').hour)] self.test_session.add(observations.Observation.new_with_astropy(t1, t2)) result = self.test_session.get_obs() self.assertEqual(result, expected)
def test_parallactic_angle(): """ Compute parallactic angle for targets at hour angle = {3, 19} for at observer at IRTF using the online SpeX calculator and PyEphem """ # Set up position for IRTF lat = 19.826218*u.deg lon = -155.471999*u.deg elevation = 4160.0 * u.m location = EarthLocation.from_geodetic(lon, lat, elevation) time = Time('2015-01-01 00:00:00') LST = time.sidereal_time('mean', longitude=lon) desired_HA_1 = 3*u.hourangle desired_HA_2 = 19*u.hourangle # = -5*u.hourangle target1 = SkyCoord(LST - desired_HA_1, -30*u.degree) target2 = SkyCoord(LST - desired_HA_2, -30*u.degree) obs = Observer(location=location) q1 = obs.parallactic_angle(time, target1) q2 = obs.parallactic_angle(time, target2) q12 = obs.parallactic_angle(time, [target1, target2]) # Get values from PyEphem for comparison from print_pyephem_parallactic_angle() pyephem_q1 = 46.54610060782033*u.deg pyephem_q2 = -65.51818282032019*u.deg assert_allclose(q1.to(u.degree).value, pyephem_q1, atol=1) assert_allclose(q2.to(u.degree).value, pyephem_q2, atol=1) # Get SpeX parallactic angle calculator values for comparison from # http://irtfweb.ifa.hawaii.edu/cgi-bin/spex/parangle.cgi to produce SpeX_q1 = 46.7237968 # deg SpeX_q2 = -65.428924 # deg assert_allclose(q1.to(u.degree).value, SpeX_q1, atol=0.1) assert_allclose(q2.to(u.degree).value, SpeX_q2, atol=0.1) assert q1 == q12[0] assert q2 == q12[1]
class aoSession: """ srcs_file: name of ASCII file with the following columns: (1) source names as they appear in the catalogue file (cat_file) (2) number of seconds to observe this source (3) "fold" or "search" to choose observing mode (4) "LWide" or "430MHz" to choose a receiever (5) path to parfile (only needed if mode is "fold") (assumed to be /home/gpu/tzpar/[NAME].par if needed and missing) cat_file: name of the CIMA catalogue file sources are being read from for this session. start_date: date of start time (AST) in "YYYY-MM-DD" format start_time: start time (AST) in "HH:MM" or "HH:MM:SS" format obslen_hr: total length of session in decimal hours stepsize_sec: the altitude and azimuth are calculated every stepsize_sec seconds """ def __init__(self, srcs_file, cat_file, start_date, start_time, obslen_hr, stepsize_sec=10): self.srcs_file = srcs_file self.cat_file = cat_file self.stepsize_sec = stepsize_sec self.time_steps = np.arange(0, obslen_hr, stepsize_sec/3600.)*u.hour self.start_time = Time("%sT%s" % (start_date, start_time), \ format='isot') + 4.*u.hour self.start_time.delta_ut1_utc = 0 self.obslen_hr = obslen_hr self.obslen_sec = int(obslen_hr*3600) self.altaz_frame = AltAz(obstime=self.start_time+self.time_steps,\ location=ao) self.plan = [] src_names = [] src_nsecs = [] src_modes = [] src_recvs = [] src_parfs = [] with open(srcs_file, 'r') as f: for line in f.readlines(): if line[0] != "#": split_line = line.split() if len(split_line) >= 4: src_name = split_line[0] src_names.append(src_name) src_nsecs.append(int(split_line[1])) mode = split_line[2].lower() if mode in ["search", "fold"]: src_modes.append(mode) else: raise ValueError("Mode input was '%s', must be"\ " 'search' or 'fold'." % mode) recv = split_line[3].lower() if recv in ["lwide", "430mhz"]: src_recvs.append(recv) else: raise ValueError("Receiver input was '%s', must"\ " be 'LWide' or '430MHz'." % recv) if len(split_line) >= 5: src_parfs.append(split_line[4]) else: src_parfs.append("/home/gpu/tzpar/%s.par"%src_name) src_ras = {} src_decs = {} with open(cat_file, 'r') as f: for line in f.readlines(): split_line = line.split() if len(split_line) >= 3: cat_name = split_line[0] if cat_name in src_names: src_ras[cat_name] = split_line[1] src_decs[cat_name] = split_line[2] self.sources = [] for ii,src in enumerate(src_names): self.sources.append(aoSource(src, src_ras[src], src_decs[src], \ src_nsecs[ii], src_modes[ii], src_recvs[ii], self.altaz_frame, \ src_parfs[ii], stepsize_sec)) def get_seconds_visible(self, time, absolute_time=False): seconds = [] for ii,src in enumerate(self.sources): seconds.append(src.get_seconds_visible(time, absolute_time)) return np.array(seconds) def plot_sources(self, time, absolute_time=False, ax=None): bgcolor = '0.9' gridlines_color = 'white' if ax is None: fig = plt.figure(figsize=(10,10)) ax = fig.add_subplot(111) ax.set_xlim(25, -25) ax.set_ylim(-25, 25) ax.set_xticks([]) ax.set_yticks([]) ax.set_axis_bgcolor(bgcolor) if absolute_time: ax.set_title(time) else: ax.set_title("%.1f minutes into session" % (time/60.)) # Let's make a few equatorial coordinate lines dec_lines = [-10, 0, 10, 20, 30, 40, 50] ra_offs_lines = [-2, -1, 0, 1, 2] if not absolute_time: actual_time = self.start_time + time*u.second actual_time.delta_ut1_utc = 0 else: actual_time = time sidereal_time = actual_time.sidereal_time('mean', ao.longitude) dec_lines_altaz_frame = AltAz(obstime=actual_time+\ np.linspace(-3, 3, 100)*u.hour, location=ao) ra_lines_altaz_frame = AltAz(obstime=actual_time, location=ao) for dec in dec_lines: line_coords = SkyCoord(ra=sidereal_time, dec=dec, \ unit=('hourangle', 'degree')) line_altaz = line_coords.transform_to(dec_lines_altaz_frame) line_az = line_altaz.az.rad line_za = 90. - line_altaz.alt.degree line_x = -line_za*np.sin(line_az) line_y = line_za*np.cos(line_az) ax.plot(line_x, line_y, c=gridlines_color, lw=2, zorder=-10) for ra_offs in ra_offs_lines: offset_time = actual_time+ra_offs*u.hour offset_time.delta_ut1_utc = 0 sidereal_time = offset_time.sidereal_time('mean', ao.longitude) line_coords = SkyCoord(ra=sidereal_time, \ dec=np.linspace(dec_lines[0], dec_lines[-1], 100), \ unit=('hourangle', 'degree')) line_altaz = line_coords.transform_to(ra_lines_altaz_frame) line_az = line_altaz.az.rad line_za = 90. - line_altaz.alt.degree line_x = -line_za*np.sin(line_az) line_y = line_za*np.cos(line_az) ax.plot(line_x, line_y, c=gridlines_color, lw=2, zorder=-10) ax.add_patch(Wedge((0,0), za_max, 0, 360, width=za_max-za_min, \ facecolor=(1, 1, 1, 0.5))) src_names = set() for src in self.sources: if src.name not in src_names: tick = src.get_tick_from_time(time, absolute_time) az_rad = src.altaz.az.rad za = src.get_za() xc = -za*np.sin(az_rad) yc = za*np.cos(az_rad) ax.plot(xc, yc, ':', c='black') ax.plot(xc[tick], yc[tick], 'o', c='purple') src_names.add(src.name) def create_plan(self, verbose=True, make_plot=True): self.plan = [] done = set() t = 0 az_starts = [] za_starts = [] az_ends = [] za_ends = [] ra_order = [] dec_order = [] ra_hr = np.array([src.pos.ra.hour for src in self.sources]) st_hr = self.start_time.sidereal_time('mean', ao.longitude).hour ha = (st_hr-ra_hr) ha[ha > 12] -= 24. hour_order = np.argsort(ha)[::-1] sec_needed = np.array([src.get_seconds_needed() for src in self.sources]) ra_hours = np.array([src.pos.ra.hour for src in self.sources]) # assume initial slew is two minutes slew_times = np.array([120]*len(self.sources)) on_source_sec_remaining = sec_needed.sum() while len(done) < len(self.sources): num_left = len(self.sources) - len(done) enough_time = True #if verbose: # print "[%.2f min] Off-source seconds available: %d" % \ # (t/60., (self.obslen_sec - t) - on_source_sec_remaining) sec_visible = [] total_sec_remaining = [] sec_to_last_seen = [] for ii,src in enumerate(self.sources): sec_visible.append(src.get_seconds_visible(t+slew_times[ii])) total_sec_remaining.append(src.get_total_seconds_remaining(t+\ slew_times[ii])) sec_to_last_seen.append(src.get_seconds_to_last_seen(t+\ slew_times[ii])) sec_visible = np.array(sec_visible) total_sec_remaining = np.array(total_sec_remaining) sec_to_last_seen = np.array(sec_to_last_seen) if not total_sec_remaining.any(): break options = [] for ii in np.where(sec_visible > sec_needed+slew_times)[0]: if ii not in done and slew_times[ii] >= 0: options.append(ii) if not len(options) and num_left == 1: ii_left = set(range(len(self.sources))).difference(done).pop() options.append(ii_left) enough_time = False options = np.array(options) if len(options): wiggle_room = sec_to_last_seen - sec_needed - slew_times this_source = options[np.argmin(wiggle_room[options]**3 * \ slew_times[options])] if verbose: print "[%.2f min] Of %d option%s, picked %s, %d left"\ " (%d sec slew)" % (t/60., len(options), \ ['','s'][bool(len(options)-1)], \ self.sources[this_source].name, \ len(self.sources)-len(done)-1, slew_times[this_source]) self.plan.append(this_source) t += slew_times[this_source] tick = self.sources[this_source].get_tick_from_time(t) az_starts.append(self.sources[this_source].altaz.az.degree[tick]) za_starts.append(self.sources[this_source].get_za()[tick]) t += sec_needed[this_source] tick = self.sources[this_source].get_tick_from_time(t) az_ends.append(self.sources[this_source].altaz.az.degree[tick]) za_ends.append(self.sources[this_source].get_za()[tick]) ra_order.append(self.sources[this_source].pos.ra.hour) dec_order.append(self.sources[this_source].pos.dec.degree) on_source_sec_remaining -= sec_needed[this_source] done.add(this_source) else: if verbose: print "[%.2f min] Nothing to pick, moving ahead by %d"\ " seconds..." % (t/60., self.stepsize_sec) t += self.stepsize_sec try: # This is sloppily placed in a try-except since there's no # "this_source" if nothing is found on the first try. However, # it makes sense for "this_source" to remain the same and for # slew times to be updated if nothing is found later. # NOTE it would maybe also make sense to add observing time to # current pulsar instead of doing nothing, though this could be # sensitive to details of the real run slew_times = np.array( [src.slew_time_from(self.sources[this_source], t) \ for src in self.sources] ) except: if verbose: print "Unable to update slew times." self.plan = np.array(self.plan) if verbose: print "Total time: %.2f h" % (t / 3600.) print "Start time:", self.start_time - 4.*u.hour print "End time:", self.start_time - 4.*u.hour + t*u.second num_missed = len(self.sources) - len(done) if num_missed: print "Missing %d pulsar%s!" % \ (num_missed, ['','s'][bool(num_missed-1)]) if not enough_time: print "Not enough time to finish last source!" if make_plot: az_starts = np.array(az_starts) za_starts = np.array(za_starts) az_ends = np.array(az_ends) za_ends = np.array(za_ends) ra_order = np.array(ra_order) dec_order = np.array(dec_order) fig = plt.figure(figsize=(10,10)) ax = fig.add_subplot(111) ax.set_xlim(25, -25) ax.set_ylim(-25, 25) ax.set_xticks([]) ax.set_yticks([]) ax.set_axis_bgcolor('0.9') self.plot_sources(0, absolute_time=False, ax=ax) az_starts_rad = az_starts * np.pi/180. az_ends_rad = az_ends * np.pi/180. x_starts = -za_starts*np.sin(az_starts_rad) y_starts = za_starts*np.cos(az_starts_rad) x_ends = -za_ends*np.sin(az_ends_rad) y_ends = za_ends*np.cos(az_ends_rad) for ii in range(len(x_starts)): ax.plot([x_starts[ii], x_ends[ii]], [y_starts[ii], y_ends[ii]], '-', c='blue') if ii < len(x_starts)-1: ax.plot([x_ends[ii], x_starts[ii+1]], [y_ends[ii], y_starts[ii+1]], '-', c='orange') ax.plot(x_starts, y_starts, 'o', c='blue') ax.plot(x_ends, y_ends, 's', c='orange') t_start = (self.start_time - 4.*u.hour).datetime title_A = t_start.strftime("%Y %b %d %H:%M:%S - ") t_end = (self.start_time - 4.*u.hour + t*u.second).datetime title_B = t_end.strftime("%H:%M:%S ") title_C = "(%.2f hours)" % (t / 3600.) ax.set_title(title_A + title_B + title_C) plt.show() def make_cmd_file(self, fname=None): """ If fname=None, just print to screen. """ if not len(self.plan): print "No observing plan found--generating one." self.create_plan(False, False) search_lwide = "LOAD PUPPI_LWide_CIMA_Inc_Search.conf\nEXEC change_puppi_scales \"set\" \"04000000\"\n" fold_lwide = "LOAD PUPPI_LWide_coherent.conf\nEXEC change_puppi_scales \"set\" \"00800000\"\n" fold_430mhz = "LOAD puppi_430MHz_coherent.conf\nEXEC change_puppi_scales \"set\" \"00400000\"\n" search_setup = "SETUP pulsaron secs = %d loops = 1 caltype = nocal calsecs = %d calmode = on winkcal = off winkcaltype = lcorcal adjpwr = never newfile = one\n" fold_setup = "SETUP pulsaron secs = %d loops = 1 caltype = winkcal calsecs = %d calmode = on winkcal = off winkcaltype = lcorcal adjpwr = never newfile = one\n" cmd_str = "" cmd_str += "CATALOG %s\n\n" % self.cat_file src = self.sources[self.plan[0]] current_mode = src.mode current_recv = src.receiver if current_mode == "search": if current_recv == "430mhz": raise ValueError("430MHz search mode not supported.") elif current_recv == "lwide": cmd_str += search_lwide + "\n" else: raise ValueError("Unknown receiver %s" % current_recv) setup_str = search_setup #cmd_str += search_setup % (src.nsec, cal_times["search"]) elif current_mode == "fold": if current_recv == "430mhz": cmd_str += fold_430mhz + "\n" elif current_recv == "lwide": cmd_str += fold_lwide + "\n" else: raise ValueError("Unknown receiver %s" % current_recv) setup_str = fold_setup #cmd_str += fold_setup % (src.nsec, cal_times["fold"]) else: raise ValueError("Unknown mode %s" % current_mode) cmd_str += setup_str % (src.nsec, cal_times[current_mode]) cmd_str += "SEEK %s\n" % src.name if current_mode == "fold": cmd_str += "EXEC change_puppi_parfile \"%s\"\n" % (src.parfile_path) cmd_str += "ADJUSTPOWER\nADJUSTPOWER\n" cmd_str += "EXEC wait_puppi_temporary \"180\" \"Verify PUPPI power levels using 'guppi_adc_hist' in the puppimaster terminal\"\n" cmd_str += "PULSARON\n\n" for ii in range(1, len(self.plan)): src = self.sources[self.plan[ii]] if src.mode != current_mode or src.receiver != current_recv: current_mode = src.mode current_recv = src.receiver if current_mode == "search": if current_recv == "430mhz": raise ValueError("430MHz search mode not supported.") elif current_recv == "lwide": cmd_str += search_lwide else: raise ValueError("Unknown receiver %s" % current_recv) setup_str = search_setup elif current_mode == "fold": if current_recv == "430mhz": cmd_str += fold_430mhz elif current_recv == "lwide": cmd_str += fold_lwide else: raise ValueError("Unknown receiver %s" % current_recv) setup_str = fold_setup else: raise ValueError("Unknown mode %s" % current_mode) cmd_str += "ADJUSTPOWER\n\n" cmd_str += "SEEK %s\n" % src.name if current_mode == "fold": cmd_str += "EXEC change_puppi_parfile \"%s\"\n" % \ (src.parfile_path) cmd_str += setup_str % (src.nsec, cal_times[current_mode]) cmd_str += "PULSARON\n\n" cmd_str += "LOG \"LBand Observation Completed.\"\n" if fname is None: print "# Command file begins below:" print "" print cmd_str else: with open(fname, 'w') as f: f.write(cmd_str) print "Wrote %s" % fname
def test_adjust_null(): ra = 45 * u.deg when = Time(56383, format='mjd', location=observatories['APO']) ha = when.sidereal_time('apparent') - ra adjusted = adjust_time_to_hour_angle(when, ra, ha) assert adjusted == when
) # o.add_option('--plot',dest='plot',default=False, action='store_true',\ # help='Outputs plot to X-Window and saves plot') opts, args = o.parse_args(sys.argv[1:]) # start by assuming things are lst aligned (they aren't) filename = args[0] pol_A = opts.pols.split(",")[0] print "reading", filename t_A, dat_A, flg_A = get_dict_of_uv_data([filename], opts.ant, pol_A, verbose=opts.v) bls_A = dat_A.keys() uv = a.miriad.UV(filename) aa = a.cal.get_aa(opts.cal, uv["sdf"], uv["sfreq"], uv["nchan"]) freqs_A = aa.get_afreqs() t_A = Time(t_A, scale="utc", format="jd", location=(aa.lat, aa.long)) lst_A = t_A.sidereal_time("apparent") if len(bls_A) == 0: print "no data found in file ", filename[0] sys.exit() D_A = n.ma.masked_where([flg_A[bl][pol_A] for bl in bls_A], [dat_A[bl][pol_A] for bl in bls_A]) filename = args[1] print "reading", filename pol_B = opts.pols.split(",")[1] t_B, dat_B, flg_B = get_dict_of_uv_data([filename], opts.ant, pol_B, verbose=opts.v) bls_B = dat_B.keys() uv = a.miriad.UV(filename) aa = a.cal.get_aa(opts.cal, uv["sdf"], uv["sfreq"], uv["nchan"]) freqs_B = aa.get_afreqs() t_B = Time(t_B, scale="utc", format="jd", location=(aa.lat, aa.long)) lst_B = t_B.sidereal_time("apparent")
class DsaAlgorithm3(object): def __init__(self, data): self._dsa_path = os.environ['DSA'] self._conx_str = os.environ['CON_STR'] if data is not None: self.data = data self.tau = pd.read_csv( self._dsa_path + 'conf/tau.csv', sep=',', header=0).set_index('freq') self.tsky = pd.read_csv( self._dsa_path + 'conf/tskyR.csv', sep=',', header=0).set_index( 'freq') self.pwvdata = pd.read_pickle( self._dsa_path + 'conf/pwvdata2.pandas') self.schedblocks = self.data.schedblocks.copy() else: mode = 'Just for some tools...' self._pwv = None self._array_res = [] self._date = ephem.now() self._availableobs = False self._time_astropy = TIME self._ALMA_ephem = ALMA1 self._static_calculated = False def set_time_now(self): """ """ self._time_astropy = Time.now() self._time_astropy.delta_ut1_utc = 0 self._time_astropy.location = ALMA self._ALMA_ephem.date = ephem.now() def set_time(self, time_str): """ Args: time_str: """ self._time_astropy = Time(time_str) self._time_astropy.delta_ut1_utc = 0 self._time_astropy.location = ALMA self._ALMA_ephem.date = ephem.date(self._time_astropy.iso) def write_ephem_coords(self): """ """ self.schedblocks['ephem'] = 'N/A' ephem_sb = pd.merge( self.schedblocks, self.data.target_tables.query( 'solarSystem != "Unspecified" and isQuery == False and ' 'RA == 0'), on='SB_UID').drop_duplicates(['SB_UID', 'ephemeris']).set_index( 'SB_UID', drop=False) results = ephem_sb.apply( lambda x: DsaTool.calc_ephem_coords( x['solarSystem'], x['ephemeris'], x['SB_UID'], alma=self._ALMA_ephem), axis=1) for r in results.iteritems(): self.schedblocks.ix[r[0], 'RA'] = r[1][0] self.schedblocks.ix[r[0], 'DEC'] = r[1][1] self.schedblocks.ix[r[0], 'ephem'] = r[1][2] def static_param(self, horizon=20): """ Args: horizon: """ if self._static_calculated: idx = self.data.target_tables.query( 'solarSystem != "Unspecified" and isQuery == False and ' 'RA == 0').SB_UID.unique() self.obs_param.ix[idx] = self.schedblocks.ix[idx].apply( lambda r: DsaTool.observable( r['RA'], r['DEC'], self._ALMA_ephem, r['RA'], r['minAR'], r['maxAR'], r['array'], r['SB_UID'], horizon=horizon), axis=1 ) else: self.obs_param = self.schedblocks.apply( lambda r: DsaTool.observable( r['RA'], r['DEC'], self._ALMA_ephem, r['RA'], r['minAR'], r['maxAR'], r['array'], r['SB_UID'], horizon=horizon), axis=1 ) ind1 = pd.np.around(self.schedblocks.repfreq, decimals=1) ind2 = self.schedblocks.apply( lambda x: str( int(x['maxPWVC'] / 0.05) * 0.05 + (0.05 if (x['maxPWVC'] % 0.05) > 0.02 else 0.)) if x['maxPWVC'] < 8 else '7.95', axis=1) self.schedblocks['transmission_ot'] = self.pwvdata.lookup( ind1, ind2) self.schedblocks['tau_ot'] = self.tau.lookup(ind1, ind2) self.schedblocks['tsky_ot'] = self.tsky.lookup(ind1, ind2) self.schedblocks['airmass_ot'] = self.schedblocks.apply( lambda x: calc_airmass(x['DEC'], transit=True), axis=1) self.schedblocks['tsys_ot'] = ( self.schedblocks.apply( lambda x: calc_tsys(x['band'], x['tsky_ot'], x['tau_ot'], x['airmass_ot']), axis=1)) self.obs_param.rise.fillna(0, inplace=True) self.obs_param['rise datetime'] = self.obs_param.apply( lambda x: dt.datetime.strptime( '2015-01-01 ' + str(int(x['rise'])) + ':' + str(int(60*(x['rise'] - int(x['rise'])))), '%Y-%m-%d %H:%M'), axis=1) self._static_calculated = True def update_apdm(self, obsproject_uid): """ Args: obsproject_uid: """ self.data._update_apdm(obsproject_uid) self.schedblocks = self.data.schedblocks.copy() self._static_calculated = False def selector(self, array_kind='TWELVE-M', prj_status=("Ready", "InProgress"), sb_status=("Ready", "Suspended", "Running", "CalibratorCheck", "Waiting"), letterg=("A", "B", "C"), bands=("ALMA_RB_03", "ALMA_RB_04", "ALMA_RB_06", "ALMA_RB_07", "ALMA_RB_08", "ALMA_RB_09", "ALMA_RB_10"), check_count=True, conf=None, calc_blratio=False, numant=None, array_id=None, horizon=20., minha=-3., maxha=3., pwv=0., sim=False): """ Args: array_kind: prj_status: sb_status: letterg: bands: check_count: conf: calc_blratio: numant: array_id: horizon: minha: maxha: pwv: sim: """ if float(pwv) > 8: pwv = 8.0 # print self._time_astropy if sim: self._aggregate_dfs(sim=True) else: self._aggregate_dfs() self.master_dsa_df['array'] = self.master_dsa_df.apply( lambda x: 'SEVEN-M' if x['array'] == "ACA" else x['array'], axis=1 ) self.master_dsa_df['isToo'] = self.master_dsa_df.apply( lambda x: True if str(x['CODE']).endswith('.T') else False, axis=1 ) self.selection_df = self.master_dsa_df[['SB_UID']].copy() # select array kind self.selection_df['selArray'] = ( self.master_dsa_df['array'] == array_kind) # select valid Prj States self.selection_df['selPrjState'] = ( self.master_dsa_df.apply( lambda x: True if x['PRJ_STATUS'] in prj_status else False, axis=1)) # select valid SB States self.selection_df['selSBState'] = ( self.master_dsa_df.apply( lambda x: True if x['SB_STATE'] in sb_status else False, axis=1)) # select By grades sbuid_ex = self.exception_df.SB_UID.unique() self.selection_df['selGrade'] = ( self.master_dsa_df.apply( lambda x: True if (x['CYCLE'] in ["2015.1", "2015.A"] and x['DC_LETTER_GRADE'] in letterg) or (x['CYCLE'] not in ["2015.1", "2015.A"] and x['DC_LETTER_GRADE'] == "A") or (x['SB_UID'] in sbuid_ex) else False, axis=1) ) # select by band self.selection_df['selBand'] = ( self.master_dsa_df.apply( lambda x: True if x['band'] in bands else False, axis=1 ) ) if not sim: self.selection_df = self.selection_df.query( 'selArray == True and selPrjState == True and ' 'selSBState == True and selGrade == True and selBand == True') sb_fsel = self.selection_df.SB_UID.unique() self.master_dsa_df = self.master_dsa_df.query('SB_UID in @sb_fsel') # select if still some observations are left self.selection_df['selCount'] = True if check_count: self.selection_df['selCount'] = ( self.master_dsa_df.EXECOUNT > self.master_dsa_df.Observed) self.selection_df['selConf'] = True # Array Configuration Selection (12m) if array_kind == "TWELVE-M": self.master_dsa_df['blmax'] = self.master_dsa_df.apply( lambda row: rUV.compute_bl(row['minAR'] / 0.8, 100.), axis=1) self.master_dsa_df['blmin'] = self.master_dsa_df.apply( lambda row: rUV.compute_bl(row['LAScor'], 100., las=True) if ((row['LAScor'] > row['minAR']) and (row['LAScor'] > 5 * row['ARcordec'])) else rUV.compute_bl(10., 100., las=True), axis=1) if conf: # Not Working For Exceptions!!! qstring = '' l = len(conf) - 1 for i, c in enumerate(conf): col = c.replace('-', '_') if i == l: qstring += '%s == "%s"' % (col, c) else: qstring += '%s == "%s" or ' % (col, c) sbs_sel = self.master_dsa_df.query(qstring).SB_UID.unique() self.selection_df['selConf'] = self.selection_df.apply( lambda x: True if (x['SB_UID'] in sbs_sel) or ((x['lenconf'] > 0) and (x['minAR'] <= self.ar <= x['maxAR'])) else False, axis=1 ) self.ar = CONFRES[conf[0]] self.master_dsa_df['bl_ratio'] = 1. self.master_dsa_df['array_ar_cond'] = self.master_dsa_df.apply( lambda x: CONFRES[x['BestConf']] if x['BestConf'] in conf else pd.np.NaN, axis=1 ) self.master_dsa_df['num_bl_use'] = 630. if calc_blratio: self._query_array() array_id = self.arrays.iloc[0, 3] array_ar, num_bl, num_ant, ruv = self._get_bl_prop(array_id) self.master_dsa_df[['array_ar_cond', 'num_bl_use']] = ( self.master_dsa_df.apply( lambda x: self._get_sbbased_bl_prop( ruv, x['blmin'] * 0.9, x['blmax'] * 1.1, x['array']), axis=1) ) self.master_dsa_df['bl_ratio'] = self.master_dsa_df.apply( lambda x: 1. / calc_bl_ratio( x['array'], x['CYCLE'], x['num_bl_use'], self.selection_df.ix[x.name, 'selConf']), axis=1 ) else: self._query_array() try: a = self._last_array_used except AttributeError: self._last_array_used = '' if array_id == 'last': array_id = self.arrays.iloc[0, 3] if self._last_array_used == array_id: self.master_dsa_df['array_ar_cond'] = \ self.arr_cache['array_ar_cond'] self.master_dsa_df['num_bl_use'] = \ self.arr_cache['num_bl_use'] else: self.ar, numbl, numant, ruv = self._get_bl_prop(array_id) self.master_dsa_df[['array_ar_cond', 'num_bl_use']] = ( self.master_dsa_df.apply( lambda x: self._get_sbbased_bl_prop( ruv, x['blmin'] * 0.9, x['blmax'] * 1.1, x['array']), axis=1) ) self.arr_cache = self.master_dsa_df[ ['array_ar_cond', 'num_bl_use']].copy() self._last_array_used = array_id self.selection_df['selConf'] = self.master_dsa_df.apply( lambda x: True if ((x['array_ar_cond'] > x['minAR']) and (self.ar > 0.5 * x['ARcordec']) and (x['array_ar_cond'] < (x['maxAR'] * 1.3)) and (x['array_ar_cond'] < (x['ARcordec'] * 1.15))) or ((x['lenconf'] > 2) and (x['minAR'] <= self.ar) and (self.ar <= x['maxAR']) and (x['array'] == "TWELVE-M")) else False, axis=1) self.master_dsa_df['bl_ratio'] = self.master_dsa_df.apply( lambda x: 1. / calc_bl_ratio( x['array'], x['CYCLE'], x['num_bl_use'], self.selection_df.ix[x.name, 'selConf']), axis=1 ) # Array Configuration Selection (7m or ACA) elif array_kind == "SEVEN-M": if numant is None: numant = 10. self.selection_df['selConf'] = self.master_dsa_df.apply( lambda x: True if x['array'] == "SEVEN-M" else False, axis=1 ) self.master_dsa_df['blmax'] = pd.np.NaN self.master_dsa_df['blmin'] = pd.np.NaN self.master_dsa_df['array_ar_cond'] = pd.np.NaN self.master_dsa_df['num_bl_use'] = pd.np.NaN self.master_dsa_df['bl_ratio'] = self.master_dsa_df.apply( lambda x: 1. / calc_bl_ratio( x['array'], x['CYCLE'], x['num_bl_use'], self.selection_df.ix[x.name, 'selConf'], numant=numant), axis=1 ) # Array Configuration selection (TP) else: if numant is None: numant = 2. # Until we have a clear idea on how to handle TP ampcals, removing # them from the DSA output # noinspection PyUnusedLocal selsb = self.master_dsa_df.query( 'array == "TP-Array"').SB_UID.unique() selsb1 = self.master_dsa_df[ self.master_dsa_df.sbNote.str.contains('TP ampcal') ].SB_UID.unique() selsb2 = pd.merge( pd.merge( self.data.orderedtar.query('SB_UID in @selsb'), self.data.target, on=['SB_UID', 'targetId']), self.data.fieldsource, on=['SB_UID', 'fieldRef']).query( 'name_y == "Amplitude"').SB_UID.unique() self.selection_df['selConf'] = self.master_dsa_df.apply( lambda x: True if (x['array'] == "TP-Array") and ((x['SB_UID'] not in selsb1) and (x['SB_UID'] not in selsb2)) else False, axis=1 ) self.master_dsa_df['blmax'] = pd.np.NaN self.master_dsa_df['blmin'] = pd.np.NaN self.master_dsa_df['array_ar_cond'] = pd.np.NaN self.master_dsa_df['num_bl_use'] = pd.np.NaN self.master_dsa_df['bl_ratio'] = 1. # select observable: elev, ha, moon & sun distance polarization = self.master_dsa_df.query('PolCalibrator != ""').copy() try: cpol = SkyCoord( ra=polarization.RA_pol * u.degree, dec=polarization.DEC_pol * u.degree, location=ALMA, obstime=self._time_astropy) except IndexError: cpol = polarization.copy() try: c = SkyCoord( ra=self.master_dsa_df.RA * u.degree, dec=self.master_dsa_df.DEC * u.degree, location=ALMA, obstime=self._time_astropy) except IndexError: print("Nothing to observe? %s" % len(self.master_dsa_df)) self._availableobs = False return ha = self._time_astropy.sidereal_time('apparent') - c.ra self.master_dsa_df['HA'] = ha.wrap_at(180 * u.degree).value self.master_dsa_df['RAh'] = c.ra.hour self.master_dsa_df['elev'] = c.transform_to( AltAz(obstime=self._time_astropy, location=ALMA)).alt.value corr_el = ((self.master_dsa_df.ephem != 'N/A') & (self.master_dsa_df.ephem != 'OK')) self.master_dsa_df.ix[corr_el, 'elev'] = -90. self.master_dsa_df.ix[corr_el, 'HA'] = -24. self.selection_df['selElev'] = ( (self.master_dsa_df.elev >= horizon) & (self.master_dsa_df.RA != 0) & (self.master_dsa_df.DEC != 0) ) self.selection_df.set_index('SB_UID', drop=False, inplace=True) if len(cpol) > 0: ha = self._time_astropy.sidereal_time('apparent') - cpol.ra polarization['HA_pol'] = ha.wrap_at(180 * u.degree).value polarization['RAh_pol'] = cpol.ra.hour polarization['elev_pol'] = cpol.transform_to( AltAz(obstime=self._time_astropy, location=ALMA)).alt.value parall = pd.np.arctan( pd.np.sin(ha.radian) / (pd.np.tan(ALMA.latitude.radian) * pd.np.cos(cpol.dec.radian) - pd.np.sin(cpol.dec.radian) * pd.np.cos(ha.radian) )) polarization['parallactic'] = pd.np.degrees(parall) corr_el = ((polarization.ephem != 'N/A') & (polarization.ephem != 'OK')) polarization.ix[corr_el, 'elev_pol'] = -90. polarization.ix[corr_el, 'HA_pol'] = -24. self.polarization = polarization self.selection_df.loc[ polarization[polarization.elev_pol < 20].SB_UID.values, 'selElev'] = False self.selection_df['selHA'] = ( (self.master_dsa_df.set_index('SB_UID').HA >= minha) & (self.master_dsa_df.set_index('SB_UID').HA <= maxha) ) # Sel Conditions, exec. frac ind1 = pd.np.around(self.master_dsa_df.repfreq, decimals=1) pwv_str = (str(int(pwv / 0.05) * 0.05 + (0.05 if (int(pwv * 100) % 5) > 2 else 0.))) self.master_dsa_df['transmission'] = self.pwvdata.ix[ ind1, pwv_str].values self.master_dsa_df['tau'] = self.tau.ix[ind1, pwv_str].values self.master_dsa_df['tsky'] = self.tsky.ix[ind1, pwv_str].values self.master_dsa_df['airmass'] = self.master_dsa_df.apply( lambda x: calc_airmass(x['elev'], transit=False), axis=1) self.master_dsa_df['tsys'] = ( self.master_dsa_df.apply( lambda x: calc_tsys(x['band'], x['tsky'], x['tau'], x['airmass']), axis=1)) self.master_dsa_df['tsys_ratio'] = self.master_dsa_df.apply( lambda x: 1. / (x['tsys'] / x['tsys_ot'])**2. if x['tsys'] <= 25000. else 0., axis=1) self.master_dsa_df['Exec. Frac'] = self.master_dsa_df.apply( lambda x: (x['bl_ratio'] * x['tsys_ratio']) if (x['bl_ratio'] * x['tsys_ratio']) <= 100. else 0., axis=1) self.selection_df['selCond'] = self.master_dsa_df.set_index( 'SB_UID').apply( lambda x: True if x['Exec. Frac'] >= 0.70 else False, axis=1 ) self.master_dsa_df.set_index('SB_UID', drop=False, inplace=True) self.selection_df.set_index('SB_UID', drop=False, inplace=True) savedate = ALMA1.date savehoriz = ALMA1.horizon ALMA1.horizon = 0.0 lstdate = str(ALMA1.sidereal_time()).split(':') lstdate0 = dt.datetime.strptime( '2014-12-31 ' + str(lstdate[0]) + ':' + str(lstdate[1]), '%Y-%m-%d %H:%M') lstdate1 = dt.datetime.strptime( '2015-01-01 ' + str(lstdate[0]) + ':' + str(lstdate[1]), '%Y-%m-%d %H:%M') lstdate2 = dt.datetime.strptime( '2015-01-02 ' + str(lstdate[0]) + ':' + str(lstdate[1]), '%Y-%m-%d %H:%M') sunrisedate = ALMA1.previous_rising(ephem.Sun()) ALMA1.date = sunrisedate sunriselst = str(ALMA1.sidereal_time()).split(':') sunriselst_h = dt.datetime.strptime( '2015-01-01 ' + str(sunriselst[0]) + ':' + str(sunriselst[1]), '%Y-%m-%d %H:%M') sunsetdate = ALMA1.next_setting(ephem.Sun()) ALMA1.date = sunsetdate sunsetlst = str(ALMA1.sidereal_time()).split(':') sunsetlst_h = dt.datetime.strptime( '2015-01-01 ' + str(sunsetlst[0]) + ':' + str(sunriselst[1]), '%Y-%m-%d %H:%M') self.inputs = pd.DataFrame( pd.np.array([lstdate0, lstdate1, lstdate2, sunsetlst_h, sunriselst_h, sunsetlst_h + dt.timedelta(1), sunriselst_h + dt.timedelta(1)]), index=['lst0', 'lst1', 'lst2', 'set1', 'rise1', 'set2', 'rise2'], columns=['2013.A']).transpose() self.inputs.ix['2013.1', :] = self.inputs.ix['2013.A', :] self.inputs.ix['2015.A', :] = self.inputs.ix['2013.A', :] self.inputs.ix['2015.1', :] = self.inputs.ix['2013.A', :] ALMA1.date = savedate ALMA1.horizon = savehoriz # noinspection PyTypeChecker,PyUnusedLocal def _aggregate_dfs(self, sim=False): """ Args: sim: """ if sim: phase = ["I", "II"] hassb = 'hasSB == True or hasSB == False' how = 'right' else: phase = ["II"] hassb = 'hasSB == True' how = 'left' self.master_dsa_df = pd.merge( self.data.projects.query('phase in @phase')[ ['OBSPROJECT_UID', 'CYCLE', 'CODE', 'DC_LETTER_GRADE', 'PRJ_SCIENTIFIC_RANK', 'PRJ_STATUS', 'EXEC']], self.data.sciencegoals.query(hassb)[ ['OBSPROJECT_UID', 'SG_ID', 'OUS_ID', 'ARcor', 'LAScor', 'isTimeConstrained', 'isCalSpecial', 'isSpectralScan', 'sg_name', 'AR', 'LAS']], on='OBSPROJECT_UID', how='left') self.master_dsa_df = pd.merge( self.master_dsa_df, self.schedblocks[ ['OBSPROJECT_UID', 'SB_UID', 'sbName', 'array', 'repfreq', 'band', 'RA', 'DEC', 'maxPWVC', 'minAR', 'maxAR', 'OT_BestConf', 'BestConf', 'two_12m', 'estimatedTime', 'isPolarization', 'ephem', 'airmass_ot', 'transmission_ot', 'tau_ot', 'tsky_ot', 'tsys_ot', 'sbNote', 'SG_ID', 'sgName', 'execount']], on=['OBSPROJECT_UID', 'SG_ID'], how=how) self.master_dsa_df = pd.merge( self.master_dsa_df, self.data.sblocks[ ['OBSPROJECT_UID', 'OUS_ID', 'GOUS_ID', 'MOUS_ID', 'SB_UID']], on=['OBSPROJECT_UID', 'SB_UID'], how='left', suffixes=['_sg', '_sb']) self.master_dsa_df['ARcor'] = self.master_dsa_df.apply( lambda x: x['AR'] * x['repfreq'] / 100. if not str(x['sbName']).endswith('_TC') else x['minAR'] / 0.8, axis=1 ) self.master_dsa_df['ARcordec'] = self.master_dsa_df.apply( lambda x: x['ARcor'] / ( 0.4001 / pd.np.cos( pd.np.radians(-23.0262015) - pd.np.radians(x['DEC'])) + 0.6103) if not str(x['sbName']).endswith('_TC') else x['ARcor'], axis=1) self.master_dsa_df['arcordec_original'] = \ self.master_dsa_df.ARcordec.copy() self.master_dsa_df = pd.merge( self.master_dsa_df, self.data.sb_status[['SB_UID', 'SB_STATE', 'EXECOUNT']], on=['SB_UID'], how='left') self.master_dsa_df.EXECOUNT.fillna(-10, inplace=True) self.master_dsa_df['EXECOUNT'] = self.master_dsa_df.apply( lambda x: x['execount'] if x['EXECOUNT'] == -10 else x['EXECOUNT'], axis=1 ) self.master_dsa_df.drop('execount', axis=1, inplace=True) self.master_dsa_df = pd.merge( self.master_dsa_df, self.data.qastatus[ ['Unset', 'Pass', 'Observed', 'ebTime', 'last_observed', 'last_qa0', 'last_status']], left_on='SB_UID', right_index=True, how='left') self.master_dsa_df.Unset.fillna(0, inplace=True) self.master_dsa_df.Pass.fillna(0, inplace=True) self.master_dsa_df.Observed.fillna(0, inplace=True) self.master_dsa_df = pd.merge( self.master_dsa_df, self.obs_param[ ['SB_UID', 'rise', 'set', 'note', 'C36_1', 'C36_2', 'C36_3', 'C36_4', 'C36_5', 'C36_6', 'C36_7', 'C36_8', 'twelve_good']], on=['SB_UID'], how='left') self.master_dsa_df.ebTime.fillna(0, inplace=True) self.master_dsa_df['estTimeOr'] = \ self.master_dsa_df.estimatedTime.copy() self.master_dsa_df['estimatedTime'] = self.master_dsa_df.apply( lambda x: x['estimatedTime'] if x['ebTime'] <= 0.1 else x['ebTime'] * x['EXECOUNT'], axis=1 ) step1 = pd.merge(self.data.polcalparam[['SB_UID', 'paramRef']], self.data.target, on=['SB_UID', 'paramRef']) step2 = pd.merge(step1, self.data.orderedtar, on=['SB_UID', 'targetId']) step3 = pd.merge( step2, self.data.fieldsource, on=['SB_UID', 'fieldRef'] ).drop_duplicates('SB_UID')[['SB_UID', 'RA', 'DEC', 'sourcename']] step3.columns = pd.Index( ['SB_UID', 'RA_pol', 'DEC_pol', 'PolCalibrator'], dtype='object') self.master_dsa_df = pd.merge(self.master_dsa_df, step3, on='SB_UID', how='left') self.master_dsa_df.RA_pol.fillna(0, inplace=True) self.master_dsa_df.DEC_pol.fillna(0, inplace=True) self.master_dsa_df.PolCalibrator.fillna('', inplace=True) self.calc_completion() self.master_dsa_df = pd.merge( self.master_dsa_df, self.grouped_ous[['OBSPROJECT_UID', 'GOUS_ID', 'GOUS_comp', 'proj_comp']], on=['OBSPROJECT_UID', 'GOUS_ID'], how='left' ) self.exception_df = pd.merge( self.data._exceptions, self.master_dsa_df[['CODE', 'sbName', 'SB_UID', 'array']], on=['CODE', 'sbName'], how='left').set_index('SB_UID', drop=False) self.exception_df.forced_confs.fillna('None', inplace=True) self.exception_df['conflist'] = \ self.exception_df.forced_confs.str.split(',') self.exception_df['CompConf'] = self.exception_df.apply( lambda x: x['conflist'][0], axis=1) self.exception_df['ExtConf'] = self.exception_df.apply( lambda x: x['conflist'][-1], axis=1) self.exception_df['lenconf'] = self.exception_df.apply( lambda x: len(x['conflist']) if 'None' not in x['conflist'] and x['array'] == "TWELVE-M" else 0, axis=1) self.master_dsa_df[ ['SB_UID_ck', 'minAR', 'maxAR', 'ARcordec', 'LAScor', 'BestConf', 'lenconf']] = self.master_dsa_df.apply( lambda row: newimparam_excep(self.exception_df, row), axis=1 ) def _query_array(self, array_kind='TWELVE-M'): """ Args: array_kind: """ if array_kind == 'TWELVE-M': sql = str( "select se.SE_TIMESTAMP ts1, sa.SLOG_ATTR_VALUE av1, " "se.SE_ARRAYNAME, se.SE_ID se1 from ALMA.SHIFTLOG_ENTRIES se, " "ALMA.SLOG_ENTRY_ATTR sa " "WHERE se.SE_TYPE=7 and se.SE_TIMESTAMP > SYSDATE - 1/1. " "and sa.SLOG_SE_ID = se.SE_ID and sa.SLOG_ATTR_TYPE = 31 " "and se.SE_LOCATION='OSF-AOS' and se.SE_CORRELATORTYPE = 'BL' " "and se.SE_ARRAYFAMILY = '12 [m]' " "and se.SE_ARRAYTYPE != 'Manual'") elif array_kind == 'SEVEN-M': sql = str( "select se.SE_TIMESTAMP ts1, sa.SLOG_ATTR_VALUE av1, " "se.SE_ARRAYNAME, se.SE_ID se1 from ALMA.SHIFTLOG_ENTRIES se, " "ALMA.SLOG_ENTRY_ATTR sa " "WHERE se.SE_TYPE=7 and se.SE_TIMESTAMP > SYSDATE - 1/1. " "and sa.SLOG_SE_ID = se.SE_ID and sa.SLOG_ATTR_TYPE = 31 " "and se.SE_LOCATION='OSF-AOS' and se.SE_CORRELATORTYPE = 'ACA' " "and se.SE_ARRAYFAMILY = '7 [m]' " "and se.SE_ARRAYTYPE != 'Manual'") elif array_kind == 'TP-Array': sql = str( "select se.SE_TIMESTAMP ts1, sa.SLOG_ATTR_VALUE av1, " "se.SE_ARRAYNAME, se.SE_ID se1 from ALMA.SHIFTLOG_ENTRIES se, " "ALMA.SLOG_ENTRY_ATTR sa " "WHERE se.SE_TYPE=7 and se.SE_TIMESTAMP > SYSDATE - 1/1. " "and sa.SLOG_SE_ID = se.SE_ID and sa.SLOG_ATTR_TYPE = 31 " "and se.SE_LOCATION='OSF-AOS' and se.SE_CORRELATORTYPE = 'ACA' " "and se.SE_ARRAYFAMILY = 'Total Power' " "and se.SE_ARRAYTYPE != 'Manual'") else: print("%s array kind is not valid. Use TWELVE-M, SEVEN-M, TP-Array") return con, cur = self.open_oracle_conn() try: cur.execute(sql) self._arrays_info = pd.DataFrame( cur.fetchall(), columns=[rec[0] for rec in cur.description] ).sort_values(by='TS1', ascending=False) finally: cur.close() con.close() if self._arrays_info.size == 0: self._arrays_info = pd.DataFrame( columns=pd.Index( [u'TS1', u'AV1', u'SE_ARRAYNAME', u'SE1'], dtype='object')) print("No %s arrays have been created in the last 6 hours." % array_kind) self._group_arrays = None self.arrays = None return if array_kind in ['TWELVE-M', 'TP-Array']: self._group_arrays = self._arrays_info[ self._arrays_info.AV1.str.startswith('CM') == False].copy() else: self._group_arrays = self._arrays_info[ self._arrays_info.AV1.str.startswith('CM') == True].copy() if array_kind == "TWELVE-M": self.arrays = self._group_arrays.groupby( 'TS1').aggregate( {'SE_ARRAYNAME': max, 'SE1': max, 'AV1': pd.np.count_nonzero}).query( 'AV1 > 28').reset_index().sort_values(by='TS1', ascending=False) elif array_kind == "SEVEN-M": self.arrays = self._group_arrays.groupby( 'TS1').aggregate( {'SE_ARRAYNAME': max, 'SE1': max, 'AV1': pd.np.count_nonzero}).query( 'AV1 > 5').reset_index().sort_values(by='TS1', ascending=False) else: self.arrays = self._group_arrays.groupby( 'TS1').aggregate( {'SE_ARRAYNAME': max, 'SE1': max, 'AV1': pd.np.count_nonzero}).query( 'AV1 >= 1').reset_index().sort_values(by='TS1', ascending=False) # get latest pad info b = str( "select se.SE_TIMESTAMP ts1, se.SE_SUBJECT, " "sa.SLOG_ATTR_VALUE av1, se.SE_ID se1, se.SE_SHIFTACTIVITY " "from alma.SHIFTLOG_ENTRIES se, alma.SLOG_ENTRY_ATTR sa " "WHERE se.SE_TYPE=1 and se.SE_TIMESTAMP > SYSDATE - 2. " "and sa.SLOG_SE_ID = se.SE_ID and sa.SLOG_ATTR_TYPE = 12 " "and se.SE_LOCATION='OSF-AOS'" ) con, cur = self.open_oracle_conn() try: cur.execute(b) self._shifts = pd.DataFrame( cur.fetchall(), columns=[rec[0] for rec in cur.description] ).sort_values(by='TS1', ascending=False) except ValueError: self._shifts = pd.DataFrame( columns=pd.Index( [u'TS1', u'AV1', u'SE_ARRAYNAME', u'SE1'], dtype='object')) print("No shiftlogs have been created in the last 6 hours.") finally: cur.close() con.close() last_shift = self._shifts[ self._shifts.SE1 == self._shifts.iloc[0].SE1].copy( ).drop_duplicates('AV1') last_shift['AV1'] = last_shift.AV1.str.split(':') ante = last_shift.apply(lambda x: x['AV1'][0], axis=1) pads = last_shift.apply(lambda x: x['AV1'][1], axis=1) self._ante_pad = pd.DataFrame({'antenna': ante, 'pad': pads}) def _get_bl_prop(self, array_name): # In case a bl_array is selected """ Args: array_name: Returns: object: """ if array_name not in CONF_LIM['minbase'].keys(): id1 = self._arrays_info.query( 'SE_ARRAYNAME == "%s"' % array_name).iloc[0].SE1 ap = self._arrays_info.query( 'SE_ARRAYNAME == "%s" and SE1 == %d' % (array_name, id1) )[['AV1']] ap.rename(columns={'AV1': 'antenna'}, inplace=True) ap = ap[ap.antenna.str.contains('CM') == False] if len(ap) == 0: ap = self._arrays_info.query( 'SE_ARRAYNAME == "%s" and SE1 == %d' % (array_name, id1))[['AV1']] ap.rename(columns={'AV1': 'antenna'}, inplace=True) conf = pd.merge(ap, self._ante_pad, left_on='antenna', right_on='antenna')[ ['pad', 'antenna']] conf_file = self._dsa_path + 'conf/%s.txt' % array_name conf.to_csv(conf_file, header=False, index=False, sep=' ') ac = rUV.ac.ArrayConfigurationCasaFile() ac.createCasaConfig(conf_file) ruv = rUV.compute_radialuv(conf_file + ".cfg") num_bl = len(ruv) num_ant = len(ap) array_ar = rUV.compute_array_ar(ruv) # If C36 is selected else: conf_file = (self._dsa_path + 'conf/%s.cfg' % array_name) ruv = rUV.compute_radialuv(conf_file) # noinspection PyTypeChecker array_ar = rUV.compute_array_ar(ruv) num_bl = len(ruv) if array_name.startswith('C40'): num_ant = 40 else: num_ant = 36 return array_ar, num_bl, num_ant, ruv @staticmethod def _get_sbbased_bl_prop(ruv, blmin, blmax, arrayfam): """ Args: ruv: blmin: blmax: arrayfam: Returns: Pandas.Series: """ if arrayfam != "TWELVE-M": return pd.Series( [pd.np.NaN, 0], index=['array_ar_cond', 'num_bl_use']) ruv = ruv[(ruv >= blmin) & (ruv <= blmax)] if len(ruv) < 400.: return pd.Series( [pd.np.NaN, 0], index=['array_ar_cond', 'num_bl_use']) num_bl = len(ruv) array_ar = rUV.compute_array_ar(ruv) return pd.Series([array_ar, num_bl], index=['array_ar_cond', 'num_bl_use']) def _observe_pol(self): pass def calc_completion(self): """ """ s1 = pd.merge( self.data.qastatus.reset_index(), self.data.sblocks[ ['OBSPROJECT_UID', 'SB_UID', 'OUS_ID', 'GOUS_ID', 'MOUS_ID', 'array']], on='SB_UID', how='right') s1.fillna(0, inplace=True) s2 = pd.merge(s1, self.data.sb_status[ ['SB_UID', 'EXECOUNT', 'SB_STATE']], on='SB_UID') s2['SB_Comp'] = s2.apply( lambda x: 1 if (x['SB_STATE'] == "FullyObserved" or x['Observed'] >= x['EXECOUNT']) else 0, axis=1) self.grouped_ous = s2.groupby( ['OBSPROJECT_UID', 'GOUS_ID']).aggregate( {'SB_UID': pd.np.count_nonzero, 'SB_Comp': pd.np.sum, 'EXECOUNT': pd.np.sum, 'Observed': pd.np.sum}).reset_index() self.grouped_ous['GOUS_comp'] = ( 1. * self.grouped_ous.SB_Comp / self.grouped_ous.SB_UID) self.grouped_ous.columns = pd.Index( [u'OBSPROJECT_UID', u'GOUS_ID', u'TotalEBObserved_GOUS', u'SB_Completed_GOUS', u'TotalExecount_GOUS', u'SB_Number_GOUS', u'GOUS_comp'], dtype='object') gp = self.grouped_ous.groupby( 'OBSPROJECT_UID').aggregate( {'GOUS_ID': pd.np.count_nonzero, 'GOUS_comp': pd.np.sum}) gp['proj_comp'] = 1. * gp.GOUS_comp / gp.GOUS_ID self.grouped_ous = pd.merge( self.grouped_ous, gp.reset_index()[['OBSPROJECT_UID', 'proj_comp']], on='OBSPROJECT_UID', how='left' ) def open_oracle_conn(self): """ Returns: object: """ connection = cx_Oracle.connect(self._conx_str, threaded=True) cursor = connection.cursor() return connection, cursor
sm.print_hadec(t_point=args.t_point) for az in range(0,360-args.step,args.step): for alt in range(0,90-args.step,args.step): r_az=uniform(0, args.step) r_alt=uniform(0, args.step) # catalog AltAz cat_aa=SkyCoord(az=az+r_az,alt=alt+r_alt,unit=(u.deg,u.deg),frame='altaz',location=sm.obs,obstime=dt_utc) # catalog EQ cat_eq=sm.LN_AltAz_to_EQ(az=cat_aa.az.deg,alt=cat_aa.alt.deg,obstime=dt_utc) # apparent AltAz (mnt), includes refraction etc. mnt_aa=sm.transform_to_altaz(eq=cat_eq,tem=args.temperature,pre=args.pressure_qfe,hum=args.humidity,astropy_f=False,correct_cat_f=True) # apparent EQ mnt_eq_tmp=sm.LN_AltAz_to_EQ(az=mnt_aa.az.degree,alt=mnt_aa.alt.degree,obstime=dt_utc) # ha= Longitude(dt_utc.sidereal_time('apparent') - mnt_eq_tmp.ra,u.radian).radian # # subtract the correction # | | 0. here vd_ha=Longitude(-d_ha_f(ha,mnt_eq_tmp.dec.radian,0.,sm.obs.latitude.radian),u.radian) # apparent coordinates vd_dec=Latitude(-d_dec_f(ha,mnt_eq_tmp.dec.radian,0.,sm.obs.latitude.radian),u.radian) # noise if sigma!=0.: vn_lon=Longitude(np.random.normal(loc=0.,scale=sigma),u.radian) vn_lat=Latitude(np.random.normal(loc=0.,scale=sigma),u.radian) # mount apparent EQ try: mnt_eq=SkyCoord(ra=mnt_eq_tmp.ra+vd_ha+vn_lon,dec=mnt_eq_tmp.dec+vd_dec+vn_lat,unit=(u.radian,u.radian),frame='cirs',location=sm.obs,obstime=dt_utc) except Exception as e: logger.warn('u_simulate: exception {}, lost one data point'.format(e)) continue
if det =='H1': Lambda = np.pi * 46.45 / 180; # latitude gamma = np.pi * 171.8 / 180; # orientation of arms lde = np.pi * 119.41 / 180; # longitude xi = np.pi / 2; # angle between arms #Livinsgton if det == 'L1': Lambda = np.pi * 30.56 / 180; # latitude gamma = np.pi * 243.0 / 180; # orientation of arms lde = np.pi * 90.77 / 180; # longitude xi = np.pi / 2; # angle between arms psi = 0#0.343 #(radians) Polarization angle t = Time(t0, format='gps') gmst = t.sidereal_time('mean','greenwich').rad lst = t.sidereal_time('mean',longitude=str(360-np.degrees(lde))+'d') print 'in ', t.isot print 'max at (ra, dec), delta:', lst.rad, np.degrees(Lambda), ((180-lst.deg)-np.degrees(lde) ) Xlista = np.arange(0,360.,1.) Ylista = np.arange(-90.,90.,1.) Z = np.array([]) for i in Ylista: for j in Xlista: ztemp = antenna_response(t0, np.radians(j),np.radians(i), psi, det ) Z = np.append(Z,ztemp) X = np.arange(-180,180.,1.)
def plot_grid(self,ra_delta=30.0,dec_delta=30.0,dec_label=0.0,ra_label=0.0,npoints=100,textcolor='g',textsize=None,auto_ra=True,**kwd): # plot ra dec grid altaz=kwd.get('altaz',False) wcs=kwd.get('wcs',None) lon=kwd.get('lon',-111.600) lat=kwd.get('lat',31.9633) height=kwd.get('height',2120.0) timezone=kwd.get('timezone',-7) datetime=kwd.get('datetime','2016-5-26 00:00:00') local=kwd.get('local',False) xc=kwd.get('xc',None) yc=kwd.get('yc',None) radius=kwd.get('radius',None) origin=kwd.get('origin','top') # get local sideral time time=Time(datetime) if local is True: time-=utcoffset time.delta_ut1_utc = 0. lst=time.sidereal_time('mean',longitude=lon) nra=360.0//ra_delta+1 ndec=90.0//dec_delta+1 ra=np.linspace(0,360,npoints) if altaz: dec=np.linspace(0,90,ndec) else: dec=np.linspace(-90,90,ndec) for idec in dec: self.plot_radec(ra,idec,**kwd) tmpra=ra_label tmpdec=idec if altaz: az=tmpra alt=tmpdec else: if auto_ra: tmpra=lst alt,az=self.radec_altaz(tmpra,tmpdec,wcs=wcs,lon=lon,lat=lat,height=height,timezone=timezone,datetime=datetime,local=local) x,y=self.altaz_xy(alt,az,xc=xc,yc=yc,radius=radius,origin=origin) self.image.axes.text(x,y,'%+3d' % idec,horizontalalignment='center',verticalalignment='center',color=textcolor,clip_on=True,size=textsize) ra=np.linspace(0,360,nra) if altaz: dec=np.linspace(0,90,npoints) else: dec=np.linspace(-90,90,npoints) for ira in ra: if ira == 360.0: continue self.plot_radec(ira,dec,**kwd) tmpra=ira tmpdec=dec_label if altaz: az=tmpra alt=tmpdec else: alt,az=self.radec_altaz(tmpra,tmpdec,wcs=wcs,lon=lon,lat=lat,height=height,timezone=timezone,datetime=datetime,local=local) x,y=self.altaz_xy(alt,az,xc=xc,yc=yc,radius=radius,origin=origin) self.image.axes.text(x,y,'%4d' % ira,horizontalalignment='center',verticalalignment='center',color=textcolor,clip_on=True,size=textsize)
def store_nominal_altaz(self,lon_step=None,lat_step=None,azimuth_interval=None,altitude_interval=None,eq_mount=None,eq_excluded_ha_interval=None,eq_minimum_altitude=None,fn=None,force_overwrite=False): # ToDo from pathlib import Path, fp=Path(ptfb),if fp.is_file()) # format lon_nml,lat_nml ptfn=self.expand_base_path(fn=fn) if not force_overwrite: if os.path.isfile(ptfn): a=input('overwriting existing file: {} [N/y]'.format(ptfn)) if a not in 'y': self.lg.info('exiting') sys.exit(0) self.nml=list() up=True #tfts=Transformation(lg=self.lg,obs=self.obs) nml_id=-1 if eq_mount: min_alt=eq_minimum_altitude/180.*np.pi low_ha=eq_excluded_ha_interval[0] high_ha=eq_excluded_ha_interval[1] lon_rng=range(0,360,lon_step) lat_rng_up=range(int(-90+lat_step),int(90.-lat_step),lat_step) lat_rng_down=range(int(90.-lat_step),int(-90+lat_step),-lat_step) now=Time(datetime.utcnow(), scale='utc',location=self.obs,out_subfmt='date') sdt=now.sidereal_time('apparent') for lon in lon_rng: if low_ha <=lon <= high_ha: self.lg.debug('store_nominal_altaz: dropped ha: {} (interval: {}, {})'.format(lon,low_ha,high_ha)) continue # Epson MX-80 if up: up=False rng=lat_rng_up else: up=True rng=lat_rng_down for lat in rng: # this is a murks ra= sdt.radian - lon/180.*np.pi hadec=SkyCoord(ra=ra,dec=lat,unit=(u.radian,u.degree),frame='icrs',location=self.obs,obstime=now) altaz=hadec.altaz lon_r=altaz.az.radian lat_r=altaz.alt.radian if min_alt < lat_r: nml_id +=1 nml_aa=altaz nml=NmlPosition(nml_id=nml_id,nml_aa=nml_aa) self.nml.append(nml) continue #self.lg.debug('store_nominal_altaz: min alt, dropped ha: {}, dec: {}, alt: {}, min_alt: {}'.format(lon,lat,lat_r*180./np.pi,min_alt*180./np.pi)) else: # ToDo input as int? lon_rng=range(int(azimuth_interval[0]),int(azimuth_interval[1]),lon_step) # No, exclusive + lon_step lat_rng_up=range(int(altitude_interval[0]),int(altitude_interval[1]+lat_step),lat_step) lat_rng_down=range(int(altitude_interval[1]),int(altitude_interval[0])-lat_step,-lat_step) lir=len(lat_rng_up) for i,lon in enumerate(lon_rng): # Epson MX-80 if up: up=False rng=lat_rng_up else: up=True rng=lat_rng_down lon_r=lon/180.*np.pi for j,lat in enumerate(rng): nml_id +=1 lat_r=lat/180.*np.pi nml_aa=SkyCoord(az=lon_r,alt=lat_r,unit=(u.radian,u.radian),frame='altaz',location=self.obs) nl=NmlPosition(nml_id=nml_id,nml_aa=nml_aa) self.nml.append(nl) # ToDo candidate for pandas with open(ptfn, 'w') as wfl: for nl in self.nml: # | is the id wfl.write('#{0},{1:12.6f},{2:12.6f}\n'.format(nl.nml_id,nl.nml_aa.az.degree,nl.nml_aa.alt.degree)) wfl.write('{},{},{}\n'.format(nl.nml_id,nl.nml_aa.az.radian,nl.nml_aa.alt.radian))
print save_path os.chdir(save_path) #create a time object images = glob.glob('AB'+planet+'*.fits') print '\nList of images = \n' print images #obtain the sideral time from header data local_time = [] sideraltime = [] for i in range(len(images)): im,hdr = fits.getdata(images[i],header=True) tempo = Time(hdr[file['date-obs']]+'T'+hdr[file['time-obs']],format='isot',scale=file['scale-time']) local_time.append(tempo) sideraltime.append(tempo.sidereal_time('apparent',longitude=file['lon-obs'])) print '\nThis is the list of local time: \n' print '\nImage ** Local Time (isot format) ** Sideral Time (hours min seg)\n' for i in range(len(images)): print images[i],' ** ',local_time[i],' ** ',sideraltime[i] print '\nSetting coordinates to our '+planet+': \n' RA = Angle(file['RA']+file['u.RA']) DEC = Angle(file['DEC']+file['u.DEC']) coordinates = SkyCoord(RA,DEC,frame=file['frame']) print '\nCoordinates: ',coordinates print '\nIncluding RA,DEC,epoch in the header of the images ....\n' #RA in hours
def corrections(lon, lat, alt, ra, dec, mjd): """ Calculate the heliocentric radial velocity corrections for an astronomical source. Parameters ---------- lon : `~astropy.coordinates.Longitude` or float Earth longitude of the observatory (western direction is positive). Can be anything that initialises an `~astropy.coordinates.Angle` object (if float, in degrees). lat : `~astropy.coordinates.Latitude` or float Earth latitude of observatory. Can be anything that initialises an `~astropy.coordinates.Latitude` object (if float, in degrees). alt : `~astropy.units.Quantity` or float Altitude of the observatory (if float, in meters). ra : `~astropy.coordinates.Angle` or float Right ascension of the object for epoch J2000 (if float, in degrees). dec : `~astropy.coordinates.Angle` or float Declination of the object for epoch J2000 (if float, in degrees). mjd : float The modified Julian date for the middle of exposure. Returns ------- barycorr : `~astropy.units.Quantity` The barycentric velocity correction. helcorr : `~astropy.units.Quantity` The heliocentric velocity correction. """ if not isinstance(lon, coord.Longitude): lon = coord.Longitude(lon * u.deg) if not isinstance(lat, coord.Latitude): lat = coord.Latitude(lat * u.deg) if not isinstance(alt, u.Quantity): alt *= u.m if not isinstance(ra, u.Quantity): ra *= u.deg if not isinstance(dec, u.Quantity): dec *= u.deg # Here we specify the location so that we can easily calculate the mean # local siderial time later on time = Time(2.4e6 + mjd, format="jd", location=(lon, lat, alt)) epoch = time.datetime.year + time.datetime.month/12. \ + time.datetime.day/365. # Precess the coordinates to the current epoch coordinate = coord.SkyCoord(ra, dec, frame="fk5").transform_to(coord.FK5(equinox="J%s" % (epoch))) # Convert geodetic latitude into geocentric latitude to correct for rotation # of the Earth dlat = ((-11. * 60. + 32.743) * np.sin(2 * lat) + 1.1633 * np.sin(4 * lat) \ - 0.0026 * np.sin(6 * lat)) * u.degree geocentric_lat = lat + dlat / 3600. # Calculate distance of observer from Earth center r = alt + 6378160.0 * u.m * (0.998327073 \ + 0.001676438 * np.cos(2 * geocentric_lat) \ - 0.000003510 * np.cos(4 * geocentric_lat) \ + 0.000000008 * np.cos(6 * geocentric_lat)) # Calculate rotational velocity perpendicular to the radius vector # Note: 23.934469591229 is the siderial day in hours for 1986 v = 2 * np.pi * r / (23.934469591229 * 3600 * u.second) # Calculate vdiurnal velocity time.delta_ut1_utc = 0#we get error otherwise. No big dela for this application vdiurnal = v * np.cos(lat) * np.cos(coordinate.dec) \ * np.sin(coordinate.ra - time.sidereal_time("mean")) # Calculate baricentric and heliocentric velocities vh, vb = baryvel(time) # Project along the line of sight projection = np.array([ np.cos(coordinate.dec) * np.cos(coordinate.ra), np.cos(coordinate.dec) * np.sin(coordinate.ra), np.sin(coordinate.dec)]) vbar = (vb * projection).sum() vhel = (vh * projection).sum() # Using baricentric velocity for correction vbar_correction = vdiurnal + vbar vhel_correction = vdiurnal + vhel # [TODO] it may be useful to return other components of velocity or extra # information about the transforms (e.g., gmst, ut, lmst, dlat, lat, vbar, # vhel, etc) return (vbar_correction, vhel_correction)
t_gp = Time('2015-10-19T00:17:47.415') tel1 = Ef tel2 = Jb uvw_mat = np.zeros((len(EVN), 3)) for i in range(len(EVN)): tel = EVN[i] X = tel.x Y = tel.y Z = tel.z Xvec = np.array([X.value, Y.value, Z.value]) ot=Time(t_gp, scale='utc', location=tel1) ot.delta_ut1_utc = 0. obst = ot.sidereal_time('mean') # I'm certain there's a better astropy way to get ot_avg in degrees h = obst.deg*u.deg - crab.ra dec = crab.dec # matrix to transform xyz to uvw mat = np.array([(np.sin(h), np.cos(h), 0), (-np.sin(dec)*np.cos(h), np.sin(dec)*np.sin(h), np.cos(dec)), (np.cos(dec)*np.cos(h), -np.cos(dec)*np.sin(h), np.sin(dec))]) uvw = np.dot(mat, Xvec) uvw_mat[i] = uvw print uvw_mat[0]
class WtoAlgorithm3(object): """ Inherits from WtoDatabase, adds the methods for selection and scoring. It also sets the default parameters for these methods: pwv=1.2, date=now, array angular resolution, transmission=0.5, minha=-5, maxha=3, etc. :return: A WtoAlgorithm instance. Should run: .update_archive .write_ephem .static_param .selector .calc_scores (in this order) """ def __init__(self, data): """ """ self.data = data self.tau = pd.read_csv( self.data._wto_path + 'conf/tau.csv', sep=',', header=0).set_index( 'freq') self.tsky = pd.read_csv( self.data._wto_path + 'conf/tskyR.csv', sep=',', header=0).set_index( 'freq') self.pwvdata = pd.read_pickle( self.data._wto_path + 'conf/pwvdata2.pandas') # .set_index('freq') # self.pwvdata.index = pd.Float64Index( # pd.np.round(self.pwvdata.index.values, decimals=1), name=u'freq') self._pwv = None self._array_res = [] self._date = ephem.now() self._availableobs = False self._time_astropy = TIME self._ALMA_ephem = ALMA1 self._static_calculated = False self.schedblocks = self.data.schedblocks.copy() def set_time_now(self): """ """ self._time_astropy = Time.now() self._time_astropy.delta_ut1_utc = 0 self._time_astropy.location = ALMA self._ALMA_ephem.date = ephem.now() def set_time(self, time_str): """ :param time_str: """ self._time_astropy = Time(time_str) self._time_astropy.delta_ut1_utc = 0 self._time_astropy.location = ALMA self._ALMA_ephem.date = ephem.date(self._time_astropy.iso) def write_ephem_coords(self): """ TODO: deal with multiple targets, which RA to take? TODO: make this table unique... by instance """ self.schedblocks['ephem'] = 'N/A' ephem_sb = pd.merge( self.schedblocks, self.data.target_tables.query( 'solarSystem != "Unspecified" and isQuery == False and ' 'RA == 0'), on='SB_UID').drop_duplicates(['SB_UID', 'ephemeris']).set_index( 'SB_UID', drop=False) results = ephem_sb.apply( lambda x: wtool.calc_ephem_coords( x['solarSystem'], x['ephemeris'], x['SB_UID'], alma=self._ALMA_ephem), axis=1) for r in results.iteritems(): self.schedblocks.ix[r[0], 'RA'] = r[1][0] self.schedblocks.ix[r[0], 'DEC'] = r[1][1] self.schedblocks.ix[r[0], 'ephem'] = r[1][2] def static_param(self, horizon=20): """ :param horizon: """ if self._static_calculated: idx = self.data.target_tables.query( 'solarSystem != "Unspecified" and isQuery == False and ' 'RA == 0').SB_UID.unique() self.obs_param.ix[idx] = self.schedblocks.ix[idx].apply( lambda r: wtool.observable( r['RA'], r['DEC'], self._ALMA_ephem, r['RA'], r['minAR'], r['maxAR'], r['array'], r['SB_UID'], horizon=horizon), axis=1 ) else: self.obs_param = self.schedblocks.apply( lambda r: wtool.observable( r['RA'], r['DEC'], self._ALMA_ephem, r['RA'], r['minAR'], r['maxAR'], r['array'], r['SB_UID'], horizon=horizon), axis=1 ) ind1 = pd.np.around(self.schedblocks.repfreq, decimals=1) ind2 = self.schedblocks.apply( lambda x: str( int(x['maxPWVC'] / 0.05) * 0.05 + (0.05 if (x['maxPWVC'] % 0.05) > 0.02 else 0.)), axis=1) self.schedblocks['transmission_ot'] = self.pwvdata.lookup( ind1, ind2) self.schedblocks['tau_ot'] = self.tau.lookup(ind1, ind2) self.schedblocks['tsky_ot'] = self.tsky.lookup(ind1, ind2) self.schedblocks['airmass_ot'] = self.schedblocks.apply( lambda x: calc_airmass(x['DEC'], transit=True), axis=1) self.schedblocks['tsys_ot'] = ( self.schedblocks.apply( lambda x: calc_tsys(x['band'], x['tsky_ot'], x['tau_ot'], x['airmass_ot']), axis=1)) self.obs_param.rise.fillna(0, inplace=True) self.obs_param['rise datetime'] = self.obs_param.apply( lambda x: dt.datetime.strptime( '2015-01-01 ' + str(int(x['rise'])) + ':' + str(int(60*(x['rise'] - int(x['rise'])))), '%Y-%m-%d %H:%M'), axis=1) self._static_calculated = True def update_apdm(self, obsproject_uid): """ :param obsproject_uid: """ self.data._update_apdm(obsproject_uid) self.schedblocks = self.data.schedblocks.copy() self._static_calculated = False def selector(self, array_kind='TWELVE-M', prj_status=("Ready", "InProgress"), sb_status=("Ready", "Suspended", "Running", "CalibratorCheck", "Waiting"), cycle=("2013.A", "2013.1", "2015.1", "2015.A"), letterg=("A", "B", "C"), bands=("ALMA_RB_03", "ALMA_RB_04", "ALMA_RB_06", "ALMA_RB_07", "ALMA_RB_08", "ALMA_RB_09", "ALMA_RB_10"), check_count=True, conf=None, calc_blratio=False, numant=None, array_id=None, horizon=20., minha=-3., maxha=3., pwv=0.): """ :param array_kind: :param prj_status: :param sb_status: :param cycle: :param letterg: :param bands: :param check_count: :param conf: :param calc_blratio: :param numant: :param array_id: :param horizon: :param minha: :param maxha: :param pwv: :param mintrans: :return: """ if float(pwv) > 8: pwv = 8.0 print self._time_astropy self._aggregate_dfs() self.master_wto_df['array'] = self.master_wto_df.apply( lambda x: 'SEVEN-M' if x['array'] == "ACA" else x['array'], axis=1 ) self.selection_df = self.master_wto_df[['SB_UID']].copy() # select array kind self.selection_df['selArray'] = ( self.master_wto_df['array'] == array_kind) # select valid Prj States self.selection_df['selPrjState'] = ( self.master_wto_df.apply( lambda x: True if x['PRJ_STATUS'] in prj_status else False, axis=1)) # select valid SB States self.selection_df['selSBState'] = ( self.master_wto_df.apply( lambda x: True if x['SB_STATE'] in sb_status else False, axis=1)) # select By grades self.selection_df['selGrade'] = ( self.master_wto_df.apply( lambda x: True if x['CYCLE'] in cycle and x['DC_LETTER_GRADE'] in letterg else False, axis=1) ) # select by band self.selection_df['selBand'] = ( self.master_wto_df.apply( lambda x: True if x['band'] in bands else False, axis=1 ) ) # select if still some observations are left self.selection_df['selCount'] = True if check_count: self.selection_df['selCount'] = ( self.master_wto_df.EXECOUNT > self.master_wto_df.Observed) self.selection_df['selConf'] = True # Array Configuraton Selection (12m) if array_kind == "TWELVE-M": self.master_wto_df['blmax'] = self.master_wto_df.apply( lambda row: rUV.compute_bl(row['minAR'] / 0.8, 100.), axis=1) self.master_wto_df['blmin'] = self.master_wto_df.apply( lambda row: rUV.compute_bl(row['LAScor'], 100., las=True), axis=1) if conf: qstring = '' l = len(conf) - 1 for i, c in enumerate(conf): col = c.replace('-', '_') if i == l: qstring += '%s == "%s"' % (col, c) else: qstring += '%s == "%s" or ' % (col, c) sbs_sel = self.master_wto_df.query(qstring).SB_UID.unique() self.selection_df['selConf'] = self.selection_df.apply( lambda x: True if x['SB_UID'] in sbs_sel else False, axis=1 ) self.master_wto_df['bl_ratio'] = 1. self.master_wto_df['array_ar_cond'] = self.master_wto_df.apply( lambda x: CONFRES[x['BestConf']] if x['BestConf'] in conf else pd.np.NaN, axis=1 ) self.master_wto_df['num_bl_use'] = 630. if calc_blratio: try: array_id = self.bl_arrays.iloc[0, 3] except AttributeError: self._query_array() array_id = self.bl_arrays.iloc[0, 3] array_ar, num_bl, num_ant, ruv = self._get_bl_prop(array_id) self.master_wto_df[['array_ar_cond', 'num_bl_use']] = ( self.master_wto_df.apply( lambda x: self._get_sbbased_bl_prop( ruv, x['blmin'] * 0.9, x['blmax'] * 1.1), axis=1) ) self.master_wto_df['bl_ratio'] = self.master_wto_df.apply( lambda x: calc_bl_ratio( x['array'], x['CYCLE'], x['num_bl_use'], self.selection_df.ix[x.name, 'selConf']), axis=1 ) else: if array_id == 'last': self._query_array() array_id = self.bl_arrays.iloc[0, 3] ar, numbl, numant, ruv = self._get_bl_prop(array_id) self.master_wto_df[['array_ar_cond', 'num_bl_use']] = ( self.master_wto_df.apply( lambda x: self._get_sbbased_bl_prop( ruv, x['blmin'] * 0.9, x['blmax'] * 1.1), axis=1) ) self.selection_df['selConf'] = self.master_wto_df.apply( lambda x: True if (x['array_ar_cond'] > x['minAR']) and (x['array_ar_cond'] < x['maxAR']) else False, axis=1 ) self.master_wto_df['bl_ratio'] = self.master_wto_df.apply( lambda x: calc_bl_ratio( x['array'], x['CYCLE'], x['num_bl_use'], self.selection_df.ix[x.name, 'selConf']), axis=1 ) # Array Configuration Selection (7m or ACA) elif array_kind == "SEVEN-M": if numant is None: numant = 10. self.selection_df['selConf'] = self.master_wto_df.apply( lambda x: True if x['array'] == "SEVEN-M" else False, axis=1 ) self.master_wto_df['blmax'] = pd.np.NaN self.master_wto_df['blmin'] = pd.np.NaN self.master_wto_df['array_ar_cond'] = pd.np.NaN self.master_wto_df['num_bl_use'] = pd.np.NaN self.master_wto_df['bl_ratio'] = self.master_wto_df.apply( lambda x: calc_bl_ratio( x['array'], x['CYCLE'], x['num_bl_use'], self.selection_df.ix[x.name, 'selConf'], numant=numant), axis=1 ) # Array Configuration selection (TP) else: if numant is None: numant = 10. self.selection_df['selConf'] = self.master_wto_df.apply( lambda x: True if x['array'] == "TP-Array" else False, axis=1 ) self.master_wto_df['blmax'] = pd.np.NaN self.master_wto_df['blmin'] = pd.np.NaN self.master_wto_df['array_ar_cond'] = pd.np.NaN self.master_wto_df['num_bl_use'] = pd.np.NaN self.master_wto_df['bl_ratio'] = 1. # select observable: elev, ha, moon & sun distance try: c = SkyCoord( ra=self.master_wto_df.RA*u.degree, dec=self.master_wto_df.DEC*u.degree, location=ALMA, obstime=self._time_astropy) except IndexError: print("Nothing to observe? %s" % len(self.master_wto_df)) self._availableobs = False return ha = self._time_astropy.sidereal_time('apparent') - c.ra self.master_wto_df['HA'] = ha.wrap_at(180*u.degree).value self.master_wto_df['RAh'] = c.ra.hour self.master_wto_df['elev'] = c.transform_to( AltAz(obstime=self._time_astropy, location=ALMA)).alt.value corr_el = ((self.master_wto_df.ephem != 'N/A') & (self.master_wto_df.ephem != 'OK')) self.master_wto_df.ix[corr_el, 'elev'] = -90. self.master_wto_df.ix[corr_el, 'HA'] = -24. self.selection_df['selElev'] = ( self.master_wto_df.elev >= horizon) self.selection_df['selHA'] = ( (self.master_wto_df.HA >= minha) & (self.master_wto_df.HA <= maxha) ) # Sel Conditions, exec. frac ind1 = pd.np.around(self.master_wto_df.repfreq, decimals=1) pwv_str = (str(int(pwv / 0.05) * 0.05 + (0.05 if (pwv % 0.05) > 0.02 else 0.))) self.master_wto_df['transmission'] = self.pwvdata.ix[ ind1, pwv_str].values self.master_wto_df['tau'] = self.tau.ix[ind1, pwv_str].values self.master_wto_df['tsky'] = self.tsky.ix[ind1, pwv_str].values self.master_wto_df['airmass'] = self.master_wto_df.apply( lambda x: calc_airmass(x['elev'], transit=False), axis=1) self.master_wto_df['tsys'] = ( self.master_wto_df.apply( lambda x: calc_tsys(x['band'], x['tsky'], x['tau'], x['airmass']), axis=1)) self.master_wto_df['tsys_ratio'] = self.master_wto_df.apply( lambda x: (x['tsys'] / x['tsys_ot'])**2. if x['tsys'] <= 25000. else pd.np.inf, axis=1) self.master_wto_df['Exec. Frac'] = self.master_wto_df.apply( lambda x: 1 / (x['bl_ratio'] * x['tsys_ratio']) if (x['bl_ratio'] * x['tsys_ratio']) <= 100. else 0., axis=1) self.master_wto_df.set_index('SB_UID', drop=False, inplace=True) self.selection_df.set_index('SB_UID', drop=False, inplace=True) savedate = ALMA1.date savehoriz = ALMA1.horizon ALMA1.horizon = 0.0 lstdate = str(ALMA1.sidereal_time()).split(':') lstdate0 = dt.datetime.strptime( '2014-12-31 ' + str(lstdate[0]) + ':' + str(lstdate[1]), '%Y-%m-%d %H:%M') lstdate1 = dt.datetime.strptime( '2015-01-01 ' + str(lstdate[0]) + ':' + str(lstdate[1]), '%Y-%m-%d %H:%M') lstdate2 = dt.datetime.strptime( '2015-01-02 ' + str(lstdate[0]) + ':' + str(lstdate[1]), '%Y-%m-%d %H:%M') sunrisedate = ALMA1.previous_rising(ephem.Sun()) ALMA1.date = sunrisedate sunriselst = str(ALMA1.sidereal_time()).split(':') sunriselst_h = dt.datetime.strptime( '2015-01-01 ' + str(sunriselst[0]) + ':' + str(sunriselst[1]), '%Y-%m-%d %H:%M') sunsetdate = ALMA1.next_setting(ephem.Sun()) ALMA1.date = sunsetdate sunsetlst = str(ALMA1.sidereal_time()).split(':') sunsetlst_h = dt.datetime.strptime( '2015-01-01 ' + str(sunsetlst[0]) + ':' + str(sunriselst[1]), '%Y-%m-%d %H:%M') self.inputs = pd.DataFrame( pd.np.array([lstdate0, lstdate1, lstdate2, sunsetlst_h - dt.timedelta(1), sunriselst_h, sunsetlst_h, sunriselst_h + dt.timedelta(1)]), index=['lst0', 'lst1', 'lst2', 'set1', 'rise1', 'set2', 'rise2'], columns=['2013.A']).transpose() self.inputs.ix['2013.1', :] = self.inputs.ix['2013.A', :] self.inputs.ix['2015.A', :] = self.inputs.ix['2013.A', :] self.inputs.ix['2015.1', :] = self.inputs.ix['2013.A', :] ALMA1.date = savedate ALMA1.horizon = savehoriz def _aggregate_dfs(self): """ """ self.master_wto_df = pd.merge( self.data.projects.query('phase == "II"')[ ['OBSPROJECT_UID', 'CYCLE', 'CODE', 'DC_LETTER_GRADE', 'PRJ_SCIENTIFIC_RANK', 'PRJ_STATUS']], self.data.sciencegoals.query('hasSB == True')[ ['OBSPROJECT_UID', 'SG_ID', 'OUS_ID', 'ARcor', 'LAScor', 'isTimeConstrained', 'isCalSpecial', 'isSpectralScan']], on='OBSPROJECT_UID', how='left') self.master_wto_df = pd.merge( self.master_wto_df, self.data.sblocks[ ['OBSPROJECT_UID', 'OUS_ID', 'GOUS_ID', 'MOUS_ID', 'SB_UID']], on=['OBSPROJECT_UID', 'OUS_ID'], how='left') self.master_wto_df = pd.merge( self.master_wto_df, self.schedblocks[ ['SB_UID', 'sbName', 'array', 'repfreq', 'band', 'RA', 'DEC', 'maxPWVC', 'minAR', 'maxAR', 'OT_BestConf', 'BestConf', 'two_12m', 'estimatedTime', 'isPolarization', 'ephem', 'airmass_ot', 'transmission_ot', 'tau_ot', 'tsky_ot', 'tsys_ot']], on=['SB_UID'], how='left') self.master_wto_df = pd.merge( self.master_wto_df, self.data.sb_status[['SB_UID', 'SB_STATE', 'EXECOUNT']], on=['SB_UID'], how='left') # noinspection PyUnusedLocal sbs_uid_s = self.master_wto_df.SB_UID.unique() h = ephem.Date(ephem.now() - 7.) # noinspection PyUnusedLocal hs = str(h)[:10].replace('/', '-') qastatus = self.data.aqua_execblock.query( 'SB_UID in @sbs_uid_s').query( 'QA0STATUS in ["Unset", "Pass"] or ' '(QA0STATUS == "SemiPass" and STARTTIME > @hs)').groupby( ['SB_UID', 'QA0STATUS']).QA0STATUS.count().unstack().fillna(0) if 'Pass' not in qastatus.columns.values: qastatus['Pass'] = 0 if 'Unset' not in qastatus.columns.values: qastatus['Unset'] = 0 if 'SemiPass' not in qastatus.columns.values: qastatus['SemiPass'] = 0 qastatus['Observed'] = qastatus.Unset + qastatus.Pass self.master_wto_df = pd.merge( self.master_wto_df, qastatus[ ['Unset', 'Pass', 'Observed', 'SemiPass']], left_on='SB_UID', right_index=True, how='left') self.master_wto_df.Unset.fillna(0, inplace=True) self.master_wto_df.Pass.fillna(0, inplace=True) self.master_wto_df.Observed.fillna(0, inplace=True) self.master_wto_df.SemiPass.fillna(0, inplace=True) self.master_wto_df = pd.merge( self.master_wto_df, self.obs_param[ ['SB_UID', 'rise', 'set', 'note', 'C36_1', 'C36_2', 'C36_3', 'C36_4', 'C36_5', 'C36_6', 'C36_7', 'C36_8', 'twelve_good']], on=['SB_UID'], how='left') def _query_array(self): """ """ bl = str( "select se.SE_TIMESTAMP ts1, sa.SLOG_ATTR_VALUE av1, " "se.SE_ARRAYNAME, se.SE_ID se1 from ALMA.SHIFTLOG_ENTRIES se, " "ALMA.SLOG_ENTRY_ATTR sa " "WHERE se.SE_TYPE=7 and se.SE_TIMESTAMP > SYSDATE - 1/1. " "and sa.SLOG_SE_ID = se.SE_ID and sa.SLOG_ATTR_TYPE = 31 " "and se.SE_LOCATION='OSF-AOS' and se.SE_CORRELATORTYPE = 'BL'") # aca = str( # "select se.SE_TIMESTAMP ts1, sa.SLOG_ATTR_VALUE av1, " # "se.SE_ARRAYNAME, se.SE_ID se1, se.SE_ARRAYFAMILY, " # "se.SE_CORRELATORTYPE from ALMA.SHIFTLOG_ENTRIES se, " # "ALMA.SLOG_ENTRY_ATTR sa " # "WHERE se.SE_TYPE=7 and se.SE_TIMESTAMP > SYSDATE - 1/1. " # "and sa.SLOG_SE_ID = se.SE_ID and sa.SLOG_ATTR_TYPE = 31 " # "and se.SE_LOCATION='OSF-AOS'") try: self.data._cursor.execute(bl) self._bl_arrays_info = pd.DataFrame( self.data._cursor.fetchall(), columns=[rec[0] for rec in self.data._cursor.description] ).sort_values(by='TS1', ascending=False) except ValueError: self._bl_arrays_info = pd.DataFrame( columns=pd.Index( [u'TS1', u'AV1', u'SE_ARRAYNAME', u'SE1'], dtype='object')) print("No BL arrays have been created in the last 6 hours.") self._group_bl_arrays = self._bl_arrays_info[ self._bl_arrays_info.AV1.str.startswith('CM') == False].copy() self.bl_arrays = self._group_bl_arrays.groupby( 'TS1').aggregate( {'SE_ARRAYNAME': max, 'SE1': max, 'AV1': pd.np.count_nonzero}).query( 'AV1 > 30').reset_index().sort_values(by='TS1', ascending=False) # get latest pad info b = str( "select se.SE_TIMESTAMP ts1, se.SE_SUBJECT, " "sa.SLOG_ATTR_VALUE av1, se.SE_ID se1, se.SE_SHIFTACTIVITY " "from alma.SHIFTLOG_ENTRIES se, alma.SLOG_ENTRY_ATTR sa " "WHERE se.SE_TYPE=1 and se.SE_TIMESTAMP > SYSDATE - 2. " "and sa.SLOG_SE_ID = se.SE_ID and sa.SLOG_ATTR_TYPE = 12 " "and se.SE_LOCATION='OSF-AOS'" ) try: self.data._cursor.execute(b) self._shifts = pd.DataFrame( self.data._cursor.fetchall(), columns=[rec[0] for rec in self.data._cursor.description] ).sort_values(by='TS1', ascending=False) except ValueError: self._shifts = pd.DataFrame( columns=pd.Index( [u'TS1', u'AV1', u'SE_ARRAYNAME', u'SE1'], dtype='object')) print("No shiftlogs have been created in the last 6 hours.") last_shift = self._shifts[ self._shifts.SE1 == self._shifts.iloc[0].SE1].copy() last_shift['AV1'] = last_shift.AV1.str.split(':') ante = last_shift.apply(lambda x: x['AV1'][0], axis=1) pads = last_shift.apply(lambda x: x['AV1'][1], axis=1) self._ante_pad = pd.DataFrame({'antenna': ante, 'pad': pads}) def _get_bl_prop(self, array_name): """ :return: :param array_name: """ # In case a bl_array is selected if array_name not in CONF_LIM['minbase'].keys(): id1 = self._bl_arrays_info.query( 'SE_ARRAYNAME == "%s"' % array_name).iloc[0].SE1 ap = self._bl_arrays_info.query( 'SE_ARRAYNAME == "%s" and SE1 == %d' % (array_name, id1) )[['AV1']] ap.rename(columns={'AV1': 'antenna'}, inplace=True) ap = ap[ap.antenna.str.contains('CM') == False] conf = pd.merge(ap, self._ante_pad, left_on='antenna', right_on='antenna')[ ['pad', 'antenna']] conf_file = self.data._data_path + '%s.txt' % array_name conf.to_csv(conf_file, header=False, index=False, sep=' ') ac = rUV.ac.ArrayConfigurationCasaFile() ac.createCasaConfig(conf_file) ruv = rUV.compute_radialuv(conf_file + ".cfg") num_bl = len(ruv) num_ant = len(ap) array_ar = rUV.compute_array_ar(ruv) # If C36 is selected else: conf_file = (self.data._wto_path + 'conf/%s.cfg' % array_name) ruv = rUV.compute_radialuv(conf_file) # noinspection PyTypeChecker array_ar = CONFRES[array_name] num_bl = 36 * 35. / 2. num_ant = 36 return array_ar, num_bl, num_ant, ruv @staticmethod def _get_sbbased_bl_prop(ruv, blmin, blmax): """ :param ruv: :param blmin: :param blmax: :return: """ ruv = ruv[(ruv >= blmin) & (ruv <= blmax)] if len(ruv) < 300.: return pd.Series( [pd.np.NaN, 0], index=['array_ar_cond', 'num_bl_use']) num_bl = len(ruv) array_ar = rUV.compute_array_ar(ruv) return pd.Series([array_ar, num_bl], index=['array_ar_cond', 'num_bl_use'])
def test_sidereal_lon_independent(iers_b, kind, jds, lat, lon, lon_delta): jd1, jd2 = jds t1 = Time(jd1, jd2, scale="ut1", format="jd", location=(lon, lat)) t2 = Time(jd1, jd2, scale="ut1", format="jd", location=(lon+lon_delta, lat)) try: diff = t1.sidereal_time(kind) + lon_delta*u.degree - t2.sidereal_time(kind) except iers.IERSRangeError: assume(False) else: expected_degrees = (diff.to_value(u.degree) + 180) % 360 assert_almost_equal(expected_degrees, 180, atol=1/(60*60*1000))