def airmassPP(zangle): """ Calculate airmass for plane parallel atmosphere. Parameters ---------- zangle : float or array The zenith angle in degrees. Returns ------- Airmass : float or array The airmass assuming a plane parallel atmosphere. """ return 1.0 / np.cos(PC.degtorad(zangle))
def airmassPP(zangle): """ Calculate airmass for plane parallel atmosphere. Parameters ---------- zangle : float or array The zenith angle in degrees. Returns ------- Airmass : float or array The airmass assuming a plane parallel atmosphere. """ return 1.0/np.cos(PC.degtorad(zangle))
def airmassSpherical(zangle, obsAltitude, rearth=6371.0, yatm=10.0): """ Calculate the airmass for a given zenith angle and observer altitude. This routine uses a geometric formula for a homogeneous, spherical atmosphere with an elevated observer. .. note:: In this model, the airmass is *not* necessarily one toward the zenith. Parameters ---------- zangle : float Zenith angle of an object in deg. obsAltitude : float Elevation of the observer in meter. rearth : float, optional Earth's radius in km. yatm : float, optional Height of the atmosphere in km. Returns ------- Airmass : float The airmass. """ # Convert observer's altitude to km to have # consistent units obsAltitude = obsAltitude/1000.0 r = (rearth/yatm) y = (obsAltitude/yatm) # Find maximal zenith angle zmax = 180.0 - PC.radtodeg(np.arcsin(rearth/(rearth + obsAltitude))) if zangle > zmax: raise(PE.PyAValError("Zenith angle is too large. The maximum allowed angle is " + str(zmax) + " deg.", \ solution="Use an angle within the limit. Check observer's altitude.")) # Convert into deg zangle = PC.degtorad(zangle) return np.sqrt( ( r + y )**2 * np.cos(zangle)**2 + 2.*r*(1.-y) - y**2 + 1.0 ) - \ (r+y)*np.cos(zangle)
def airmassSpherical(zangle, obsAltitude, rearth=6371.0, yatm=10.0): """ Calculate the airmass for a given zenith angle and observer altitude. This routine uses a geometric formula for a homogeneous, spherical atmosphere with an elevated observer. .. note:: In this model, the airmass is *not* necessarily one toward the zenith. Parameters ---------- zangle : float Zenith angle of an object in deg. obsAltitude : float Elevation of the observer in meter. rearth : float, optional Earth's radius in km. yatm : float, optional Height of the atmosphere in km. Returns ------- Airmass : float The airmass. """ # Convert observer's altitude to km to have # consistent units obsAltitude = obsAltitude / 1000.0 r = (rearth / yatm) y = (obsAltitude / yatm) # Find maximal zenith angle zmax = 180.0 - PC.radtodeg(np.arcsin(rearth / (rearth + obsAltitude))) if zangle > zmax: raise(PE.PyAValError("Zenith angle is too large. The maximum allowed angle is " + str(zmax) + " deg.", \ solution="Use an angle within the limit. Check observer's altitude.")) # Convert into deg zangle = PC.degtorad(zangle) return np.sqrt( ( r + y )**2 * np.cos(zangle)**2 + 2.*r*(1.-y) - y**2 + 1.0 ) - \ (r+y)*np.cos(zangle)
def helcorr(obs_long, obs_lat, obs_alt, ra2000, dec2000, jd, debug=False): """ Calculate barycentric velocity correction. This function calculates the motion of an observer in the direction of a star. In contract to :py:func:`baryvel` and :py:func:`baryCorr`, the rotation of the Earth is taken into account. .. note:: This function was ported from the REDUCE IDL package. See Piskunov & Valenti 2002, A&A 385, 1095 for a detailed description of the package and/or visit http://www.astro.uu.se/~piskunov/RESEARCH/REDUCE/ .. warning:: Contrary to the original implementation the longitude increases toward the East and the right ascension is given in degrees instead of hours. The JD is given as is, in particular, nothing needs to be subtracted. Parameters ---------- obs_long : float Longitude of observatory (degrees, **eastern** direction is positive) obs_lat : float Latitude of observatory [deg] obs_alt : float Altitude of observatory [m] ra2000 : float Right ascension of object for epoch 2000.0 [deg] dec2000 : float Declination of object for epoch 2000.0 [deg] jd : float Julian date for the middle of exposure. Returns ------- Barycentric correction : float The barycentric correction accounting for the rotation of the Earth, the rotation of the Earth's center around the Earth-Moon barycenter, and the motion of the Earth-Moon barycenter around the center of the Sun [km/s]. HJD : float Heliocentric Julian date for middle of exposure. Notes ----- :IDL REDUCE - Documentation: Calculates heliocentric Julian date, barycentric and heliocentric radial velocity corrections from: INPUT: <OBSLON> Longitude of observatory (degrees, western direction is positive) <OBSLAT> Latitude of observatory (degrees) <OBSALT> Altitude of observatory (meters) <RA2000> Right ascension of object for epoch 2000.0 (hours) <DE2000> Declination of object for epoch 2000.0 (degrees) <JD> Julian date for the middle of exposure [DEBUG=] set keyword to get additional results for debugging OUTPUT: <CORRECTION> barycentric correction - correction for rotation of earth, rotation of earth center about the earth-moon barycenter, earth-moon barycenter about the center of the Sun. <HJD> Heliocentric Julian date for middle of exposure Algorithms used are taken from the IRAF task noao.astutils.rvcorrect and some procedures of the IDL Astrolib are used as well. Accuracy is about 0.5 seconds in time and about 1 m/s in velocity. History: written by Peter Mittermayer, Nov 8,2003 2005-January-13 Kudryavtsev Made more accurate calculation of the sidereal time. Conformity with MIDAS compute/barycorr is checked. 2005-June-20 Kochukhov Included precession of RA2000 and DEC2000 to current epoch """ from PyAstronomy.pyaC import degtorad # This reverts the original longitude convention. After this, # East longitudes are positive obs_long = -obs_long if jd < 2.4e6: PE.warn( PE.PyAValError("The given Julian Date (" + str(jd) + ") is exceedingly small. Did you subtract 2.4e6?")) # Covert JD to Gregorian calendar date xjd = jd year, month, day, ut = tuple(daycnv(xjd)) # Current epoch epoch = year + month / 12. + day / 365. # Precess ra2000 and dec2000 to current epoch, resulting ra is in degrees ra = ra2000 dec = dec2000 ra, dec = precess(ra, dec, 2000.0, epoch) # Calculate heliocentric julian date rjd = jd - 2.4e6 hjd = helio_jd(rjd, ra, dec) + 2.4e6 # DIURNAL VELOCITY (see IRAF task noao.astutil.rvcorrect) # convert geodetic latitude into geocentric latitude to correct # for rotation of earth dlat = -(11.*60.+32.743)*np.sin(2.0*degtorad(obs_lat)) \ +1.1633*np.sin(4.0*degtorad(obs_lat)) - 0.0026*np.sin(6.0*degtorad(obs_lat)) lat = obs_lat + dlat / 3600.0 # Calculate distance of observer from earth center r = 6378160.0 * (0.998327073+0.001676438*np.cos(2.0*degtorad(lat)) \ -0.00000351 * np.cos(4.0*degtorad(lat)) + 0.000000008*np.cos(6.0*degtorad(lat))) \ + obs_alt # Calculate rotational velocity (perpendicular to the radius vector) in km/s # 23.934469591229 is the sidereal day in hours for 1986 v = 2. * np.pi * (r / 1000.) / (23.934469591229 * 3600.) # Calculating local mean sidereal time (see astronomical almanach) tu = (rjd - 51545.0) / 36525.0 gmst = 6.697374558 + ut + \ (236.555367908*(rjd-51545.0) + 0.093104*tu**2 - 6.2e-6*tu**3)/3600.0 lmst = idlMod(gmst - obs_long / 15., 24) # Projection of rotational velocity along the line of sight vdiurnal = v * np.cos(degtorad(lat)) * np.cos(degtorad(dec)) * np.sin( degtorad(ra - lmst * 15)) # BARICENTRIC and HELIOCENTRIC VELOCITIES vh, vb = baryvel(xjd, 0) # Project to line of sight vbar = vb[0]*np.cos(degtorad(dec))*np.cos(degtorad(ra)) + vb[1]*np.cos(degtorad(dec))*np.sin(degtorad(ra)) + \ vb[2]*np.sin(degtorad(dec)) vhel = vh[0]*np.cos(degtorad(dec))*np.cos(degtorad(ra)) + vh[1]*np.cos(degtorad(dec))*np.sin(degtorad(ra)) + \ vh[2]*np.sin(degtorad(dec)) # Use barycentric velocity for correction corr = (vdiurnal + vbar) if debug: print('') print('----- HELCORR.PRO - DEBUG INFO - START ----') print( '(obs_long (East positive),obs_lat,obs_alt) Observatory coordinates [deg,m]: ', -obs_long, obs_lat, obs_alt) print('(ra,dec) Object coordinates (for epoch 2000.0) [deg]: ', ra, dec) print('(ut) Universal time (middle of exposure) [hrs]: ', ut) print('(jd) Julian date (middle of exposure) (JD): ', jd) print('(hjd) Heliocentric Julian date (middle of exposure) (HJD): ', hjd) print('(gmst) Greenwich mean sidereal time [hrs]: ', idlMod(gmst, 24)) print('(lmst) Local mean sidereal time [hrs]: ', lmst) print('(dlat) Latitude correction [deg]: ', dlat) print('(lat) Geocentric latitude of observer [deg]: ', lat) print('(r) Distance of observer from center of earth [m]: ', r) print( '(v) Rotational velocity of earth at the position of the observer [km/s]: ', v) print( '(vdiurnal) Projected earth rotation and earth-moon revolution [km/s]: ', vdiurnal) print('(vbar) Barycentric velocity [km/s]: ', vbar) print('(vhel) Heliocentric velocity [km/s]: ', vhel) print('(corr) Vdiurnal+vbar [km/s]: ', corr) print('----- HELCORR.PRO - DEBUG INFO - END -----') print('') return corr, hjd
def helcorr(obs_long, obs_lat, obs_alt, ra2000, dec2000, jd, debug=False): """ Calculate barycentric velocity correction. This function calculates the motion of an observer in the direction of a star. In contract to :py:func:`baryvel` and :py:func:`baryCorr`, the rotation of the Earth is taken into account. .. note:: This function was ported from the REDUCE IDL package. See Piskunov & Valenti 2002, A&A 385, 1095 for a detailed description of the package and/or visit http://www.astro.uu.se/~piskunov/RESEARCH/REDUCE/ .. warning:: Contrary to the original implementation the longitude increases toward the East and the right ascension is given in degrees instead of hours. The JD is given as is, in particular, nothing needs to be subtracted. Parameters ---------- obs_long : float Longitude of observatory (degrees, **eastern** direction is positive) obs_lat : float Latitude of observatory [deg] obs_alt : float Altitude of observatory [m] ra2000 : float Right ascension of object for epoch 2000.0 [deg] dec2000 : float Declination of object for epoch 2000.0 [deg] jd : float Julian date for the middle of exposure. Returns ------- Barycentric correction : float The barycentric correction accounting for the rotation of the Earth, the rotation of the Earth's center around the Earth-Moon barycenter, and the motion of the Earth-Moon barycenter around the center of the Sun [km/s]. HJD : float Heliocentric Julian date for middle of exposure. Notes ----- :IDL REDUCE - Documentation: Calculates heliocentric Julian date, barycentric and heliocentric radial velocity corrections from: INPUT: <OBSLON> Longitude of observatory (degrees, western direction is positive) <OBSLAT> Latitude of observatory (degrees) <OBSALT> Altitude of observatory (meters) <RA2000> Right ascension of object for epoch 2000.0 (hours) <DE2000> Declination of object for epoch 2000.0 (degrees) <JD> Julian date for the middle of exposure [DEBUG=] set keyword to get additional results for debugging OUTPUT: <CORRECTION> barycentric correction - correction for rotation of earth, rotation of earth center about the earth-moon barycenter, earth-moon barycenter about the center of the Sun. <HJD> Heliocentric Julian date for middle of exposure Algorithms used are taken from the IRAF task noao.astutils.rvcorrect and some procedures of the IDL Astrolib are used as well. Accuracy is about 0.5 seconds in time and about 1 m/s in velocity. History: written by Peter Mittermayer, Nov 8,2003 2005-January-13 Kudryavtsev Made more accurate calculation of the sidereal time. Conformity with MIDAS compute/barycorr is checked. 2005-June-20 Kochukhov Included precession of RA2000 and DEC2000 to current epoch """ from PyAstronomy.pyaC import degtorad # This reverts the original longitude convention. After this, # East longitudes are positive obs_long = -obs_long if jd < 2.4e6: PE.warn(PE.PyAValError("The given Julian Date (" + str(jd) + ") is exceedingly small. Did you subtract 2.4e6?")) # Covert JD to Gregorian calendar date xjd = jd year, month, day, ut = tuple(daycnv(xjd)) # Current epoch epoch = year + month/12. + day/365. # Precess ra2000 and dec2000 to current epoch, resulting ra is in degrees ra = ra2000 dec = dec2000 ra, dec = precess(ra, dec, 2000.0, epoch) # Calculate heliocentric julian date rjd = jd-2.4e6 hjd = helio_jd(rjd, ra, dec) + 2.4e6 # DIURNAL VELOCITY (see IRAF task noao.astutil.rvcorrect) # convert geodetic latitude into geocentric latitude to correct # for rotation of earth dlat = -(11.*60.+32.743)*np.sin(2.0*degtorad(obs_lat)) \ +1.1633*np.sin(4.0*degtorad(obs_lat)) - 0.0026*np.sin(6.0*degtorad(obs_lat)) lat = obs_lat + dlat/3600.0 # Calculate distance of observer from earth center r = 6378160.0 * (0.998327073+0.001676438*np.cos(2.0*degtorad(lat)) \ -0.00000351 * np.cos(4.0*degtorad(lat)) + 0.000000008*np.cos(6.0*degtorad(lat))) \ + obs_alt # Calculate rotational velocity (perpendicular to the radius vector) in km/s # 23.934469591229 is the sidereal day in hours for 1986 v = 2.*np.pi * (r/1000.) / (23.934469591229*3600.) # Calculating local mean sidereal time (see astronomical almanach) tu = (rjd-51545.0)/36525.0 gmst = 6.697374558 + ut + \ (236.555367908*(rjd-51545.0) + 0.093104*tu**2 - 6.2e-6*tu**3)/3600.0 lmst = idlMod(gmst-obs_long/15, 24) # Projection of rotational velocity along the line of sight vdiurnal = v*np.cos(degtorad(lat))*np.cos(degtorad(dec))*np.sin(degtorad(ra-lmst*15)) # BARICENTRIC and HELIOCENTRIC VELOCITIES vh, vb = baryvel(xjd,0) # Project to line of sight vbar = vb[0]*np.cos(degtorad(dec))*np.cos(degtorad(ra)) + vb[1]*np.cos(degtorad(dec))*np.sin(degtorad(ra)) + \ vb[2]*np.sin(degtorad(dec)) vhel = vh[0]*np.cos(degtorad(dec))*np.cos(degtorad(ra)) + vh[1]*np.cos(degtorad(dec))*np.sin(degtorad(ra)) + \ vh[2]*np.sin(degtorad(dec)) # Use barycentric velocity for correction corr = (vdiurnal + vbar) if debug: print '' print '----- HELCORR.PRO - DEBUG INFO - START ----' print '(obs_long (East positive),obs_lat,obs_alt) Observatory coordinates [deg,m]: ', -obs_long, obs_lat, obs_alt print '(ra,dec) Object coordinates (for epoch 2000.0) [deg]: ', ra,dec print '(ut) Universal time (middle of exposure) [hrs]: ', ut print '(jd) Julian date (middle of exposure) (JD): ', jd print '(hjd) Heliocentric Julian date (middle of exposure) (HJD): ', hjd print '(gmst) Greenwich mean sidereal time [hrs]: ', idlMod(gmst, 24) print '(lmst) Local mean sidereal time [hrs]: ', lmst print '(dlat) Latitude correction [deg]: ', dlat print '(lat) Geocentric latitude of observer [deg]: ', lat print '(r) Distance of observer from center of earth [m]: ', r print '(v) Rotational velocity of earth at the position of the observer [km/s]: ', v print '(vdiurnal) Projected earth rotation and earth-moon revolution [km/s]: ', vdiurnal print '(vbar) Barycentric velocity [km/s]: ', vbar print '(vhel) Heliocentric velocity [km/s]: ', vhel print '(corr) Vdiurnal+vbar [km/s]: ', corr print '----- HELCORR.PRO - DEBUG INFO - END -----' print '' return corr, hjd
def positionAngle(ra1, dec1, ra2, dec2, positive=True): """ Compute the position angle. The position angle is measured from the first position from North through East. If the `positive` flag is set True (default) the result will be given as an angle from 0 to 360 degrees. If the flag is set False, the scale is -180 to 180 degrees with negative number increasing from North through West; note that this is the behavior of the posAng IDL routine. Parameters ---------- ra1 : float Right ascension of first object [deg]. dec1 : float Declination of first object [deg]. ra2 : float Right ascension of second object [deg]. dec2 : float Declination of second object [deg]. positive : boolean, optional If True (default), the output will be given as an angle between 0 and 360 degrees. Otherwise, the angle ranges from -180 to +180 degrees. Returns ------- Position angle : float The position angle in degrees. Notes ----- .. note:: This function was ported from the IDL Astronomy User's Library. :IDL - Documentation: NAME: POSANG PURPOSE: Computes rigorous position angle of source 2 relative to source 1 EXPLANATION: Computes the rigorous position angle of source 2 (with given RA, Dec) using source 1 (with given RA, Dec) as the center. CALLING SEQUENCE: POSANG, U, RA1, DC1, RA2, DC2, ANGLE INPUTS: U -- Describes units of inputs and output: 0: everything radians 1: RAx in decimal hours, DCx in decimal degrees, ANGLE in degrees RA1 -- Right ascension of point 1 DC1 -- Declination of point 1 RA2 -- Right ascension of point 2 DC2 -- Declination of point 2 OUTPUTS: ANGLE-- Angle of the great circle containing [ra2, dc2] from the meridian containing [ra1, dc1], in the sense north through east rotating about [ra1, dc1]. See U above for units. PROCEDURE: The "four-parts formula" from spherical trig (p. 12 of Smart's Spherical Astronomy or p. 12 of Green' Spherical Astronomy). EXAMPLE: For the star 56 Per, the Hipparcos catalog gives a position of RA = 66.15593384, Dec = 33.94988843 for component A, and RA = 66.15646079, Dec = 33.96100069 for component B. What is the position angle of B relative to A? IDL> RA1 = 66.15593384/15.d & DC1 = 33.95988843 IDL> RA2 = 66.15646079/15.d & DC2 = 33.96100069 IDL> posang,1,ra1,dc1,ra2,dc2, ang will give the answer of ang = 21.4 degrees NOTES: (1) If RA1,DC1 are scalars, and RA2,DC2 are vectors, then ANGLE is a vector giving the position angle between each element of RA2,DC2 and RA1,DC1. Similarly, if RA1,DC1 are vectors, and RA2, DC2 are scalars, then DIS is a vector giving the position angle of each element of RA1, DC1 and RA2, DC2. If both RA1,DC1 and RA2,DC2 are vectors then ANGLE is a vector giving the position angle between each element of RA1,DC1 and the corresponding element of RA2,DC2. If then vectors are not the same length, then excess elements of the longer one will be ignored. (2) Note that POSANG is not commutative -- the position angle between A and B is theta, then the position angle between B and A is 180+theta PROCEDURE CALLS: ISARRAY() HISTORY: Modified from GCIRC, R. S. Hill, RSTX, 1 Apr. 1998 Use V6.0 notation W.L. Mar 2011 """ # Convert into rad rarad1 = pyaC.degtorad(ra1) rarad2 = pyaC.degtorad(ra2) dcrad1 = pyaC.degtorad(dec1) dcrad2 = pyaC.degtorad(dec2) radif = rarad2 - rarad1 angle = arctan2(sin(radif), cos(dcrad1) * tan(dcrad2) - sin(dcrad1) * cos(radif)) result = pyaC.radtodeg(angle) if positive and (result < 0.0): result += 360.0 return result
def positionAngle(ra1, dec1, ra2, dec2, positive=True): """ Compute the position angle. The position angle is measured from the first position from North through East. If the `positive` flag is set True (default) the result will be given as an angle from 0 to 360 degrees. If the flag is set False, the scale is -180 to 180 degrees with negative number increasing from North through West; note that this is the behavior of the posAng IDL routine. Parameters ---------- ra1 : float Right ascension of first object [deg]. dec1 : float Declination of first object [deg]. ra2 : float Right ascension of second object [deg]. dec2 : float Declination of second object [deg]. positive : boolean, optional If True (default), the output will be given as an angle between 0 and 360 degrees. Otherwise, the angle ranges from -180 to +180 degrees. Returns ------- Position angle : float The position angle in degrees. Notes ----- .. note:: This function was ported from the IDL Astronomy User's Library. :IDL - Documentation: NAME: POSANG PURPOSE: Computes rigorous position angle of source 2 relative to source 1 EXPLANATION: Computes the rigorous position angle of source 2 (with given RA, Dec) using source 1 (with given RA, Dec) as the center. CALLING SEQUENCE: POSANG, U, RA1, DC1, RA2, DC2, ANGLE INPUTS: U -- Describes units of inputs and output: 0: everything radians 1: RAx in decimal hours, DCx in decimal degrees, ANGLE in degrees RA1 -- Right ascension of point 1 DC1 -- Declination of point 1 RA2 -- Right ascension of point 2 DC2 -- Declination of point 2 OUTPUTS: ANGLE-- Angle of the great circle containing [ra2, dc2] from the meridian containing [ra1, dc1], in the sense north through east rotating about [ra1, dc1]. See U above for units. PROCEDURE: The "four-parts formula" from spherical trig (p. 12 of Smart's Spherical Astronomy or p. 12 of Green' Spherical Astronomy). EXAMPLE: For the star 56 Per, the Hipparcos catalog gives a position of RA = 66.15593384, Dec = 33.94988843 for component A, and RA = 66.15646079, Dec = 33.96100069 for component B. What is the position angle of B relative to A? IDL> RA1 = 66.15593384/15.d & DC1 = 33.95988843 IDL> RA2 = 66.15646079/15.d & DC2 = 33.96100069 IDL> posang,1,ra1,dc1,ra2,dc2, ang will give the answer of ang = 21.4 degrees NOTES: (1) If RA1,DC1 are scalars, and RA2,DC2 are vectors, then ANGLE is a vector giving the position angle between each element of RA2,DC2 and RA1,DC1. Similarly, if RA1,DC1 are vectors, and RA2, DC2 are scalars, then DIS is a vector giving the position angle of each element of RA1, DC1 and RA2, DC2. If both RA1,DC1 and RA2,DC2 are vectors then ANGLE is a vector giving the position angle between each element of RA1,DC1 and the corresponding element of RA2,DC2. If then vectors are not the same length, then excess elements of the longer one will be ignored. (2) Note that POSANG is not commutative -- the position angle between A and B is theta, then the position angle between B and A is 180+theta PROCEDURE CALLS: ISARRAY() HISTORY: Modified from GCIRC, R. S. Hill, RSTX, 1 Apr. 1998 Use V6.0 notation W.L. Mar 2011 """ # Convert into rad rarad1 = pyaC.degtorad(ra1) rarad2 = pyaC.degtorad(ra2) dcrad1 = pyaC.degtorad(dec1) dcrad2 = pyaC.degtorad(dec2) radif = rarad2 - rarad1 angle = arctan2(sin(radif), cos(dcrad1)*tan(dcrad2)-sin(dcrad1)*cos(radif)) result = pyaC.radtodeg(angle) if positive and (result < 0.0): result+= 360.0 return result