def get_angles(): global sun_angle_i, moon_angle_i, sun_alt_i, moon_alt_i, obj_alt_i global times, PI, loc global dist_sun, dist_moon, alt_s, alt_m, alt_o, obj_alt, sun_angle, moon_angle, sun_alt, moon_alt, dist_s, dist_m """read in from entry boxes""" sun_angle = float(sun_angle_i.get()) moon_angle = float(moon_angle_i.get()) sun_alt = float(sun_alt_i.get()) moon_alt = float(moon_alt_i.get()) obj_alt = float(obj_alt_i.get()) """whether or not the object is far enough away""" """this returns values in the range [0, 180]; negatives do not matter""" dist_s = [abs(i) > sun_angle for i in dist_sun] dist_m = [abs(i) > moon_angle for i in dist_moon] """whether or not the altitudes are low enough""" alt_s = (coords_s.transform_to( coordinates.AltAz(obstime=times + offset * u.hour, location=loc)).alt.degree < sun_alt) alt_m = (coords_m.transform_to( coordinates.AltAz(obstime=times + offset * u.hour, location=loc)).alt.degree < moon_alt) """object's altitude in degrees""" true_alt_o = (coords_o.transform_to( coordinates.AltAz(obstime=times + offset * u.hour, location=loc)).alt.degree) """whether or not the altitude is high enough""" alt_o = (true_alt_o > obj_alt) """change button after press""" separ_button.config(fg='black', bg='#FFE100')
def altaz2radec(az, alt, t): """ Convert Azimuth-Elevation coordinates into RA-Dec equatorial coordinates It is expected that the observer is NenuFAR in Nancay The conversion is computed for a sky set at time t Parameters ---------- az : float Azimuth in degrees alt : float Elevation in degrees t : str or Time Time at which to compute the corresponding RA Dec Returns ------- RA : float Right Ascension in radians Dec : float Declination in radians """ if not isinstance(t, Time): try: t = Time(t) except: raise ValueError( "\n\t=== Time syntax should be 'YYYY-MM-DD hh:mm:ss' ===") frame = coord.AltAz(obstime=t, location=nancay()) altaz = coord.SkyCoord(az * u.deg, alt * u.deg, frame=frame) radec = altaz.transform_to(coord.FK5(equinox='J2000')) return radec.ra.rad, radec.dec.rad
def _calc(self, datetime, lat: str, lon: str, height=0.0): """Calculate the azimuth and elevation of the sun. Calculates the azimuth and elevation of the sun as seen from the specified time and place (latitude, longitude, sea level). Args: datetime (datetime): datetime to calculate. (aware instance) lat (str): latitude. lon (str): longitude. height (float, optional): height above sea level. Default to 0.0 Returns: az (float): azimuth of sun. el (float): elevation of sun. """ time = ap_t.Time(datetime) loc = ap_crd.EarthLocation( lat=ap_crd.Angle(lat), lon=ap_crd.Angle(lon), height=height ) sun = ap_crd.get_sun(time).transform_to( ap_crd.AltAz(obstime=time, location=loc) ) az = sun.az.degree el = sun.alt.degree return az, el
def triangulate(self, v2_v1, v3_v2): """ Used to triangulate the true latitude and longitude corresponding to the norm of the telescope position. Input ------ v2_v1: list [args,len=2,dtype=float] The difference in [azimuth,altitude] between object 2 and object 1 v3_v2: list [args,len=2,dtype=float] The difference in [azimuth,altitude] between object 3 and object 2 """ ra = cp.Angle(self.cel_calib["RA"], unit=u.hourangle) dec = cp.Angle(self.cel_calib["DEC"], unit=u.deg) v = np.array([ra.rad, dec.rad]).T out = self.triangulation_class.triangulate(v[0], v[1], v[2], v2_v1, v3_v2) n = cp.SkyCoord(out[0][0], out[0][1], unit=u.rad, frame='icrs') npr = cp.EarthLocation(lon=0 * u.deg, lat=90 * u.deg, height=0 * u.m) n.location = npr n.obstime = self.time [self.lon, self.lat] = [180 - n.altaz.az.deg, n.altaz.alt.deg] self.home = [self.lon, self.lat] h = cp.EarthLocation(self.home[0] * u.deg, self.home[1] * u.deg) self.tel_frame = cp.AltAz(location=h, obstime=self.time) v3 = cp.SkyCoord(v[2][0], v[2][1], unit=u.rad) self.tel_pos = v3
def trailPointToAzAlt(visitInfo, wcs, trailPoint, dateOverride, loc): """Get the Azimuth and Altitude corresponding to an x, y image position. Parameters ---------- visitInfo : `lsst.afw.image.VisitInfo` Dict-like metadata for the image. wcs : `lsst.afw.geom.SkyWcs` The WCS for the image. trailPoint : `list` with 2 values [x, y] coordinates of a point in image, in pixels dateOverride : `str` or `None` If the visitInfo date is wrong, this permits a user to pass along the correct date to use. Must be e.g. '2020-01-01' format. loc : `str` One of astropy.coordinates.EarthLocation.get_site_names() Such as "Cerro Tololo Interamerican Observatory" or "Subaru Telescope" Returns ------- aa.az : `astropy.Quantity` Azimuth angle aa.alt : `astropy.Quantity` Altitude angle """ dateObsAstropy = getDateObsAstropy(visitInfo, dateOverride) sky_coord_afw = wcs.pixelToSky( lsst.geom.Point2D(trailPoint[0], trailPoint[1])) sky_coord = coord.SkyCoord(sky_coord_afw.getRa().asDegrees() * u.deg, sky_coord_afw.getDec().asDegrees() * u.deg) location = coord.EarthLocation.of_site(loc) aa_frame = coord.AltAz(obstime=dateObsAstropy, location=location) aa = sky_coord.transform_to(aa_frame) return aa.az, aa.alt
def __compute_azimuth_and_altitude(self): try: alt_and_az = coord.AltAz(location=self.pic_location, obstime=self.pic_datetime) self.altitude = self.sun.transform_to(alt_and_az).alt.degree self.azimuth = self.sun.transform_to(alt_and_az).az.degree except Exception as e: raise e
def __init__(self, centers, time, indices=None): self.centers = centers self.time = time self.indices = indices # figure out where the sun is self.solar_coord = ac.get_sun(time) # subset by the provided indices, if specified if indices is None: lats = centers.lat lons = centers.lon else: lats = centers.lat[indices] lons = centers.lon[indices] # calculate the solar zenith angle at each pixel center. # neglect refraction and height above geoid. pixels = ac.EarthLocation(lons, lats, ellipsoid='GRS80') solar_vecs = self.solar_coord.transform_to( ac.AltAz(obstime=time, location=pixels)) # mask out the non earth pixels, unless the user specified which pixels to calculate if indices is None: mask = ma.getmask(centers.lon) else: mask = None self.solar_zenith = ma.array(solar_vecs.zen.to_value(u.deg), mask=mask) self.solar_az = ma.array(solar_vecs.az.to_value(u.deg), mask=mask)
def can_observe(self): """Check for night and weather""" self.logger.info(self.current_time.iso) # start by checking for 12 degree twilight if coord.get_sun(self.current_time).transform_to( coord.AltAz(obstime=self.current_time, location=P48_loc)).alt.is_within_bounds( upper=-12. * u.deg): if self.historical_observability_year is None: # don't use weather, just use 12 degree twilight return True else: is_observable = self.observability.check_historical_observability( self.current_time, year=self.historical_observability_year) if not is_observable: # optimization: fast-forward to start of next block block_now = block_index(self.current_time) block_end_time = block_index_to_time(block_now, self.current_time, where='end')[0] self.logger.info('Weathered out. Fast forwarding to end of this block: {}'.format( block_end_time.iso)) self.current_time = block_end_time return is_observable else: # daytime # optimization: fast-forward to sunset next_twilight = next_12deg_evening_twilight(self.current_time) self.logger.info('Fast forwarding to 12 deg twilight: {}'.format( next_twilight.iso)) self.current_time = next_twilight return False
def trailPointToAzAlt(visitInfo, wcs, trailPoint, loc="Cerro Tololo Interamerican Observatory"): """Get the Azimuth and Altitude corresponding to an x, y image position. Parameters ---------- visitInfo : `lsst.afw.image.VisitInfo` Dict-like metadata for the image. wcs : `lsst.afw.geom.SkyWcs` The WCS for the image. trailPoint : `list` with 2 values [x, y] coordinates of a point in image, in pixels loc : `str`, optional Default is "Cerro Tololo Interamerican Observatory" """ dateObs = visitInfo.getDate().toPython() dateObsAstropy = Time(dateObs) sky_coord_afw = wcs.pixelToSky( lsst.geom.Point2D(trailPoint[0], trailPoint[1])) sky_coord = coord.SkyCoord(sky_coord_afw.getRa().asDegrees() * u.deg, sky_coord_afw.getDec().asDegrees() * u.deg) location = coord.EarthLocation.of_site(loc) aa_frame = coord.AltAz(obstime=dateObsAstropy, location=location) aa = sky_coord.transform_to(aa_frame) return aa.az, aa.alt
def can_observe(self): """Check for night and weather""" self.logger.info(self.current_time.iso) # start by checking for 12 degree twilight if coord.get_sun(self.current_time).transform_to( coord.AltAz(obstime=self.current_time, location=P48_loc)).alt.is_within_bounds( upper=-12. * u.deg): if self.historical_observability_year is None: # don't use weather, just use 12 degree twilight return True else: return self.observability.check_historical_observability( self.current_time, year=self.historical_observability_year) else: # daytime # optimization: fast-forward to sunset next_twilight = next_12deg_evening_twilight(self.current_time) self.logger.info( 'Fast forwarding to 12 deg twilight: {}'.format(next_twilight)) # TODO: check if this works--may not be possible to change state # here self.current_time = next_twilight return False
def gen_mock_obs(self): """ Generates fake observation data based on possible errors of +/- 5deg. Output: ------ obs: list [args,len=2,dtype=float] Difference in altitude and azimuth for three points, used in triangulation. """ # creates class object based on random errors in telescope placement self.mock_home = [self.lon_est + np.random.uniform(-5,5)*u.deg, self.lat_est + np.random.uniform(-5,5)*u.deg] # creates objects based on errors mock_loc = cp.EarthLocation(self.mock_home[0],self.mock_home[1]) surf = cp.AltAz(location=mock_loc,obstime=self.time) pts = self.altaz_calib.transform_to(surf) # calculate angular differences in altitude and azimuth for points self.v2_v1 = [pts[1].az.rad - pts[0].az.rad, pts[1].alt.rad - pts[0].alt.rad] self.v3_v2 = [pts[2].az.rad - pts[1].az.rad, pts[2].alt.rad - pts[1].alt.rad] return [self.v2_v1, self.v3_v2]
def get_sun_state(lat: float, lon: float, t: datetime): """Given a time and location get the sun position relative to this location. Args: lat (float): latitude lon (float): longitude t (datetime): query time Returns: tuple: zenith and azimuth angles """ loc = coord.EarthLocation(lon=lon * u.deg, lat=lat * u.deg) query_time_string = t.strftime("%Y-%m-%dT%H:%M:%S.%f") t = Time(query_time_string, format="isot", scale="utc") altaz = coord.AltAz(location=loc, obstime=t) sun = coord.get_sun(t) transformer = sun.transform_to(altaz) theta_z = transformer.zen theta_A = transformer.az return theta_z.degree, theta_A.degree
def getSunPos(latitude, longitude, t): loc = coord.EarthLocation(lon=longitude * u.deg, lat=latitude * u.deg) now = Time(t) altaz = coord.AltAz(location=loc, obstime=now) sun = coord.get_sun(now) result = sun.transform_to(altaz) return result
def eff_night(cls,day_ini,earth_loc): """This method calculates the time range between the Sun being at -14deg below the horizon (begin and end of night), for a single night of observation Inputs - day_ini: noon of the initial day of observation, the date at which the night starts - earth_loc: location of the observing site, EarthLocation object Returns - array of astropy.time.core.Time elements, containing begin, middle, and end of the night """ #sample the day by minute aux = day_ini + np.linspace(0,24,1440) * apy_u.hour #Sun position is in GCRS sun1 = apy_coord.get_sun(aux) altaz_frame = apy_coord.AltAz(obstime=aux,location=earth_loc) sun1_altaz = sun1.transform_to(altaz_frame) #transform AltAz to degrees vs,v1,v2,v3 = apy_coord.Angle(sun1_altaz.alt).signed_dms todeg = lambda w,x,y,z: w*(x + y/np.float(60) + z/np.float(60**2)) vect = np.vectorize(todeg,otypes=["f4"]) sun1_deg = vect(vs,v1,v2,v3) #Sun position closest to -14deg, use local minima idx_minim = signal.argrelextrema(np.abs(sun1_deg + 14),np.less) if idx_minim[0].shape[0] != 2: logger.error("Error setting Sun at -14deg") exit(1) #save time for begin, middle, and end of the night ntime = aux[idx_minim] midnight = apy_time.Time(apy_time.Time(np.mean(ntime.jd),format="jd"), scale="utc",format="iso") ntime = np.insert(ntime,1,midnight) return ntime
def solarzenithangle(t, glat, glon, alt_m): """ Parameters ---------- t : datetime time of observation glat : float latitude glon : float longitude alt_m : float observer altitude [meters] Returns ------- sza : float solar zenith angle [degrees] """ obs = ac.EarthLocation(lat=glat * u.deg, lon=glon * u.deg, height=alt_m * u.m) times = astropy.time.Time(t, scale="ut1") sun = ac.get_sun(times) sunobs = sun.transform_to(ac.AltAz(obstime=times, location=obs)) return 90.0 - sunobs.alt.degree
def _perform(self): """ Returns an Argument() with the parameters that depends on this operation. """ self.log.info(f"Running {self.__class__.__name__} action") lat=c.Latitude(self.action.args.kd.get('SITELAT'), unit=u.degree) lon=c.Longitude(self.action.args.kd.get('SITELONG'), unit=u.degree) height=float(self.action.args.kd.get('ALT-OBS')) * u.meter loc = c.EarthLocation(lon, lat, height) temperature=float(self.action.args.kd.get('AMBTEMP'))*u.Celsius pressure=self.cfg['Telescope'].getfloat('pressure', 700)*u.mbar altazframe = c.AltAz(location=loc, obstime=self.action.args.kd.obstime(), temperature=temperature, pressure=pressure) moon = c.get_moon(Time(self.action.args.kd.obstime()), location=loc) sun = c.get_sun(Time(self.action.args.kd.obstime())) moon_alt = ((moon.transform_to(altazframe).alt).to(u.degree)).value moon_separation = (moon.separation(self.action.args.header_pointing).to(u.degree)).value\ if self.action.args.header_pointing is not None else None # Moon illumination formula from Meeus, ÒAstronomical # Algorithms". Formulae 46.1 and 46.2 in the 1991 edition, # using the approximation cos(psi) \approx -cos(i). Error # should be no more than 0.0014 (p. 316). moon_illum = 50*(1 - np.sin(sun.dec.radian)*np.sin(moon.dec.radian)\ - np.cos(sun.dec.radian)*np.cos(moon.dec.radian)\ * np.cos(sun.ra.radian-moon.ra.radian)) self.action.args.moon_alt = moon_alt self.action.args.moon_separation = moon_separation self.action.args.moon_illum = moon_illum return self.action.args
def calculate_elevation(tt, loc=_loc_blindern): sun_time = Time(tt) if ( (tt.hour == 0) and (tt.minute == 0) ): print(f'Calculate solar elevation angle for: {sun_time}') zen_ang = coord.get_sun(sun_time).transform_to( coord.AltAz(obstime=sun_time, location=loc)).alt.degree return zen_ang
def test_horizontal_to_equatorial_astropy(self): from astropy import coordinates as coord from astropy import units as u from astropy import time from astropy.time import Time utc_date = datetime.datetime.utcnow() loc = Dunedin obstime = time.Time(utc_date, scale="utc") eloc = coord.EarthLocation( lat=loc.latitude_deg() * u.deg, lon=loc.longitude_deg() * u.deg, height=loc.alt * u.m, ) altaz_frame = coord.AltAz(obstime=obstime, location=eloc) for el, az in zip(np.linspace(0, 90, 10), np.linspace(0, 259, 10)): elaz = coord.SkyCoord(alt=el * u.deg, az=az * u.deg, frame=altaz_frame) radec = elaz.transform_to(coord.ICRS) ra, dec = loc.horizontal_to_equatorial(utc_date, angle.from_dms(el), angle.from_dms(az)) self.assertAlmostEqual( radec.ra.degree, ra.to_degrees(), -1) # TODO better agreement should be possible. self.assertAlmostEqual( radec.dec.degree, dec.to_degrees(), 1) # TODO better agreement should be possible.
def air_mass(self): mid_time = astrotime.Time(self.jd + self.exptime / 86400., format='jd', scale='utc', location=self.site) target_altaz = self.target.transform_to( coord.AltAz(obstime=mid_time, location=self.site)) return target_altaz.secz
def aztrack(startTime, shotTime, duration, fixedElevation, jumpFrac=0.1, offsetScale=3.0, **ignore_kwargs): kpno = get_kpno() duration = duration * u.hour fixedElevation = fixedElevation * u.degree offsetScale *= u.degree # find positions within the azimuth track at the given elevation # that are within the survey footprint nAz = 100 altaz = coo.AltAz(alt=np.repeat(fixedElevation, nAz), az=np.linspace(0, 360, nAz) * u.degree, obstime=startTime, location=kpno) cel = altaz.transform_to(coo.FK5) bounds = get_desi_bounds() ii = np.where(in_desi_bounds(cel.ra, cel.dec, bounds))[0] if len(ii) == 0: return None # pick the starting point randomly from the list of valid positions np.random.shuffle(ii) i = ii[0] # now build up the track by making random azimuthal offsets az = altaz[i].az coords = [cel[i]] azimuths = [az] times = [startTime] while times[-1] - startTime < duration: dAz = offsetScale * np.random.rand() if np.random.rand() < jumpFrac: dAz *= -3 az = az + dAz t = times[-1] + shotTime * u.second a = coo.AltAz(alt=fixedElevation, az=az, obstime=t, location=kpno) c = a.transform_to(coo.FK5) # stop if this move takes the track out of bounds if not in_desi_bounds(c.ra, c.dec, bounds): break coords.append(c) azimuths.append(az) times.append(t) return dict(coords=coo.SkyCoord(coords), ut=times, azimuths=azimuths)
def alt_az(self, time, cuts=None): """return Altitude & Azimuth by field at a given time""" if cuts is None: index = self.fields.index fieldsAltAz = self.field_coords.transform_to( coord.AltAz(obstime=time, location=self.loc)) else: # warning: specifying cuts makes this much slower index = self.fields[cuts].index fieldsAltAz = self._field_coords(cuts=cuts).transform_to( coord.AltAz(obstime=time, location=self.loc)) return pd.DataFrame({ 'alt': fieldsAltAz.alt, 'az': fieldsAltAz.az }, index=index)
def __call__ (self, t): """Selects the t t should be utc and in datetime or isot format Arguments: t (datetime, str) : should be parsable by astropy.Time """ ttime = at.Time (t, scale='utc', location=self.location) aa = asc.AltAz (alt=self.tt, az=self.pp, obstime=ttime, location=self.location) gc = aa.transform_to (self.gal) return gc
def solar_zenith_angle(alt, lat, lon, time): atime = Time(time) loc = coord.EarthLocation.from_geodetic( height=alt * units.km, lat=lat * units.deg, lon=lon * units.deg, ) altaz = coord.AltAz(location=loc, obstime=atime) sun = coord.get_sun(atime) return sun.transform_to(altaz).zen.value
def sunIsDown(): """Is the sun below the horizon? Warning: on the 2020-Q1 PFS VMs, this takes ~70ms """ now = astroTime.Time(time.time(), format='unix', scale='utc') here = coords.AltAz(obstime=now, location=subaru) sunaltaz = coords.get_sun(now).transform_to(here) return sunaltaz.alt.value < -2
def lookup(target: str) -> (str, str): """ Convert a target name 'M31', 'NGC6946', to a RA/Dec pair using the location of the observatory. Given a string representing a target ('M 31', 'NGC 4584', 'Horsehead Nebula') return an (RA, DEC) string tuple of the form ('hh:mm:sss', 'dd:mm:ss') Parameters ---------- target: str A string representing the target name Returns ------- ra: str String representation of right-ascension; 'hh:mm:ss' dec: str String representation of declination, 'dd:mm:ss' Notes ----- Author: rprechelt """ # location of observatory obs_location = coordinates.EarthLocation( lat=config.general.latitude * units.deg, lon=config.general.longitude * units.deg, height=config.general.altitude * units.m) obs_time = time.Time.now() frame = coordinates.AltAz(obstime=obs_time, location=obs_location) # planetary bodies - TODO: Add moons solar_system = [ 'mercury', 'venus', 'moon', 'mars', 'jupiter', 'saturn', 'uranus', 'neptune', 'pluto' ] coordinates.solar_system_ephemeris.set('de432s') # convert it all to lowercase target = target.lower() # we have a planetary body if target in solar_system: celestial_body = coordinates.get_body(target, obs_time, obs_location) return (celestial_body.ra.to_string(unit=units.hour, sep=':'), celestial_body.dec.to_string(unit=units.degree, sep=':')) else: # stellar body try: target_coordinates = coordinates.SkyCoord.from_name(target) return (target_coordinates.ra.to_string(unit=units.hour, sep=':'), target_coordinates.dec.to_string(unit=units.degree, sep=':')) except Exception as e: return None, None
def solang(row): loc = coord.EarthLocation(lon=row['Longitude'] * u.deg, lat=row['Latitude'] * u.deg) #timy0 = timei.to_pydatetime() timy = Time(row['date_saved'], format='datetime') altaz = coord.AltAz(location=loc, obstime=timy) sun = coord.get_sun(timy) return sun.transform_to(altaz).zen.degree
def calculateSunPosition(self, ntimes): azi_ang = np.zeros((ntimes)) elv_ang = np.zeros((ntimes)) for tt, time in enumerate(self.times): sun_time = Time(time) #UTC time sunpos = coord.AltAz(obstime=sun_time, location=self.location) alt = coord.get_sun(sun_time).transform_to(sunpos).alt azi = coord.get_sun(sun_time).transform_to(sunpos).az elv_ang[tt] = alt.degree azi_ang[tt] = azi.degree self.elevation_angle = elv_ang self.azimuth_angle = azi_ang
def list_filepaths2data(list_filepaths): tar_ra = [] tar_dec = [] fwhm = [] date_obs = [] filters = [] jd = [] lim_mag = [] exp_time = [] iaohanle = EarthLocation(lat=32.778889 * u.deg, lon=78.964722 * u.deg, height=4500 * u.m) for file in list_filepaths: hdu = fits.open(file)[0] data = hdu.data header = hdu.header tar_ra.append(header['TARRA']) tar_dec.append(header['TARDEC']) fwhm.append(header['MED_FWHM']) date_obs.append(header['DATE-OBS']) filters.append(header['FILTER']) jd.append(header['JD']) lim_mag.append(header['LIM_MAG']) exp_time.append(header['EXPTIME']) tar_ra = np.array(tar_ra) tar_dec = np.array(tar_dec) fwhm = np.array(fwhm) filters = np.array(filters) date_obs = np.array(date_obs) observing_time = Time(date_obs) aa = coord.AltAz(location=iaohanle, obstime=observing_time) target = coord.SkyCoord(tar_ra * u.deg, tar_dec * u.deg, frame='icrs') x = target.transform_to(aa) az = x.az.value alt = x.alt.value table = pd.DataFrame( { 'observing_time': jd, 'exposure_time': exp_time, 'azimuth': az, 'altitude': alt, 'fwhm': fwhm, 'lim_mag': lim_mag, 'filter': filters }, columns=[ 'observing_time', 'exposure_time', 'azimuth', 'altitude', 'fwhm', 'lim_mag', 'filter' ]) return table
def _perform(self): """ Returns an Argument() with the parameters that depend on this operation. """ self.log.info(f"Running {self.__class__.__name__} action") if self.action.args.imtype == 'OBJECT': if self.action.args.header_pointing is not None: self.log.info('Determine Moon info') site_lat = c.Latitude(self.cfg['Telescope'].getfloat('site_lat'), unit=u.degree) site_lon = c.Longitude(self.cfg['Telescope'].getfloat('site_lon'), unit=u.degree) site_elevation = self.cfg['Telescope'].getfloat('site_elevation') * u.meter loc = c.EarthLocation(site_lon, site_lat, site_elevation) pressure = self.cfg['Telescope'].getfloat('pressure', 700)*u.mbar obstime = Time(self.action.args.meta.get('date'), location=loc) altazframe = c.AltAz(location=loc, obstime=obstime, pressure=pressure) moon = c.get_moon(obstime) sun = c.get_sun(obstime) moon_alt = ((moon.transform_to(altazframe).alt).to(u.degree)).value moon_separation = (moon.separation(self.action.args.header_pointing).to(u.degree)).value\ if self.action.args.header_pointing is not None else None # Moon illumination formula from Meeus, ÒAstronomical # Algorithms". Formulae 46.1 and 46.2 in the 1991 edition, # using the approximation cos(psi) \approx -cos(i). Error # should be no more than 0.0014 (p. 316). moon_illum = 50*(1 - np.sin(sun.dec.radian)*np.sin(moon.dec.radian)\ - np.cos(sun.dec.radian)*np.cos(moon.dec.radian)\ * np.cos(sun.ra.radian-moon.ra.radian)) self.action.args.meta['moon_alt'] = moon_alt self.action.args.meta['moon_separation'] = moon_separation self.action.args.meta['moon_illum'] = moon_illum elif self.action.args.imtype == 'BIAS': self.log.info('Determine image stats') mean, med, std = stats.sigma_clipped_stats(self.action.args.ccddata.data) self.log.info(f" mean, med, std = {mean:.0f}, {med:.0f}, {std:.0f} (adu)") self.action.args.meta['mean adu'] = mean self.action.args.meta['median adu'] = med self.action.args.meta['std dev adu'] = std elif self.action.args.imtype == 'DARK': mean, med, std = stats.sigma_clipped_stats(self.action.args.ccddata.data) self.log.info(f" mean, med, std = {mean:.0f}, {med:.0f}, {std:.0f} (adu)") self.action.args.meta['mean adu'] = mean self.action.args.meta['median adu'] = med self.action.args.meta['std dev adu'] = std elif self.action.args.imtype in ['DOMEFLAT', 'TWIFLAT']: mean, med, std = stats.sigma_clipped_stats(self.action.args.ccddata.data) self.log.info(f" mean, med, std = {mean:.0f}, {med:.0f}, {std:.0f} (adu)") self.action.args.meta['mean adu'] = mean self.action.args.meta['median adu'] = med self.action.args.meta['std dev adu'] = std return self.action.args
def generate_example_datapack(Nant=10, Ntime=1, Ndir=10, fov=4., alt=90., az=0., time=None, radio_array=None): '''Generate a datapack suitable for testing purposes, if time is None then use current time. The dtec is randomly distributed.''' if radio_array is None: radio_array = generate_example_radio_array(Nant=Nant) if time is None: time = at.Time(strftime("%Y-%m-%dT%H:%M:%S", gmtime()), format='isot') else: if isinstance(time, str): time = at.Time(time, format='isot') antennas = radio_array.get_antenna_locs() antenna_labels = radio_array.get_antenna_labels() Nant = len(antennas) times = at.Time(np.arange(Ntime) * 8. + time.gps, format='gps') phase = ac.AltAz(alt=alt * au.deg, az=az * au.deg, location=radio_array.get_center(), obstime=time).transform_to(ac.ICRS) uvw = UVW(location=radio_array.get_center(), obstime=time, phase=phase) phi = np.random.uniform(low=-fov / 2., high=fov / 2., size=Ndir) * np.pi / 180. theta = np.random.uniform(low=0, high=360., size=Ndir) * np.pi / 180. dirs = np.array([ np.cos(theta) * np.sin(phi), np.sin(theta) * np.sin(phi), np.cos(phi) ]).T dirs = ac.SkyCoord(u=dirs[:, 0], v=dirs[:, 1], w=dirs[:, 2], frame=uvw).transform_to(ac.ICRS) patch_names = np.array(["facet_patch_{}".format(i) for i in range(Ndir)]) dtec = np.random.normal(size=[Nant, Ntime, Ndir]) data_dict = { 'radio_array': radio_array, 'antennas': antennas, 'antenna_labels': antenna_labels, 'times': times, 'timestamps': times.isot, 'directions': dirs, 'patch_names': patch_names, 'dtec': dtec } datapack = DataPack(data_dict=data_dict) datapack.set_reference_antenna(antenna_labels[0]) return datapack