def scFromCCPVOff(p, v, offP): """ Converts cartesian position, velocity and offset to spherical coordinates (see also SCFromCC and SCFromCCPV). Inputs: - p(3) position (au) - v(3) velocity (au per year) - offP(3) offset position (au) Returns: - pos(2) spherical position (degrees) ranges: axis 1: [0, 360), axis 2: [-90,90] - pm(2) proper motion (arcsec per century) - parlax parallax (arcsec) - radVel radial velocity (km/s) - offDir offset direction (degrees): dir. of increasing pos[0] = 0 dir. of increasing pos[1] = 90 - offMag magnitude of offset (degrees on the sky) - atPole true if at a pole; see "Error Cond." for implications Error Conditions: - Raises ValueError if |p| is too small to safely compute. - If p is very near a pole, atPole is set true, pos[1], pm[0], pm[1] and offDir are set to zero; pos[0], parlax, radVel and offMag are still computed correctly (pos[0] is +/-90.0, as appropriate). - If inputs are too large, overflows are possible--roughly if p^2 or v^2 overflows. History 2002-08-22 ROwen Converted to Python from the TCC's sph_CCPVOff2SC 6-1. """ # convert p and v from cartesian to spherical pos, pm, parlax, radVel, atPole = scFromCCPV(p, v) # convert offP from cartesian to spherical offPos, magOffP, offAtPole = scFromCC(offP) # compute offset direction and magnitude ang_A, side_bb, ang_C, offAtPole2 = angSideAng( 90.0 - pos[1], offPos[0] - pos[0], 90.0 - offPos[1], ) offMag = side_bb if atPole: offDir = 0.0 else: offDir = 90.0 - ang_C return (pos, pm, parlax, radVel, offDir, offMag, atPole)
def scFromDC(p): """Convert direction cosines or any cartesian vector to spherical coordinates. Similar to scFromCC but magnitude is not returned. Inputs: - p(3) direction cosines or any cartesian vector Returns a tuple containing: - pos(2) spherical position (deg) as equatorial, polar angle, e.g. (RA, Dec), (-HA, Dec) or (Az, Alt); ranges are: pos[0]: [0, 360), pos[1]: [-90,90] - atPole true if very near the pole, in which case pos[1] = 0, and pos[0] = +/- 90 as appropriate. Error Conditions: - If |p| is too small, raises ValueError. - If |p| is too large, overflows are possible--roughly if p^2 overflows. Of course neither of these can occur if p is a direction cosine (unit vector). History: 2002-07-23 R Owen. """ pos, mag, atPole = scFromCC(p) return (pos, atPole)
def scFromCCPV(p, v): """ Converts cartesian position and velocity to spherical coordinates (if you just want to convert position, use sph_CC2SC). Inputs: p(3) cartesian position (au) v(3) cartesian velocity (au per year) Returns a tuple containing: pos(2) spherical position (degrees) ranges: pos[0]: [0, 360), pos[1]: [-90,90] pm(2) proper motion (arcsec per century) dpos/dt, not velocity on the sky (i.e. large near the poles) parallax parallax (arcsec) radVel radial velocity (km/s, positive receding) atPole true if at a pole; see "Error Cond." for implications Error Conditions: Raises valueError if |p| is too small If p is very near a pole, atPole is set true and pos[1], pm[0] and pm[1] are set to zero; pos[0], parallax and radVel are computed correctly (pos[0] is +/-90.0, as appropriate). If inputs are too large, overflows are possible--roughly if p^2 or v^2 overflows. History 2002-07-08 ROwen Converted from TCC's sph_SCPV2CC 1-1. """ x, y, z = p vX, vY, vZ = v pos, magP, atPole = scFromCC(p) # warning: test atPole after computing radial velocity and parallax # since they can be correctly computed even at the pole # compute parallax; note that arcsec = 1 / parsec; # the division is safe because magP must have some reasonable # minimum value, else scFromCC would have raised an exception parallax = RO.PhysConst.AUPerParsec / magP # compute radial velocity in (au/year) and convert to (km/s) radVel = float ((x * vX) + (y * vY) + (z * vZ)) / magP radVel *= _KMPerSec_Per_AUPerYear # now that parallax and radial velocity have been computed # handle the "at pole" case if atPole: # pos, parallax and radVel are already set pm = [0.0, 0.0] else: # useful quantities magPxySq = float((x * x) + (y * y)) magPxy = math.sqrt (magPxySq) magPSq = magPxySq + z * z # compute proper motion in rad per year, # then convert to arcsec per century; # the divisions are save because: # - magPxySq must have some reasonable minimum value, # else sph_CC2SC would have set atPole true, # and that case has already been handled above # - magPSq must have some reasonable minimum value, # else sph_CC2SC would have set isOK false pm = [ ((x * vY) - (y * vX)) / magPxySq, ((vZ * magPxy) - ((z / magPxy) * ((x * vX) + (y * vY)))) / magPSq, ] pm[0] = pm[0] * _ASPerCy_Per_RadPerYear pm[1] = pm[1] * _ASPerCy_Per_RadPerYear return (pos, pm, parallax, radVel, atPole)