def set_pointings(self, time_arr): """ Set the pointing centers (in ra/dec) based on array location and times. Dec = self.lat RA = What RA is at zenith at a given JD? Also sets the north pole positions in ICRS. """ self.times_jd = time_arr centers = [] north_poles = [] for t in Time(time_arr, scale="utc", format="jd"): zen = AltAz( alt=Angle("90d"), az=Angle("0d"), obstime=t, location=self.telescope_location, ) north = AltAz( alt=Angle("0d"), az=Angle("0d"), obstime=t, location=self.telescope_location, ) zen_radec = zen.transform_to(ICRS()) north_radec = north.transform_to(ICRS()) centers.append([zen_radec.ra.deg, zen_radec.dec.deg]) north_poles.append([north_radec.ra.deg, north_radec.dec.deg]) self.pointing_centers = centers self.north_poles = north_poles
def time2coord(time): point = AltAz(alt=90 * u.deg, az=0 * u.deg, location=location(), obstime=time) sky = point.transform_to(SkyCoord(0 * u.deg, 0 * u.deg, frame='icrs')) gal = point.transform_to(SkyCoord(0 * u.deg, 0 * u.deg, frame='galactic')) ra = sky.ra.rad dec = sky.dec.rad gall = gal.l.rad galb = gal.b.rad return ra, dec, gall, galb
def getradec(self): """Get RA/Dec coordinates""" time = Time(self.d.data['mjd'], format='mjd') point = AltAz(alt=90*u.deg, az=0*u.deg, location=telescope_loc, obstime=time) sky = point.transform_to(SkyCoord(0*u.deg, 0*u.deg, frame='icrs')) self.ra = sky.ra self.dec = sky.dec
def azel2radec(az_deg: float, el_deg: float, lat_deg: float, lon_deg: float, time: datetime, usevallado: bool = False) -> Tuple[float, float]: """ viewing angle (az, el) to sky coordinates (ra, dec) inputs ------ azimuth: degrees clockwize from North elevation: degrees above horizon (neglecting aberration) observer latitude [-90, 90], longitude [-180, 180] (degrees) time: datetime of observation Outputs ------- ecliptic right ascension, declination (degrees) """ if usevallado or Time is None: # non-AstroPy method, less accurate return vazel2radec(az_deg, el_deg, lat_deg, lon_deg, time) obs = EarthLocation(lat=lat_deg * u.deg, lon=lon_deg * u.deg) direc = AltAz(location=obs, obstime=Time(str2dt(time)), az=az_deg * u.deg, alt=el_deg * u.deg) sky = SkyCoord(direc.transform_to(ICRS())) return sky.ra.deg, sky.dec.deg
def apply_wcs_to_photometry(ptable, w, location=lsst_location, zp=None): """ Take a photometry table and add ra and dec cols Parameters ---------- ptable : astropy table Needs columns xcenter, ycenter, and mjd. Assumes all the mjd are the same wcs : wcs object the World Coordinate System object location : astropy EarthLocation object Returns ------- Photometry table with columns added for the alt, az, ra, dec """ time = Time(ptable['mjd'].max(), format='mjd') az, alt = w.all_pix2world(ptable['xcenter'], ptable['ycenter'], 0) coords = AltAz(az=az*u.degree, alt=alt*u.degree, location=location, obstime=time) sky_coords = coords.transform_to(ICRS) ptable['alt_wcs'] = coords.alt ptable['az_wcs'] = coords.az ptable['ra_wcs'] = sky_coords.ra ptable['dec_wcs'] = sky_coords.dec if zp is not None: ptable['mag'] = -2.5*np.log10(ptable['residual_aperture_sum'].data) - zp return ptable
def RunAstrometryCalibration(InputImage,Outputfile=None): """ Does Astrometry calibration of input fits image InputImage. Returns True if calibration succeded.""" # Following lines are TIRSPEC specific for formating the time from fits header obs_timehdr = fits.getval(InputImage,'OBSTIME') obs_datehdr = fits.getval(InputImage,'OBSDATE') time_str = '{0} {1}'.format('-'.join(obs_datehdr.split('.')),obs_timehdr) time = Time(time_str,format='iso',scale='utc') hct_hanle = EarthLocation(lat=32.77944*u.deg, lon=78.9641*u.deg, height=4500*u.m) zenith = AltAz(location=hct_hanle, obstime=time, az=0*u.deg, alt=90*u.deg) ZenithRaDec = zenith.transform_to(ICRS) # Finally call astrometry.net software to calibrate fits image Z_ra = '{0.ra}'.format(ZenithRaDec).split()[0] Z_dec = '{0.dec}'.format(ZenithRaDec).split()[0] ret = subprocess.call(['solve-field','--no-plots', '--ra',Z_ra, '--dec',Z_dec, '--radius','85', '--scale-units','arcsecperpix', '--scale-low','0.28', '--scale-high','0.32', InputImage]) print(ret) if ret == 0: if Outputfile is not None: print('Copying {0} to {1}'.format(os.path.splitext(InputImage)[0]+'.new',Outputfile)) shutil.copy(os.path.splitext(InputImage)[0]+'.new',Outputfile) return True else: return False
def altaz_to_radec(alt=35, az=90, location=None, obstime=None, verbose=False): """Convert alt/az degrees to RA/Dec SkyCoord. Args: alt (int, optional): Altitude, defaults to 35 az (int, optional): Azimute, defaults to 90 (east) location (None|astropy.coordinates.EarthLocation, required): A valid location. obstime (None, optional): Time for object, defaults to `current_time` verbose (bool, optional): Verbose, default False. Returns: astropy.coordinates.SkyCoord: Coordinates corresponding to the AltAz. """ assert location is not None if obstime is None: obstime = current_time() if verbose: print("Getting coordinates for Alt {} Az {}, from {} at {}".format( alt, az, location, obstime)) altaz = AltAz(obstime=obstime, location=location, alt=alt * u.deg, az=az * u.deg) return SkyCoord(altaz.transform_to(ICRS))
def convert_to_gal_coord(self, az_el, time=None): """Converts an AzEl Tuple into a Galactic Tuple from Location Parameters ---------- az_el : (float, float) Azimuth and Elevation to Convert time : AstroPy Time Obj Time of Conversion Returns ------- (float, float) Galactic Latitude and Longitude """ if time is None: time = Time.now() az, el = az_el start_frame = AltAz(obstime=time, location=self.location, alt=el * u.deg, az=az * u.deg) end_frame = Galactic() result = start_frame.transform_to(end_frame) g_lat = float(result.b.degree) g_lng = float(result.l.degree) return g_lat, g_lng
def get_sky_coord(self, pitch: float, yaw: float, time: Time = None): if not time: time = Time.now() alt = Angle(self.get_altitude(pitch), unit='deg') az = Angle(yaw, unit='deg') local_observation = AltAz(az=az, alt=alt, obstime=time, location=self.location) return local_observation.transform_to(ICRS())
def altaz_to_radec(alt=35, az=90, location=None, obstime=None, *args, **kwargs): """ Convert alt/az degrees to RA/Dec SkyCoord Args: alt (int, optional): Altitude, defaults to 35 az (int, optional): Azimute, defaults to 90 (east) location (None, required): A ~astropy.coordinates.EarthLocation location must be passed. obstime (None, optional): Time for object, defaults to `current_time` Returns: `astropy.coordinates.SkyCoord: FK5 SkyCoord """ assert location is not None if obstime is None: obstime = current_time() verbose = kwargs.get('verbose', False) if verbose: print("Getting coordinates for Alt {} Az {}, from {} at {}".format( alt, az, location, obstime)) altaz = AltAz(obstime=obstime, location=location, alt=alt * u.deg, az=az * u.deg) return SkyCoord(altaz.transform_to(ICRS))
def azel2radec(az_deg, el_deg, lat_deg, lon_deg, dtime): obs = EarthLocation(lat=lat_deg * u.deg, lon=lon_deg * u.deg) direc = AltAz(location=obs, obstime=Time(dtime), az=az_deg * u.deg, alt=el_deg * u.deg) sky = SkyCoord(direc.transform_to(ICRS())) return sky.ra.deg, sky.dec.deg
def dt2radec(self, dt): """Datetime to RA/Dec""" time = Time(dt, format='datetime', scale='utc') point = AltAz(alt=90 * u.deg, az=0 * u.deg, location=telescope_loc, obstime=time) sky = point.transform_to(SkyCoord(0 * u.deg, 0 * u.deg, frame='icrs')) return sky.ra.value, sky.dec.value
def azel2radec(az_deg, el_deg, lat_deg, lon_deg, dtime): if usevallado: ra_deg, dec_deg = azel2radecvallado( az_deg,el_deg,lat_deg,lon_deg,dtime) else: #use astropy v1.0 + obs = EarthLocation(lat=lat_deg*u.deg, lon=lon_deg*u.deg) direc = AltAz(location=obs, obstime=Time(dtime), az=az_deg*u.deg, alt=el_deg*u.deg) sky = SkyCoord(direc.transform_to(ICRS())) return sky.ra.deg, sky.dec.deg
def get_zenith_ra_dec(time: str) -> astropy.coordinates.SkyCoord: """Returns RA and Dec of the zenith at Palomar at the given time Args: time (str): MJD time Returns: astropy.coordinates.SkyCoord: object containing the zenith RA and Dec """ time = Time(time, format='mjd') altaz = AltAz(alt=Angle(90, unit=u.deg), az=Angle(0, unit=u.deg), obstime=time, location=loc) return altaz.transform_to(ICRS)
def altaz_to_radec(alt=None, az=None, location=None, obstime=None, **kwargs): """Convert alt/az degrees to RA/Dec SkyCoord. >>> from panoptes.utils import altaz_to_radec >>> from astropy.coordinates import EarthLocation >>> from astropy import units as u >>> keck = EarthLocation.of_site('Keck Observatory') ... >>> altaz_to_radec(alt=75, az=180, location=keck, obstime='2020-02-02T20:20:02.02') <SkyCoord (ICRS): (ra, dec) in deg (281.78..., 4.807...)> >>> # Can use quantities or not. >>> alt = 4500 * u.arcmin >>> az = 180 * u.degree >>> altaz_to_radec(alt=alt, az=az, location=keck, obstime='2020-02-02T20:20:02.02') <SkyCoord (ICRS): (ra, dec) in deg (281.78..., 4.807...)> >>> # Will use current time if none given. >>> altaz_to_radec(alt=35, az=90, location=keck) <SkyCoord (ICRS): (ra, dec) in deg (..., ...)> >>> # Must pass a `location` instance. >>> altaz_to_radec() Traceback (most recent call last): File "<stdin>", line 1, in <module> ... assert location is not None AssertionError Args: alt (astropy.units.Quantity or scalar): Altitude. az (astropy.units.Quantity or scalar): Azimuth. location (astropy.coordinates.EarthLocation, required): A valid location. obstime (None, optional): Time for object, defaults to `current_time` Returns: astropy.coordinates.SkyCoord: Coordinates corresponding to the AltAz. """ assert location is not None if obstime is None: obstime = current_time() alt = get_quantity_value(alt, 'degree') * u.degree az = get_quantity_value(az, 'degree') * u.degree altaz = AltAz(obstime=obstime, location=location, alt=alt, az=az) return SkyCoord(altaz.transform_to(ICRS))
def azalt_to_radec(LOCATION, AZ, ALT): Location = location_config(LOCATION) time = datetime.utcnow() altaz = AltAz(alt=ALT * u.deg, az=AZ * u.deg, location=location, obstime=time) frame = 'icrs' frame = astropy.coordinates.frame_transform_graph.lookup_name(frame)() radec = altaz.transform_to(frame) ra = radec.ra.deg dec = radec.dec.deg return ra, dec
def azel2radec(az_deg, el_deg, lat_deg, lon_deg, t): if Time is None: raise ImportError('You need to install AstroPy') t = str2dt(t) obs = EarthLocation(lat=lat_deg * u.deg, lon=lon_deg * u.deg) direc = AltAz(location=obs, obstime=Time(t), az=az_deg * u.deg, alt=el_deg * u.deg) sky = SkyCoord(direc.transform_to(ICRS())) return sky.ra.deg, sky.dec.deg
def getradec(self): """Get ra/dec""" print('calculating ra/dec...') sys.stdout.flush() time = Time(self.mjd, format='mjd') point = AltAz(alt=90 * u.deg, az=0 * u.deg, location=telescope_loc, obstime=time) sky = point.transform_to(SkyCoord(0 * u.deg, 0 * u.deg, frame='icrs')) self.ra = sky.ra.value self.dec = sky.dec.value return
def to_skycoord(cls, theta=None, phi=None, time=None, coordsys=ICRS): r""" Transforms an input direction given in a local site from alt-az system (theta, phi) to `~astropy.coordinates.SkyCoord` sky coordinates. GRAND convention: receiver convention: phi is oriented West of North, theta from zenith ``` z=Up /\ | | | theta |- /. | / . |/ . --------------> y=West / . . / / . . /- . / phi |/ x=North ``` Parameters ---------- theta : array, scalar, Quantity, Angle Local azimuth of the event phi : array, scalar, Quantity, Angle Local altitude of the event time : sequence, ndarray, number, str, bytes, or Time object Time to use to compute the AltAz coordinates, instance of `~astropy.time.Time` coordsys: class or frame object or SkyCoord object Coordinate system to use, can be an instance of `~astropy.coordinates` such as ICRS, FK5, etc... Returns ------- ICRS Sky coordinates in 'ICRS' """ az = -Angle(phi) zenith = '90d' alt = Angle(zenith) - Angle(theta) time = Time(time) c = AltAz(az=az, alt=alt, obstime=time, location=cls.localsite) return c.transform_to(coordsys)
def zenith_at_birth(address, time): # If the query returns more than one location (e.g., searching on # address='springfield'), this function will use the first returned # location. 'address' can be a full specified address though. location = EarthLocation.of_address(address) birth_time = Time(time) age = (Time.now() - birth_time).to(u.year) zenith = AltAz(obstime=birth_time, location=location, alt=90*u.deg, az=0*u.deg) zenith_icrs = zenith.transform_to(ICRS) return zenith_icrs, age
def coord_trans(ptable, w): """ Take a photometry table and add ra and dec cols """ time = Time(ptable['mjd'].max(), format='mjd') az, alt = w.all_pix2world(ptable['xcenter'], ptable['ycenter'], 0) coords = AltAz(az=az * u.degree, alt=alt * u.degree, location=lsst_location, obstime=time) sky_coords = coords.transform_to(ICRS) ptable['alt_rough'] = coords.alt ptable['az_rough'] = coords.az ptable['ra_rough'] = sky_coords.ra ptable['dec_rough'] = sky_coords.dec return ptable
def test_az_za_astropy(): """ Check the calculated azimuth and zenith angle for a selection of HEALPix pixels against the corresponding astropy calculation. """ Nside = 128 altitude = 0.0 loc = EarthLocation.from_geodetic(longitude, latitude, altitude) obs = observatory.Observatory(latitude, longitude, nside=Nside) t0 = Time(2458684.453187554, format="jd") obs.set_fov(180) zen = AltAz(alt=Angle("90d"), az=Angle("0d"), obstime=t0, location=loc) zen_radec = zen.transform_to(ICRS()) center = [zen_radec.ra.deg, zen_radec.dec.deg] northloc = EarthLocation.from_geodetic(lat="90.d", lon="0d", height=0.0) north_radec = AltAz(alt="90.0d", az="0.0d", obstime=t0, location=northloc).transform_to(ICRS()) yvec = np.array([north_radec.ra.deg, north_radec.dec.deg]) za, az, inds = obs.calc_azza(center, yvec, return_inds=True) ra, dec = hp.pix2ang(Nside, inds, lonlat=True) altaz_astropy = ICRS(ra=Angle(ra, unit="deg"), dec=Angle(dec, unit="deg")).transform_to( AltAz(obstime=t0, location=loc)) za0 = altaz_astropy.zen.rad az0 = altaz_astropy.az.rad if environ.get("VIS", False): hmap = np.zeros(12 * Nside**2) + hp.UNSEEN hmap[inds] = np.unwrap(az0 - az) import IPython IPython.embed() print(np.degrees(za0 - za)) assert np.allclose(za0, za, atol=1e-4) assert np.allclose( np.unwrap(az0 - az), 0.0, atol=3e-4 ) # About 1 arcmin precision. Worst is at the southern horizon.
def azel2radec(az_deg: float, el_deg: float, lat_deg: float, lon_deg: float, time: datetime, *, use_astropy: bool = True) -> tuple[float, float]: """ viewing angle (az, el) to sky coordinates (ra, dec) Parameters ---------- az_deg : float azimuth [degrees clockwize from North] el_deg : float elevation [degrees above horizon (neglecting aberration)] lat_deg : float observer latitude [-90, 90] lon_deg : float observer longitude [-180, 180] (degrees) time : datetime.datetime or str time of observation use_astropy : bool, optional default use astropy. Returns ------- ra_deg : float ecliptic right ascension (degress) dec_deg : float ecliptic declination (degrees) """ if use_astropy and Time is not None: obs = EarthLocation(lat=lat_deg * u.deg, lon=lon_deg * u.deg) direc = AltAz(location=obs, obstime=Time(str2dt(time)), az=az_deg * u.deg, alt=el_deg * u.deg) sky = SkyCoord(direc.transform_to(ICRS())) return sky.ra.deg, sky.dec.deg return vazel2radec(az_deg, el_deg, lat_deg, lon_deg, time)
def get_radec_from_altaz(alt, az, obstime, lat=-30.244639, lon=-70.749417, height=2663.0): """ Get the ra, dec fron the altitude/azimuth and the telescope location using the astropy AltAz function Parameters ---------- alt : float The Altitude (angle) for the object az : float The Azimuth (angle) for the object obstime: float The time of the observation lat: float Optional, the geographic latitude in degrees lon: float Optional, the geographic longitude in degrees height: float Optional, the height in meters Returns ------- ra: float The Right Ascension dec: float """ # Get an astropy location object, using the appropiate astropy units location = EarthLocation.from_geodetic(lon * u.deg, lat * u.deg, height * u.m) # Get an astropy coordinate of frame in the Altitude-Azimuth system elaz = AltAz(alt=alt * u.deg, az=az * u.deg, obstime=obstime, location=location) coords = elaz.transform_to(ICRS) return coords.ra.deg, coords.dec.deg
def azel_value(self, az=None, el=None, n=100): """ Get the :attr:`~nenupy.astro.hpxsky.HpxSky.skymap` values at ``az``, ``el`` coordinates. :param az: Azimuth in horizontal coordinates (degrees) Default: None :type az: `float`, :class:`~numpy.ndarray`, or :class:`~astropy.units.Quantity` :param el: Elevation in horizontal coordinates (degrees) Default: None :type el: `float`, :class:`~numpy.ndarray`, or :class:`~astropy.units.Quantity` :param n: Number of points to evaluate if one coordinate is `None` Default: 100 :type n: `int` :returns: Sky map values at ``az``, ``el`` :rtype: :class:`~numpy.ndarray` """ if (az is not None) and (el is not None): pass elif (az is not None) and (el is None): if isinstance(az, u.Quantity): az = az.to(u.deg).value az = np.ones(n) * az el = np.linspace(0, 90, n) elif (az is None) and (el is not None): if isinstance(el, u.Quantity): el = el.to(u.deg).value az = np.linspace(0, 360, n) el = np.ones(n) * el else: raise Exception('Give at least one coordinate') # Transform to RADEC altaz = AltAz(az=az * u.deg, alt=el * u.deg, location=nenufar_loc, obstime=self.time) radec = altaz.transform_to(ICRS) # Get the indices indices = ang2pix(theta=radec.ra.deg, phi=radec.dec.deg, nside=self.nside, lonlat=True) return self.skymap[indices]
def azel2radec(az_deg, el_deg, lat_deg, lon_deg, t): if PY2 or Time is None: # non-AstroPy method, less accurate return vazel2radec(az_deg, el_deg, lat_deg, lon_deg, t) t = str2dt(t) obs = EarthLocation(lat=lat_deg * u.deg, lon=lon_deg * u.deg) direc = AltAz(location=obs, obstime=Time(t), az=az_deg * u.deg, alt=el_deg * u.deg) sky = SkyCoord(direc.transform_to(ICRS())) return sky.ra.deg, sky.dec.deg
def azel2radec(az_deg: float, el_deg: float, lat_deg: float, lon_deg: float, time: datetime, usevallado: bool = False) -> Tuple[float, float]: """ viewing angle (az, el) to sky coordinates (ra, dec) Parameters ---------- az_deg : float or numpy.ndarray of float azimuth [degrees clockwize from North] el_deg : float or numpy.ndarray of float elevation [degrees above horizon (neglecting aberration)] lat_deg : float observer latitude [-90, 90] lon_deg : float observer longitude [-180, 180] (degrees) time : datetime.datetime time of observation usevallado : bool, optional default use astropy. If true, use Vallado algorithm Returns ------- ra_deg : float or numpy.ndarray of float ecliptic right ascension (degress) dec_deg : float or numpy.ndarray of float ecliptic declination (degrees) """ if usevallado or Time is None: # non-AstroPy method, less accurate return vazel2radec(az_deg, el_deg, lat_deg, lon_deg, time) obs = EarthLocation(lat=lat_deg * u.deg, lon=lon_deg * u.deg) direc = AltAz(location=obs, obstime=Time(str2dt(time)), az=az_deg * u.deg, alt=el_deg * u.deg) sky = SkyCoord(direc.transform_to(ICRS())) return sky.ra.deg, sky.dec.deg
def azel2radec(az_deg, el_deg, lat_deg, lon_deg, t): """convert astronomical target horizontal azimuth, elevation to ecliptic right ascension, declination (degrees)""" if PY2 or Time is None: # non-AstroPy method, less accurate return vazel2radec(az_deg, el_deg, lat_deg, lon_deg, t) t = str2dt(t) obs = EarthLocation(lat=lat_deg * u.deg, lon=lon_deg * u.deg) direc = AltAz(location=obs, obstime=Time(t), az=az_deg * u.deg, alt=el_deg * u.deg) sky = SkyCoord(direc.transform_to(ICRS())) return sky.ra.deg, sky.dec.deg
def set_pointings(self, time_arr): """ Set the pointing centers (in ra/dec) based on array location and times. Dec = self.lat RA = What RA is at zenith at a given JD? """ telescope_location = EarthLocation.from_geodetic(self.lon, self.lat) self.times_jd = time_arr centers = [] for t in Time(time_arr, scale='utc', format='jd'): zen = AltAz(alt=Angle('89d'), az=Angle('0d'), obstime=t, location=telescope_location) zen_radec = zen.transform_to(ICRS) centers.append([zen_radec.ra.deg, zen_radec.dec.deg]) self.pointing_centers = centers
def altaz_to_radec(alt=35, az=90, location=None, obstime=None, **kwargs): """Convert alt/az degrees to RA/Dec SkyCoord. >>> from panoptes.utils import altaz_to_radec >>> from astropy.coordinates import EarthLocation >>> keck = EarthLocation.of_site('Keck Observatory') ... >>> altaz_to_radec(alt=75, az=180, location=keck, obstime='2020-02-02T20:20:02.02') <SkyCoord (ICRS): (ra, dec) in deg (281.78..., 4.807...)> >>> # Will use current time if none given >>> altaz_to_radec(location=keck) <SkyCoord (ICRS): (ra, dec) in deg (..., ...)> >>> altaz_to_radec(location=keck, obstime='2020-02-02T20:20:02.02') <SkyCoord (ICRS): (ra, dec) in deg (338.4096..., 11.1175...)> >>> # Must pass a `location` instance. >>> altaz_to_radec() Traceback (most recent call last): File "<stdin>", line 1, in <module> ... assert location is not None AssertionError Args: alt (int, optional): Altitude, defaults to 35 az (int, optional): Azimute, defaults to 90 (east) location (None|astropy.coordinates.EarthLocation, required): A valid location. obstime (None, optional): Time for object, defaults to `current_time` Returns: astropy.coordinates.SkyCoord: Coordinates corresponding to the AltAz. """ assert location is not None if obstime is None: obstime = current_time() altaz = AltAz(obstime=obstime, location=location, alt=alt * u.deg, az=az * u.deg) return SkyCoord(altaz.transform_to(ICRS))
def llh_to_radec(lon, lat, height, obstime, location): """Convert latitude, longitude, height to apparent Ra/Dec at a given site""" with warnings.catch_warnings(): warnings.simplefilter("ignore") altaz_near = AltAz( az=0 * u.deg, alt=90 * u.deg, distance=height, obstime=obstime, location=EarthLocation(lon=lon, lat=lat, height=0), ).transform_to(AltAz(location=location, obstime=obstime)) altaz_far = AltAz(location=location, obstime=obstime, alt=altaz_near.alt, az=altaz_near.az) return altaz_far.transform_to(FK5)
def get_coords_from_altaz_offset(obstimes, el, az, xoffs, yoffs, location, inplace=False): """""" # Calculate observing angle if not inplace: el = copy.deepcopy(el) az = copy.deepcopy(az) el += yoffs.to(u.rad).value az += xoffs.to(u.rad).value / np.cos(el) coords = AltAz(az=Angle(az), alt=Angle(el), location=location, obstime=obstimes) # According to line_profiler, coords.icrs is *by far* the longest # operation in this function, taking between 80 and 90% of the # execution time. Need to study a way to avoid this. coords_deg = coords.transform_to(ICRS) ra = np.radians(coords_deg.ra) dec = np.radians(coords_deg.dec) return ra, dec
def azel2radec(az_deg: float, el_deg: float, lat_deg: float, lon_deg: float, time: datetime, usevallado: bool = False) -> Tuple[float, float]: """ viewing angle (az, el) to sky coordinates (ra, dec) Parameters ---------- az_deg : float or numpy.ndarray of float azimuth [degrees clockwize from North] el_deg : float or numpy.ndarray of float elevation [degrees above horizon (neglecting aberration)] lat_deg : float observer latitude [-90, 90] lon_deg : float observer longitude [-180, 180] (degrees) time : datetime.datetime or str time of observation usevallado : bool, optional default use astropy. If true, use Vallado algorithm Returns ------- ra_deg : float or numpy.ndarray of float ecliptic right ascension (degress) dec_deg : float or numpy.ndarray of float ecliptic declination (degrees) """ if usevallado or Time is None: # non-AstroPy method, less accurate return vazel2radec(az_deg, el_deg, lat_deg, lon_deg, time) obs = EarthLocation(lat=lat_deg * u.deg, lon=lon_deg * u.deg) direc = AltAz(location=obs, obstime=Time(str2dt(time)), az=az_deg * u.deg, alt=el_deg * u.deg) sky = SkyCoord(direc.transform_to(ICRS())) return sky.ra.deg, sky.dec.deg
def map_sky(skymap, obstime, az_grid, za_grid): """ Converted from Randall Wayth's IDL code. Map skymap onto grid of arbitrary size """ out = az_grid * 0.0 # new array for gridded sky grid = AltAz(az=Angle(az_grid, unit=astropy.units.deg), alt=Angle(90 - za_grid, unit=astropy.units.deg), obstime=obstime, location=config.MWAPOS) grid_equatorial = grid.transform_to(ICRS) ra = grid_equatorial.ra.hour dec_grid = grid_equatorial.dec.deg size_dec = skymap.shape[0] size_ra = skymap.shape[1] p = za_grid < 90.0 + EPS # array indices for visible sky # the following assumes RA=0 in centre # of the sky image and increases to the left. ra_index = (((36 - ra) % 24) / 24) * size_ra dec_index = (dec_grid / 180.0 + 0.5) * size_dec print ra_index.min(), ra_index.max() print dec_index.min(), dec_index.max() # select pixels of sky map, using ra and dec index values # rounded down to nearest index integer # print p # print numpy.rint(ra_index[p]),numpy.rint(dec_index[p]) print numpy.rint(ra_index[p]).astype(int) print numpy.rint(dec_index[p]).astype(int) print skymap.shape out[p] = skymap[dec_index[p].astype(int), ra_index[p].astype(int)] return out
def altaz_to_radec(alt=35, az=90, location=None, obstime=None, *args, **kwargs): """ Convert alt/az degrees to RA/Dec SkyCoord Args: alt (int, optional): Altitude, defaults to 35 az (int, optional): Azimute, defaults to 90 (east) location (None, required): A ~astropy.coordinates.EarthLocation location must be passed. obstime (None, optional): Time for object, defaults to `current_time` Returns: `astropy.coordinates.SkyCoord: FK5 SkyCoord """ assert location is not None if obstime is None: obstime = current_time() verbose = kwargs.get('verbose', False) if verbose: print("Getting coordinates for Alt {} Az {}, from {} at {}".format(alt, az, location, obstime)) altaz = AltAz(obstime=obstime, location=location, alt=alt * u.deg, az=az * u.deg) return SkyCoord(altaz.transform_to(ICRS))
def altaz2radec(altaz, location, obstime=None, epoch_RA=2000.0, time_type=None): """ ---------------------------------------------------------------------------- Convert Alt-Az to RA-Dec with accurate ephemeris Inputs: altaz [numpy array] Altitude and Azimuth as a Nx2 numpy array. All units in degrees location [instance of class astropy.coordinates.EarthLocation] Location of the observer provided as an instance of class astropy.coordinates.EarthLocation obstime [scalar, string, or instance of class astropy.time.Time] The time or epoch which applies to input altaz. It can be a scalar (in JD or JYear), string (JYear string prefixed with 'J' or ISO or ISOT), or an instance of class astropy.time.Time. The appropriate format must be specified in input time_type. If set to None (default), it will be set equal to epoch_RA. epoch_RA [scalar, string, or instance of class astropy.time.Time] The time or epoch which applies to output radec. It can be a scalar (in JD or JYear), string (JYear string prefixed with 'J' or ISO or ISOT), or an instance of class astropy.time.Time. The appropriate format must be specified in input time_type. It must be in the same format as the one obstime is specified in. If set to 2000.0 (default), it is assumed to be in 'jyear' format. If set to None, it will be set equal to default of 2000.0 in 'jyear' format. time_type [string] Specifies the format in which obstime and epoch_RA are provided. Accepted values are 'jd' (Julian Day), 'jyear' (Julian year), 'iso' or 'isot'. If set to None (default) and if obstime and/or epoch_RA is a scalar, the corresponding scalar entries are assumed to be in Julian Year. Output: The output radec as a numpy array of shape (N,2) in units of degrees is returned at the epoch specified in epoch_RA. ---------------------------------------------------------------------------- """ if isinstance(altaz, NP.ndarray): if altaz.size == 2: altaz = altaz.reshape(1,-1) if altaz.ndim != 2: raise ValueError('Input altaz must be a numpy array of shape (N,2)') if altaz.shape[1] != 2: raise ValueError('Input altaz must be a numpy array of shape (N,2)') elif not isinstance(altaz, AltAz): raise TypeError('Input altaz must be a numpy array or an instance of class astropy.coordinates.AltAz') if not isinstance(location, EarthLocation): raise TypeError('Input location must be an instance of class astropy.coordinates.EarthLocation') if epoch_RA is not None: if isinstance(epoch_RA, (int,float)): if (time_type is None) or (time_type.lower() == 'jyear'): equinox_RA = Time(epoch_RA, scale='utc', format='jyear') elif time_type.lower() == 'jd': equinox_RA = Time(epoch_RA, scale='utc', format='jd') elif isinstance(epoch_RA, str): if time_type.lower() == 'jyear': equinox_RA = Time('J{0:.9f}'.format(epoch_RA), scale='utc', format='jyear_str') elif (time_type.lower() == 'iso') or (time_type.lower() == 'isot'): equinox_RA = Time(epoch_RA, scale='utc', format=time_type.lower()) elif isinstance(epoch_RA, Time): equinox_RA = copy.copy(epoch_RA) else: raise TypeError('Input epoch_RA is invalid or currently not accepted') else: equinox_RA = Time(2000.0, format='jyear', scale='utc') warnings.warn('No epoch_RA provided. Setting epoch to {0}'.format(equinox_RA.jyear_str)) if obstime is not None: if isinstance(obstime, (int,float)): if (time_type is None) or (time_type.lower() == 'jyear'): equinox_altaz = Time(obstime, scale='utc', format='jyear') elif time_type.lower() == 'jd': equinox_altaz = Time(obstime, scale='utc', format='jd') elif isinstance(obstime, str): if time_type.lower() == 'jyear': equinox_altaz = Time('J{0:.9f}'.format(obstime), scale='utc', format='jyear_str') if (time_type.lower() == 'iso') or (time_type.lower() == 'isot'): equinox_altaz = Time(obstime, scale='utc', format=time_type.lower()) elif isinstance(obstime, Time): equinox_altaz = copy.copy(obstime) else: raise TypeError('Input obstime is invalid or currently not accepted') else: if isinstance(altaz, AltAz): equinox_altaz = copy.deepcopy(altaz.obstime) else: equinox_altaz = copy.copy(equinox_RA) warnings.warn('No obstime provided. Setting obstime to {0}'.format(equinox_altaz.jyear_str)) if isinstance(altaz, AltAz): elaz = copy.deepcopy(altaz) else: elaz = AltAz(alt=altaz[:,0]*U.deg, az=altaz[:,1]*U.deg, obstime=equinox_altaz, location=location) coords_radec = elaz.transform_to(FK5(equinox=equinox_RA)) radec = NP.hstack((coords_radec.ra.deg.reshape(-1,1), coords_radec.dec.deg.reshape(-1,1))) return radec
def make_test_observation_table(observatory_name='HESS', n_obs=10, datestart=None, dateend=None, use_abs_time=False, random_state='random-seed'): """Make a test observation table. For the moment, only random observation tables are created. If `datestart` and `dateend` are specified, the starting time of the observations will be restricted to the specified interval. These parameters are interpreted as date, the precise hour of the day is ignored, unless the end date is closer than 1 day to the starting date, in which case, the precise time of the day is also considered. Parameters ---------- observatory_name : str Name of the observatory; a list of choices is given in `~gammapy.obs.observatory_locations`. n_obs : int Number of observations for the obs table. datestart : `~astropy.time.Time`, optional Starting date for random generation of observation start time. dateend : `~astropy.time.Time`, optional Ending date for random generation of observation start time. use_abs_time : bool, optional Use absolute UTC times instead of [MET]_ seconds after the reference. random_state : {int, 'random-seed', 'global-rng', `~numpy.random.RandomState`}, optional Defines random number generator initialisation. Passed to `~gammapy.utils.random.get_random_state`. Returns ------- obs_table : `~gammapy.obs.ObservationTable` Observation table. """ random_state = get_random_state(random_state) n_obs_start = 1 obs_table = ObservationTable() # build a time reference as the start of 2010 dateref = Time('2010-01-01T00:00:00', format='isot', scale='utc') dateref_mjd_fra, dateref_mjd_int = np.modf(dateref.mjd) # define table header obs_table.meta['OBSERVATORY_NAME'] = observatory_name obs_table.meta['MJDREFI'] = dateref_mjd_int obs_table.meta['MJDREFF'] = dateref_mjd_fra if use_abs_time: # show the observation times in UTC obs_table.meta['TIME_FORMAT'] = 'absolute' else: # show the observation times in seconds after the reference obs_table.meta['TIME_FORMAT'] = 'relative' header = obs_table.meta # obs id obs_id = np.arange(n_obs_start, n_obs_start + n_obs) obs_table['OBS_ID'] = obs_id # obs time: 30 min time_observation = Quantity(30. * np.ones_like(obs_id), 'minute').to('second') obs_table['TIME_OBSERVATION'] = time_observation # livetime: 25 min time_live = Quantity(25. * np.ones_like(obs_id), 'minute').to('second') obs_table['TIME_LIVE'] = time_live # start time # - random points between the start of 2010 and the end of 2014 (unless # otherwise specified) # - using the start of 2010 as a reference time for the header of the table # - observations restrict to night time (only if specified time interval is # more than 1 day) # - considering start of astronomical day at midday: implicit in setting # the start of the night, when generating random night hours if datestart == None: datestart = Time('2010-01-01T00:00:00', format='isot', scale='utc') if dateend == None: dateend = Time('2015-01-01T00:00:00', format='isot', scale='utc') time_start = random_state.uniform(datestart.mjd, dateend.mjd, len(obs_id)) time_start = Time(time_start, format='mjd', scale='utc') # check if time interval selected is more than 1 day if (dateend - datestart).jd > 1.: # keep only the integer part (i.e. the day, not the fraction of the day) time_start_f, time_start_i = np.modf(time_start.mjd) time_start = Time(time_start_i, format='mjd', scale='utc') # random generation of night hours: 6 h (from 22 h to 4 h), leaving 1/2 h # time for the last run to finish night_start = Quantity(22., 'hour') night_duration = Quantity(5.5, 'hour') hour_start = random_state.uniform(night_start.value, night_start.value + night_duration.value, len(obs_id)) hour_start = Quantity(hour_start, 'hour') # add night hour to integer part of MJD time_start += hour_start if use_abs_time: # show the observation times in UTC time_start = Time(time_start.isot) else: # show the observation times in seconds after the reference time_start = time_relative_to_ref(time_start, header) # converting to quantity (better treatment of units) time_start = Quantity(time_start.sec, 'second') obs_table['TIME_START'] = time_start # stop time # calculated as TIME_START + TIME_OBSERVATION if use_abs_time: time_stop = Time(obs_table['TIME_START']) time_stop += TimeDelta(obs_table['TIME_OBSERVATION']) else: time_stop = TimeDelta(obs_table['TIME_START']) time_stop += TimeDelta(obs_table['TIME_OBSERVATION']) # converting to quantity (better treatment of units) time_stop = Quantity(time_stop.sec, 'second') obs_table['TIME_STOP'] = time_stop # az, alt # random points in a sphere above 45 deg altitude az, alt = sample_sphere(size=len(obs_id), lon_range=Angle([0, 360], 'degree'), lat_range=Angle([45, 90], 'degree'), random_state=random_state) az = Angle(az, 'degree') alt = Angle(alt, 'degree') obs_table['AZ'] = az obs_table['ALT'] = alt # RA, dec # derive from az, alt taking into account that alt, az represent the values # at the middle of the observation, i.e. at time_ref + (TIME_START + TIME_STOP)/2 # (or better: time_ref + TIME_START + (TIME_OBSERVATION/2)) # in use_abs_time mode, the time_ref should not be added, since it's already included # in TIME_START and TIME_STOP az = Angle(obs_table['AZ']) alt = Angle(obs_table['ALT']) if use_abs_time: obstime = Time(obs_table['TIME_START']) obstime += TimeDelta(obs_table['TIME_OBSERVATION']) / 2. else: obstime = time_ref_from_dict(obs_table.meta) obstime += TimeDelta(obs_table['TIME_START']) obstime += TimeDelta(obs_table['TIME_OBSERVATION']) / 2. location = observatory_locations[observatory_name] alt_az_coord = AltAz(az=az, alt=alt, obstime=obstime, location=location) sky_coord = alt_az_coord.transform_to(FK5) obs_table['RA'] = sky_coord.ra obs_table['DEC'] = sky_coord.dec # positions # number of telescopes # random integers between 3 and 4 n_tels_min = 3 n_tels_max = 4 n_tels = random_state.randint(n_tels_min, n_tels_max + 1, len(obs_id)) obs_table['N_TELS'] = n_tels # muon efficiency # random between 0.6 and 1.0 muon_efficiency = random_state.uniform(low=0.6, high=1.0, size=len(obs_id)) obs_table['MUON_EFFICIENCY'] = muon_efficiency return obs_table
Greenland = EarthLocation( lat=Angle(72.5796, 'deg'), lon=Angle(-38.4592, 'deg'), height=3200 * u.m), Tibet = EarthLocation( lat=Angle(32.3166667, 'deg'), lon=Angle(80.0166666667, 'deg'), height=5100 * u.m), ) location = locations[LOCATION] start_time = Time(datetime.datetime(2015, 8, 1), scale='ut1') sampling_interval = TimeDelta(SAMPLING, format="sec") time = start_time + sampling_interval * np.arange(0., HOURS*3600/SAMPLING) # zenith altaz = AltAz(az=Angle(0., unit=u.degree), alt=ELEVATION, obstime=time, location=location) radec = altaz.transform_to(ICRS) ra_zenith = radec.ra.radian dec_zenith = radec.dec.radian # local north altaz = AltAz(az=Angle(0., unit=u.degree), alt=Angle(0., unit=u.degree), obstime=time, location=location) radec = altaz.transform_to(ICRS) ra_north = radec.ra.radian dec_north = radec.dec.radian import pandas as pd pd.DataFrame({"ra_zenith_rad":ra_zenith, "dec_zenith_rad":dec_zenith, "ra_north_rad":ra_north, "dec_north_rad":dec_north}, index=time.datetime).to_hdf("zenith_pointing_" + LOCATION.lower() + ".h5", "data")