def compute_aberration(ra_eclip, dec_eclip, mjd, magnif): # Given target ecliptic lonlat, and JD, # returns the fully aberrated & magnified LonLat. speed = 0.99365E-4 # Meeus p.151 in radians apexlon = getSunLon(mjd) - 90. if isinstance(ra_eclip, float): apexXYZ = getXYZ(apexlon, 0.) else: apexXYZ = getXYZ(apexlon * np.ones(ra_eclip.shape), np.zeros(ra_eclip.shape)) targetXYZ = getXYZ(ra_eclip, dec_eclip) if len(targetXYZ.shape) > 1: VxT = np.zeros(targetXYZ.shape) TxVxT = np.zeros(targetXYZ.shape) for i in range(targetXYZ.shape[1]): VxT[:, i] = np.cross(apexXYZ[:, i], targetXYZ[:, i]) TxVxT[:, i] = np.cross(targetXYZ[:, i], VxT[:, i]) else: VxT = np.cross(apexXYZ, targetXYZ) TxVxT = np.cross(targetXYZ, VxT) aberXYZ = speed * TxVxT plotXYZ = targetXYZ + magnif * aberXYZ # DANGER with getNormalized(): use only one triplet per call. return getLONLAT(getNormalized(plotXYZ))
def compute_polar_misalignment_rotation_matrix(me_arcsec,ma_arcsec) : """ compute a rotation matrix to move the polar axis to the north vector product """ ha1,dec1=altaz2hadec(alt=LATITUDE-me_arcsec/3600.,az=ma_arcsec/3600.) xyz1=getXYZ(ha1,dec1) ha2,dec2=altaz2hadec(alt=LATITUDE,az=0.) xyz2=getXYZ(ha2,dec2) cross = np.cross(xyz1,xyz2) norme = np.sqrt(np.sum(cross**2)) if norme > 0 : polar_misalignment_rotation = rotation_matrix(cross/norme,np.arcsin(norme)) else : polar_misalignment_rotation = np.eye(3) return polar_misalignment_rotation
def apply_precession(ra, dec, years) : """ see DESI-4957 Equator and zero longitude point glide westward at 0.0139 deg/year, so.. Star ecliptic longitudes increase +0.0139 deg/year from combined lunar and solar torques on the Earth. To precess any sta'’s {RA,DEC}: 1. Convert to ecliptic coordinates {elon, elat} 2. Add 0.0139 deg * number of years to elon 3. Convert back to {RA,DEC} """ deltaELON = 360.* (years / PRECESSION_PERIOD_IN_YEARS) # degrees lon,lat=radec2eclip(ra,dec) xyz_ecliptic = getXYZ(lon,lat) xyz_precessed = np.dot(vecZ(deltaELON), xyz_ecliptic) lon,lat = getLONLAT(xyz_precessed) return eclip2radec(lon,lat)
def hadec2xy(ha,dec,tel_ha,tel_dec) : """ Convert HA,Dec to tangent plane x,y given a telescope pointing tel_ha, tel_dec Args: ha: float or 1D np.array Hour Angle in degrees dec: float or 1D np.array Hour Angle in degrees (same size as ha) tel_ha: float; telescope pointing Hour Angle in degrees tel_dec: float; telescope pointing Dec in degrees Returns: x y float or 1D np.array """ xyz = getXYZ(ha,dec) sh,ch = sincosd(tel_ha) sd,cd = sincosd(tel_dec) rh=np.array([[ch,sh,0],[-sh,ch,0],[0,0,1]]) # rotation about HA axis rd=np.array([[sd,0,-cd],[0,1,0],[+cd,0,sd]]) # rotation about Dec axis tmp = rd.dot(rh.dot(xyz)) x=tmp[1] y=-tmp[0] return x,y
def eclip2radec(lon,lat): # same epoch ecliptic_xyz = getXYZ(lon,lat) equatorial_xyz = np.dot(refX(-OBLIQ), ecliptic_xyz) # roll frame counterclockwise by obliq return getLONLAT(equatorial_xyz)
def radec2eclip(ra,dec): # same epoch equatorial_xyz = getXYZ(ra,dec) ecliptic_xyz = np.dot(refX(OBLIQ), equatorial_xyz) # roll frame clockwise return getLONLAT(ecliptic_xyz)
def tan2radec(x_tan,y_tan,tel_ra,tel_dec,mjd,lst_deg,hexrot_deg, precession = True, aberration = True, polar_misalignment = True, use_astropy = False) : """ Convert ICRS coordinates to tangent plane coordinates Args: xtan: float or 1D np.array with tangent plane coordinates ytan: float or 1D np.array with tangent plane coordinates tel_ra: float, in degrees, telescope pointing RA tel_dec: float, in degrees, telescope pointing Dec mjd: float, Modified Julian Date of observation, in days lst_deg: float, local sidereal time, in degrees hexrot_deg: float, hexapod rotation angle, in degrees Returns RA,Dec in ICRS system (hopefully) Optional arguments: aberration: boolean; compute aberration if True polar_misalignment: boolean; compute polar misalignment if True use_astropy: boolean; use astropy coordinates for precession and aberration if True """ # undo hexapod rotation shex,chex = sincosd(hexrot_deg) x = chex*x_tan+shex*y_tan y = -shex*x_tan+chex*y_tan # need to apply precession ... etc to telescope pointing to interpret the x,y if precession : tel_ra,tel_dec = apply_precession_from_icrs(tel_ra, tel_dec, mjd, use_astropy) if aberration : tel_ra,tel_dec = apply_aberration(tel_ra,tel_dec,mjd, use_astropy) tel_ha = lst_deg - tel_ra if polar_misalignment : polar_misalignment_matrix = compute_polar_misalignment_rotation_matrix(me_arcsec=ME_ARCSEC,ma_arcsec=MA_ARCSEC) tel_ha,tel_dec = getLONLAT(polar_misalignment_matrix.dot(getXYZ(tel_ha,tel_dec))) # we need to apply refraction for the telescope pointing to interpret the x,y tel_alt,tel_az = hadec2altaz(tel_ha,tel_dec) # apply refraction refracted_tel_alt = apply_refraction(tel_alt) # back to ha,dec refracted_tel_ha,refracted_tel_dec = altaz2hadec(refracted_tel_alt,tel_az) # now convert x,y to ha,dec refracted_ha,refracted_dec = xy2hadec(x,y,refracted_tel_ha,refracted_tel_dec) # alt,az alt,az = hadec2altaz(refracted_ha,refracted_dec) # undo refraction alt = undo_refraction(alt) # back to ha,dec ha,dec = altaz2hadec(alt,az) # now polar mis-alignment if polar_misalignment : # inverse matrix polar_misalignment_matrix = compute_polar_misalignment_rotation_matrix(me_arcsec=-ME_ARCSEC,ma_arcsec=-MA_ARCSEC) ha,dec = getLONLAT(polar_misalignment_matrix.dot(getXYZ(ha,dec))) # ra ra = lst_deg - ha if aberration : ra,dec = undo_aberration(ra,dec,mjd, use_astropy) if precession : ra,dec = undo_precession_from_icrs(ra, dec, mjd, use_astropy) return ra,dec
def radec2tan(ra,dec,tel_ra,tel_dec,mjd,lst_deg,hexrot_deg, precession = True, aberration = True, polar_misalignment = True, use_astropy = False) : """ Convert ICRS coordinates to tangent plane coordinates Args: ra: float or 1D np.array with RA in degrees dec: float or 1D np.array with RA in degrees tel_ra: float, in degrees, telescope pointing RA tel_dec: float, in degrees, telescope pointing Dec mjd: float, Modified Julian Date of observation, in days lst_deg: float, local sidereal time, in degrees hexrot_deg: float, hexapod rotation angle, in degrees Returns x_tan,y_tan , tangent plane coordinates: x_tan = sin(theta)*cos(phi) : float on np.array (same shape as input ra,dec) y_tan = sin(theta)*sin(phi) : float on np.array (same shape as input ra,dec) where theta,phi are polar coordinates. theta=0 for along the telescope pointing. phi=0 for a star with the same Dec as the telescope pointing but a larger HA (or smaller RA). Optional arguments: aberration: boolean; compute aberration if True polar_misalignment: boolean; compute polar misalignment if True use_astropy: boolean; use astropy coordinates for precession and aberration if True """ if precession : ra,dec = apply_precession_from_icrs(ra, dec, mjd, use_astropy) tel_ra,tel_dec = apply_precession_from_icrs(tel_ra, tel_dec, mjd, use_astropy) if aberration : ra,dec = apply_aberration(ra,dec,mjd, use_astropy) tel_ra,tel_dec = apply_aberration(tel_ra,tel_dec,mjd, use_astropy) # ha,dec ha = lst_deg - ra tel_ha = lst_deg - tel_ra if polar_misalignment : # rotate polar_misalignment_matrix = compute_polar_misalignment_rotation_matrix(me_arcsec=ME_ARCSEC,ma_arcsec=MA_ARCSEC) ha,dec = getLONLAT(polar_misalignment_matrix.dot(getXYZ(ha,dec))) tel_ha,tel_dec = getLONLAT(polar_misalignment_matrix.dot(getXYZ(tel_ha,tel_dec))) # alt,az alt,az = hadec2altaz(ha,dec) tel_alt,tel_az = hadec2altaz(tel_ha,tel_dec) # apply refraction alt = apply_refraction(alt) tel_alt = apply_refraction(tel_alt) # convert back to ha,dec ha,dec = altaz2hadec(alt,az) tel_ha,tel_dec = altaz2hadec(tel_alt,tel_az) # tangent plane x,y = hadec2xy(ha,dec,tel_ha,tel_dec) # hexapod rotation shex,chex = sincosd(hexrot_deg) return chex*x-shex*y , +shex*x+chex*y