{-|
Module: Data.Astro.Effects.Parallax
Description: Calculation effects of geocentric parallax
Copyright: Alexander Ignatyev, 2016


Calculation effects of geocentric parallax.
-}

module Data.Astro.Effects.Parallax
(
  parallaxQuantities
  , parallax
)

where

import Data.Astro.Types (DecimalDegrees(..)
                        , DecimalHours(..)
                        , AstronomicalUnits(..)
                        , GeographicCoordinates(..)
                        , toRadians, fromRadians
                        , fromDMS
                        , toDecimalHours, fromDecimalHours)
import Data.Astro.Time (utToLST)
import Data.Astro.Time.JulianDate (JulianDate(..))
import Data.Astro.Time.Sidereal (LocalSiderealTime(..), utToGST, gstToLST)
import Data.Astro.Coordinate (EquatorialCoordinates1(..), raToHA)


-- | It takes latitude of the observer

-- and height above sea-level of the observer measured in metres

-- Returns palallax quantities (p*(sin phi'), p*(cos phi')),

-- where phi' is the geocentric latitude

-- and p is the distance of the obserbve from the centre of the Earth.

parallaxQuantities :: DecimalDegrees -> Double -> (Double, Double)
parallaxQuantities :: DecimalDegrees -> Double -> (Double, Double)
parallaxQuantities DecimalDegrees
latitude Double
height =
  let c :: Double
c = Double
0.996647
      phi :: Double
phi = DecimalDegrees -> Double
toRadians DecimalDegrees
latitude
      h :: Double
h = Double -> Double
earthRadiusUnits Double
height
      u :: Double
u = Double -> Double
forall a. Floating a => a -> a
atan (Double
cDouble -> Double -> Double
forall a. Num a => a -> a -> a
*(Double -> Double
forall a. Floating a => a -> a
tan Double
phi))
      pSin :: Double
pSin = Double
c Double -> Double -> Double
forall a. Num a => a -> a -> a
* (Double -> Double
forall a. Floating a => a -> a
sin Double
u) Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
hDouble -> Double -> Double
forall a. Num a => a -> a -> a
*(Double -> Double
forall a. Floating a => a -> a
sin Double
phi)
      pCos :: Double
pCos = (Double -> Double
forall a. Floating a => a -> a
cos Double
u) Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
hDouble -> Double -> Double
forall a. Num a => a -> a -> a
*(Double -> Double
forall a. Floating a => a -> a
cos Double
phi)
  in (Double
pSin, Double
pCos)


-- | Calculate the apparent position of the celestial object (the Sun or a planet).

-- It takes geocraphic coordinates of the observer and height above sea-level of the observer measured in metres,

-- distance from the celestial object to the Earth measured in AU, the Universal Time and geocentric equatorial coordinates.

-- It returns adjusted equatorial coordinates.

parallax :: GeographicCoordinates -> Double -> AstronomicalUnits -> JulianDate -> EquatorialCoordinates1 -> EquatorialCoordinates1
parallax :: GeographicCoordinates
-> Double
-> AstronomicalUnits
-> JulianDate
-> EquatorialCoordinates1
-> EquatorialCoordinates1
parallax (GeoC DecimalDegrees
latitude DecimalDegrees
longitude) Double
height AstronomicalUnits
distance JulianDate
ut (EC1 DecimalDegrees
delta DecimalHours
alpha) =
  let piD :: DecimalDegrees
piD = AstronomicalUnits -> DecimalDegrees
earthRadiusUnitsAU AstronomicalUnits
distance
      lst :: LocalSiderealTime
lst = DecimalDegrees -> JulianDate -> LocalSiderealTime
utToLST DecimalDegrees
longitude JulianDate
ut
      (Double
pSin, Double
pCos) = DecimalDegrees -> Double -> (Double, Double)
parallaxQuantities DecimalDegrees
latitude Double
height
      ha :: Double
ha = DecimalDegrees -> Double
toRadians (DecimalDegrees -> Double) -> DecimalDegrees -> Double
forall a b. (a -> b) -> a -> b
$ DecimalHours -> DecimalDegrees
fromDecimalHours (DecimalHours -> DecimalDegrees) -> DecimalHours -> DecimalDegrees
forall a b. (a -> b) -> a -> b
$ DecimalHours -> DecimalDegrees -> JulianDate -> DecimalHours
raToHA DecimalHours
alpha DecimalDegrees
longitude JulianDate
ut
      delta' :: Double
delta' = DecimalDegrees -> Double
toRadians DecimalDegrees
delta
      dAlpha :: DecimalHours
dAlpha = (DecimalDegrees -> DecimalHours
toDecimalHours DecimalDegrees
piD) DecimalHours -> DecimalHours -> DecimalHours
forall a. Num a => a -> a -> a
* (Double -> DecimalHours
DH (Double -> DecimalHours) -> Double -> DecimalHours
forall a b. (a -> b) -> a -> b
$ (Double -> Double
forall a. Floating a => a -> a
sin Double
ha)Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
pCosDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/(Double -> Double
forall a. Floating a => a -> a
cos Double
delta'))
      dDelta :: DecimalDegrees
dDelta = DecimalDegrees
piD DecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
* (Double -> DecimalDegrees
DD (Double -> DecimalDegrees) -> Double -> DecimalDegrees
forall a b. (a -> b) -> a -> b
$ Double
pSinDouble -> Double -> Double
forall a. Num a => a -> a -> a
*(Double -> Double
forall a. Floating a => a -> a
cos Double
delta') Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
pCosDouble -> Double -> Double
forall a. Num a => a -> a -> a
*(Double -> Double
forall a. Floating a => a -> a
cos Double
ha)Double -> Double -> Double
forall a. Num a => a -> a -> a
*(Double -> Double
forall a. Floating a => a -> a
sin Double
delta'))
  in DecimalDegrees -> DecimalHours -> EquatorialCoordinates1
EC1 (DecimalDegrees
deltaDecimalDegrees -> DecimalDegrees -> DecimalDegrees
forall a. Num a => a -> a -> a
-DecimalDegrees
dDelta) (DecimalHours
alphaDecimalHours -> DecimalHours -> DecimalHours
forall a. Num a => a -> a -> a
-DecimalHours
dAlpha)


-- | It takes the distance in metres and

-- returns the distance measured in units of qquatorial Earth radius

earthRadiusUnits :: Double -> Double
earthRadiusUnits :: Double -> Double
earthRadiusUnits Double
d = Double
d Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
6378140


--earthRadiusUnitsAU :: AstronomicalUnits -> DecimalDegrees

earthRadiusUnitsAU :: AstronomicalUnits -> DecimalDegrees
earthRadiusUnitsAU (AU Double
d) = Int -> Int -> Double -> DecimalDegrees
forall a. RealFrac a => Int -> Int -> a -> DecimalDegrees
fromDMS Int
0 Int
0 (Double
8.794Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
d)