def azAltFromHADec(haDec, lat): """Converts HA/Dec position to az/alt. Inputs: - haDec (ha, dec) (degrees) - lat latitude (degrees) Returns a tuple containing: (az, alt) (degrees) atPole true => object near the pole (see Error Conditions) Error Conditions: - If converted position is too near the pole, atPole is true and ha is undefined. Sign convention: azimuth is 0 south and 90 east. History: 2002-07-23 ROwen Converted from TCC's sph_HADec2AzAlt 1-2. 2003-05-06 ROwen Modified test data to match new scFromCC. """ # convert spherical -ha/dec to direction cosines negHADec = (-haDec[0], haDec[1]) haDecDC = dcFromSC (negHADec) # convert ha/dec direction cosines to az/alt direction cosines azAltDC = Cnv.azAltFromHADec (haDecDC, lat) # convert az/alt direction cosines to spherical az/alt (deg) return scFromDC (azAltDC)
def azAltFromHADec(haDec, lat): """Converts HA/Dec position to az/alt. Inputs: - haDec (ha, dec) (degrees) - lat latitude (degrees) Returns a tuple containing: (az, alt) (degrees) atPole true => object near the pole (see Error Conditions) Error Conditions: - If converted position is too near the pole, atPole is true and ha is undefined. Sign convention: azimuth is 0 south and 90 east. History: 2002-07-23 ROwen Converted from TCC's sph_HADec2AzAlt 1-2. 2003-05-06 ROwen Modified test data to match new scFromCC. """ # convert spherical -ha/dec to direction cosines negHADec = (-haDec[0], haDec[1]) haDecDC = dcFromSC(negHADec) # convert ha/dec direction cosines to az/alt direction cosines azAltDC = Cnv.azAltFromHADec(haDecDC, lat) # convert az/alt direction cosines to spherical az/alt (deg) return scFromDC(azAltDC)
def haDecFromAzAlt (azAlt, lat): """Converts alt/az position to ha/dec position. Inputs: - azAlt (az, alt) (deg) - lat latitude (degrees); >0 is north of the equator, <0 is south Returns a tuple containing: - haDec (HA, Dec) (deg), a tuple; HA is in the range (-180, 180] - atPole true => object near the pole (see Error Conditions) Error Conditions: - If converted position is too near the north or south pole, atPole is set true and HA is some arbitrary value. Details: Sign conventions: - azimuth is 0 south and 90 east - ha/dec is the usual left-handed coordinate system History: 3/01 ROwen Converted to Python from TCC's sph_AzAlt2HADec 1-2. 2/02 ROwen Minor tweaks to header. 2002-07-02 ROwen Renamed from azAltToHADec. 2003-05-06 ROwen Changed HA range from [0, 360) to (-180, 180] """ # convert spherical az/alt (deg) to direction cosines azAltDC = dcFromSC (azAlt) # convert az/alt direction cosines to -ha/dec direction cosines negHADecDC = Cnv.haDecFromAzAlt (azAltDC, lat) # convert -ha/dec direction cosines to spherical -ha/dec (deg) ((negHA, dec), atPole) = scFromDC (negHADecDC) return ((RO.MathUtil.wrapCtr(-negHA), dec), atPole)
def haDecFromAzAlt(azAlt, lat): """Converts alt/az position to ha/dec position. Inputs: - azAlt (az, alt) (deg) - lat latitude (degrees); >0 is north of the equator, <0 is south Returns a tuple containing: - haDec (HA, Dec) (deg), a tuple; HA is in the range (-180, 180] - atPole true => object near the pole (see Error Conditions) Error Conditions: - If converted position is too near the north or south pole, atPole is set true and HA is some arbitrary value. Details: Sign conventions: - azimuth is 0 south and 90 east - ha/dec is the usual left-handed coordinate system History: 3/01 ROwen Converted to Python from TCC's sph_AzAlt2HADec 1-2. 2/02 ROwen Minor tweaks to header. 2002-07-02 ROwen Renamed from azAltToHADec. 2003-05-06 ROwen Changed HA range from [0, 360) to (-180, 180] """ # convert spherical az/alt (deg) to direction cosines azAltDC = dcFromSC(azAlt) # convert az/alt direction cosines to -ha/dec direction cosines negHADecDC = Cnv.haDecFromAzAlt(azAltDC, lat) # convert -ha/dec direction cosines to spherical -ha/dec (deg) ((negHA, dec), atPole) = scFromDC(negHADecDC) return ((RO.MathUtil.wrapCtr(-negHA), dec), atPole)
def coordConv( fromPos, fromSys, fromDate, toSys, toDate, fromPM=(0.0, 0.0), fromParlax=0.0, fromRadVel=0.0, obsData=None, refCo=None, fromDir=0.0, ): """ Converts position, velocity, and unit position offset from one coordinate system to another. Inputs: - fromPos(2) input position (deg) - fromSys coord. system from which to convert (e.g. "ICRS"); any of the entries in the table below; use RO.CoordSys constants. - fromDate date of "from" coordinates*. - toSys coordinate system to which to convert (see fromSys) - toDate date of "to" coordinates* - fromPM(2)** input proper motion (arcsec per century***); default is (0,0) - fromParlax** input parallax (arcsec) - fromRadVel** input radial velocity (km/sec, positive receding) - obsData an RO.Astro.Cnv.ObserverData object; required if fromSys or toSys is Topocentric or Observed; ignored otherwise. - refCo(2) refraction coefficients; required if fromSys or toSys is Observed; ignored otherwise. - fromDir input reference direction (deg); input axis 1 = 0, axis 2 = 90 Returns: - toPos(2) converted position - toPM(2) converted proper motion - toParlax converted parallax - toRadVel converted radial velocity - toDir converted reference direction (deg); output axis 1 = 0, axis 2 = 90; the wrap is chosen so that |toDir - fromDir| < 360 - ScaleChange scale change along reference dir. (out mag/in mag) - atInf true => object very far away (see Error Conditions) - atPole true => toPos near the pole (see Error Conditions) *the units of date depend on the associated coordinate system: coord sys def date date ICRS 2000.0 Julian epoch of observation FK5 2000.0 Julian epoch of equinox and observation FK4 1950.0 Besselian epoch of equinox and observation Galactic now Julian epoch of observation Geocentric now UT1 (MJD) Topocentric now UT1 (MJD) Observed now UT1 (MJD) **Setting proper motion, parallax and radial velocity all zero implies the object is fixed. This slighly affects conversion to or from FK4, which has fictitious proper motion. These inputs are ignored for conversion from apparent coordinate systems. ***Besselian for the FK4 system, Julian for all others Error Conditions: - If obsData or refCo are absend and are required, raises ValueError. - If the object is very far away: atInf is set true, toParlax is set to 0.0 and toRadVel = fromRadVel. - If toPos is too near the pole: atPole is set 1 and toPos[0], toPM[0] and toDir are incorrect. Details: Sph.CoordConv is simply a front end to Cnv.CoordConv (which see) with the added support for measuring angle and scale factor. fromDir, toDir and ScaleChange: fromDir is used to create a small vector perpendicular to fromPos. A second position is created offset by this much, and both positions are converted. The resulting difference is then turned into a direction (toDir) and a length (ScaleChange = toOffMag/fromMag). This is used to track the effects of the conversion on orientation, for driving the rotator. In most cases, one may set fromDir = 0, ignore ScaleChange, and use toDir as the change in orientation. However, for drift scanning, you should set fromDir to the direction you are moving. This allows you to compensate velocity for refraction to keep the stars moving at the same rate across the CCD. Current scan velocity = scaleFactor * desired constant scan rate on sky. Note: actually implementing such a scan can be a headache as it mixes path length as seen at the telescope with a path whose direction is given in mean sky coordinates. On the TCCs I end up doing a bit of iteration and keeping track of accumulated path length. If you have a small enough field of view you may be able to skip this step and put up with the resulting slight image blur. History: 2002-08-23 ROwen Untested beta. Converted to Python from the TCC's sph_CoordConv 6-4 """ # print "Sph.CoordConv(fromPos=%s, fromSys=%s, fromDate=%s, toSys=%s, toDate=%s, fromPM=%s, fromParlax=%s, fromRadVel=%s, refCo=%s, fromDir=%s)" % (fromPos, fromSys, fromDate, toSys, toDate, fromPM, fromParlax, fromRadVel, refCo, fromDir) # convert RA, Dec, etc to cartesian coordinates fromP, fromV, fromOffP, atInf = ccFromSCPVOff(fromPos, fromPM, fromParlax, fromRadVel, fromDir, Const.OffMag) # print "Sph.CoordConv: fromP=%s, fromV=%s, fromOffP=%s, atInf=%s" % (fromP, fromV, fromOffP, atInf) # convert coordinates toP, toV = Cnv.coordConv(fromP, fromV, fromSys, fromDate, toSys, toDate, obsData, refCo) toOffP, dumV = Cnv.coordConv(fromOffP, fromV, fromSys, fromDate, toSys, toDate, obsData, refCo) # print "Sph.CoordConv: toP=%s, toV=%s, toOffP=%s" % (toP, toV, toOffP) toPos, toPM, toParlax, toRadVel, toDir, toOffMag, atPole = scFromCCPVOff( toP, toV, toOffP) # put toDir into same wrap as fromDir toDir = fromDir + RO.MathUtil.wrapCtr(toDir - fromDir) # if at infinity, zero parallax and set to radial velocity = from radial velocity if atInf: toParlax = 0.0 toRadVel = fromRadVel scaleChange = toOffMag / Const.OffMag # print "Sph.CoordConv: toPos=%s, toPM=%s, toParlax=%s, toRadVel=%s, toDir=%s, toOffMag=%s, atPole=%s, scaleChange=%s" % (toPos, toPM, toParlax, toRadVel, toDir, toOffMag, atPole, scaleChange) return (toPos, toPM, toParlax, toRadVel, toDir, scaleChange, atInf, atPole)
def coordConv ( fromPos, fromSys, fromDate, toSys, toDate, fromPM = (0.0, 0.0), fromParlax=0.0, fromRadVel=0.0, obsData = None, refCo = None, fromDir=0.0, ): """ Converts position, velocity, and unit position offset from one coordinate system to another. Inputs: - fromPos(2) input position (deg) - fromSys coord. system from which to convert (e.g. "ICRS"); any of the entries in the table below; use RO.CoordSys constants. - fromDate date of "from" coordinates*. - toSys coordinate system to which to convert (see fromSys) - toDate date of "to" coordinates* - fromPM(2)** input proper motion (arcsec per century***); default is (0,0) - fromParlax** input parallax (arcsec) - fromRadVel** input radial velocity (km/sec, positive receding) - obsData an RO.Astro.Cnv.ObserverData object; required if fromSys or toSys is Topocentric or Observed; ignored otherwise. - refCo(2) refraction coefficients; required if fromSys or toSys is Observed; ignored otherwise. - fromDir input reference direction (deg); input axis 1 = 0, axis 2 = 90 Returns: - toPos(2) converted position - toPM(2) converted proper motion - toParlax converted parallax - toRadVel converted radial velocity - toDir converted reference direction (deg); output axis 1 = 0, axis 2 = 90; the wrap is chosen so that |toDir - fromDir| < 360 - ScaleChange scale change along reference dir. (out mag/in mag) - atInf true => object very far away (see Error Conditions) - atPole true => toPos near the pole (see Error Conditions) *the units of date depend on the associated coordinate system: coord sys def date date ICRS 2000.0 Julian epoch of observation FK5 2000.0 Julian epoch of equinox and observation FK4 1950.0 Besselian epoch of equinox and observation Galactic now Julian epoch of observation Geocentric now UT1 (MJD) Topocentric now UT1 (MJD) Observed now UT1 (MJD) **Setting proper motion, parallax and radial velocity all zero implies the object is fixed. This slighly affects conversion to or from FK4, which has fictitious proper motion. These inputs are ignored for conversion from apparent coordinate systems. ***Besselian for the FK4 system, Julian for all others Error Conditions: - If obsData or refCo are absend and are required, raises ValueError. - If the object is very far away: atInf is set true, toParlax is set to 0.0 and toRadVel = fromRadVel. - If toPos is too near the pole: atPole is set 1 and toPos[0], toPM[0] and toDir are incorrect. Details: Sph.CoordConv is simply a front end to Cnv.CoordConv (which see) with the added support for measuring angle and scale factor. fromDir, toDir and ScaleChange: fromDir is used to create a small vector perpendicular to fromPos. A second position is created offset by this much, and both positions are converted. The resulting difference is then turned into a direction (toDir) and a length (ScaleChange = toOffMag/fromMag). This is used to track the effects of the conversion on orientation, for driving the rotator. In most cases, one may set fromDir = 0, ignore ScaleChange, and use toDir as the change in orientation. However, for drift scanning, you should set fromDir to the direction you are moving. This allows you to compensate velocity for refraction to keep the stars moving at the same rate across the CCD. Current scan velocity = scaleFactor * desired constant scan rate on sky. Note: actually implementing such a scan can be a headache as it mixes path length as seen at the telescope with a path whose direction is given in mean sky coordinates. On the TCCs I end up doing a bit of iteration and keeping track of accumulated path length. If you have a small enough field of view you may be able to skip this step and put up with the resulting slight image blur. History: 2002-08-23 ROwen Untested beta. Converted to Python from the TCC's sph_CoordConv 6-4 """ # print "Sph.CoordConv(fromPos=%s, fromSys=%s, fromDate=%s, toSys=%s, toDate=%s, fromPM=%s, fromParlax=%s, fromRadVel=%s, refCo=%s, fromDir=%s)" % (fromPos, fromSys, fromDate, toSys, toDate, fromPM, fromParlax, fromRadVel, refCo, fromDir) # convert RA, Dec, etc to cartesian coordinates fromP, fromV, fromOffP, atInf = ccFromSCPVOff ( fromPos, fromPM, fromParlax, fromRadVel, fromDir, Const.OffMag) # print "Sph.CoordConv: fromP=%s, fromV=%s, fromOffP=%s, atInf=%s" % (fromP, fromV, fromOffP, atInf) # convert coordinates toP, toV = Cnv.coordConv(fromP, fromV, fromSys, fromDate, toSys, toDate, obsData, refCo) toOffP, dumV = Cnv.coordConv(fromOffP, fromV, fromSys, fromDate, toSys, toDate, obsData, refCo) # print "Sph.CoordConv: toP=%s, toV=%s, toOffP=%s" % (toP, toV, toOffP) toPos, toPM, toParlax, toRadVel, toDir, toOffMag, atPole = scFromCCPVOff (toP, toV, toOffP) # put toDir into same wrap as fromDir toDir = fromDir + RO.MathUtil.wrapCtr (toDir - fromDir) # if at infinity, zero parallax and set to radial velocity = from radial velocity if atInf: toParlax = 0.0 toRadVel = fromRadVel scaleChange = toOffMag / Const.OffMag # print "Sph.CoordConv: toPos=%s, toPM=%s, toParlax=%s, toRadVel=%s, toDir=%s, toOffMag=%s, atPole=%s, scaleChange=%s" % (toPos, toPM, toParlax, toRadVel, toDir, toOffMag, atPole, scaleChange) return (toPos, toPM, toParlax, toRadVel, toDir, scaleChange, atInf, atPole)