module SwissEphemeris
(
JulianTime (..),
SiderealTime (..),
HouseCusp,
SplitDegreesOption (..),
Planet (..),
HouseSystem (..),
ZodiacSignName (..),
NakshatraName (..),
EclipticPosition (..),
EquatorialPosition (..),
GeographicPosition (..),
HousePosition (..),
ObliquityInformation (..),
Angles (..),
CuspsCalculation (..),
LongitudeComponents (..),
setEphemeridesPath,
setNoEphemeridesPath,
closeEphemerides,
withEphemerides,
withoutEphemerides,
calculateEclipticPosition,
calculateEquatorialPosition,
calculateObliquity,
calculateCusps,
calculateCuspsLenient,
calculateCuspsStrict,
equatorialToEcliptic,
eclipticToEquatorial,
calculateSiderealTime,
calculateSiderealTimeSimple,
calculateHousePosition,
calculateHousePositionSimple,
julianDay,
gregorianDateTime,
deltaTime,
defaultSplitDegreesOptions,
splitDegrees,
splitDegreesZodiac,
)
where
import Control.Exception (bracket_)
import Data.Semigroup ((<>))
import Foreign
import Foreign.C.String
import Foreign.SwissEphemeris
import SwissEphemeris.Internal
import System.IO.Unsafe (unsafePerformIO)
setEphemeridesPath :: FilePath -> IO ()
setEphemeridesPath :: FilePath -> IO ()
setEphemeridesPath FilePath
path =
FilePath -> (CString -> IO ()) -> IO ()
forall a. FilePath -> (CString -> IO a) -> IO a
withCString FilePath
path ((CString -> IO ()) -> IO ()) -> (CString -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \CString
ephePath -> CString -> IO ()
c_swe_set_ephe_path CString
ephePath
setNoEphemeridesPath :: IO ()
setNoEphemeridesPath :: IO ()
setNoEphemeridesPath = CString -> IO ()
c_swe_set_ephe_path CString
forall a. Ptr a
nullPtr
closeEphemerides :: IO ()
closeEphemerides :: IO ()
closeEphemerides = IO ()
c_swe_close
withEphemerides :: FilePath -> (IO a) -> IO a
withEphemerides :: FilePath -> IO a -> IO a
withEphemerides FilePath
ephemeridesPath =
IO () -> IO () -> IO a -> IO a
forall a b c. IO a -> IO b -> IO c -> IO c
bracket_
(FilePath -> IO ()
setEphemeridesPath FilePath
ephemeridesPath)
(IO ()
closeEphemerides)
withoutEphemerides :: (IO a) -> IO a
withoutEphemerides :: IO a -> IO a
withoutEphemerides =
IO () -> IO () -> IO a -> IO a
forall a b c. IO a -> IO b -> IO c -> IO c
bracket_
(IO ()
setNoEphemeridesPath)
(IO ()
closeEphemerides)
julianDay :: Int -> Int -> Int -> Double -> JulianTime
julianDay :: Int -> Int -> Int -> Double -> JulianTime
julianDay Int
year Int
month Int
day Double
hour = Double -> JulianTime
JulianTime (Double -> JulianTime) -> Double -> JulianTime
forall a b. (a -> b) -> a -> b
$ CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac (CDouble -> Double) -> CDouble -> Double
forall a b. (a -> b) -> a -> b
$ CInt -> CInt -> CInt -> CDouble -> GregFlag -> CDouble
c_swe_julday CInt
y CInt
m CInt
d CDouble
h GregFlag
gregorian
where
y :: CInt
y = Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
year
m :: CInt
m = Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
month
d :: CInt
d = Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
day
h :: CDouble
h = Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
hour
gregorianDateTime :: JulianTime -> (Int, Int, Int, Double)
gregorianDateTime :: JulianTime -> (Int, Int, Int, Double)
gregorianDateTime (JulianTime Double
jd) =
IO (Int, Int, Int, Double) -> (Int, Int, Int, Double)
forall a. IO a -> a
unsafePerformIO (IO (Int, Int, Int, Double) -> (Int, Int, Int, Double))
-> IO (Int, Int, Int, Double) -> (Int, Int, Int, Double)
forall a b. (a -> b) -> a -> b
$ do
(Ptr CInt -> IO (Int, Int, Int, Double))
-> IO (Int, Int, Int, Double)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CInt -> IO (Int, Int, Int, Double))
-> IO (Int, Int, Int, Double))
-> (Ptr CInt -> IO (Int, Int, Int, Double))
-> IO (Int, Int, Int, Double)
forall a b. (a -> b) -> a -> b
$ \Ptr CInt
jyear -> (Ptr CInt -> IO (Int, Int, Int, Double))
-> IO (Int, Int, Int, Double)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CInt -> IO (Int, Int, Int, Double))
-> IO (Int, Int, Int, Double))
-> (Ptr CInt -> IO (Int, Int, Int, Double))
-> IO (Int, Int, Int, Double)
forall a b. (a -> b) -> a -> b
$ \Ptr CInt
jmon -> (Ptr CInt -> IO (Int, Int, Int, Double))
-> IO (Int, Int, Int, Double)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CInt -> IO (Int, Int, Int, Double))
-> IO (Int, Int, Int, Double))
-> (Ptr CInt -> IO (Int, Int, Int, Double))
-> IO (Int, Int, Int, Double)
forall a b. (a -> b) -> a -> b
$ \Ptr CInt
jday -> (Ptr CDouble -> IO (Int, Int, Int, Double))
-> IO (Int, Int, Int, Double)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CDouble -> IO (Int, Int, Int, Double))
-> IO (Int, Int, Int, Double))
-> (Ptr CDouble -> IO (Int, Int, Int, Double))
-> IO (Int, Int, Int, Double)
forall a b. (a -> b) -> a -> b
$ \Ptr CDouble
jut -> do
()
_ <-
CDouble
-> GregFlag
-> Ptr CInt
-> Ptr CInt
-> Ptr CInt
-> Ptr CDouble
-> IO ()
c_swe_revjul
(Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
jd)
GregFlag
gregorian
Ptr CInt
jyear
Ptr CInt
jmon
Ptr CInt
jday
Ptr CDouble
jut
CInt
year <- Ptr CInt -> IO CInt
forall a. Storable a => Ptr a -> IO a
peek Ptr CInt
jyear
CInt
month <- Ptr CInt -> IO CInt
forall a. Storable a => Ptr a -> IO a
peek Ptr CInt
jmon
CInt
day <- Ptr CInt -> IO CInt
forall a. Storable a => Ptr a -> IO a
peek Ptr CInt
jday
CDouble
time <- Ptr CDouble -> IO CDouble
forall a. Storable a => Ptr a -> IO a
peek Ptr CDouble
jut
(Int, Int, Int, Double) -> IO (Int, Int, Int, Double)
forall (m :: * -> *) a. Monad m => a -> m a
return ((Int, Int, Int, Double) -> IO (Int, Int, Int, Double))
-> (Int, Int, Int, Double) -> IO (Int, Int, Int, Double)
forall a b. (a -> b) -> a -> b
$ (CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
year, CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
month, CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
day, CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
time)
calculateEclipticPosition :: JulianTime -> Planet -> IO (Either String EclipticPosition)
calculateEclipticPosition :: JulianTime -> Planet -> IO (Either FilePath EclipticPosition)
calculateEclipticPosition JulianTime
time Planet
planet = do
let options :: CalcFlag
options = ([CalcFlag] -> CalcFlag
mkCalculationOptions [CalcFlag]
defaultCalculationOptions)
Either FilePath [Double]
rawCoords <- CalcFlag
-> JulianTime -> PlanetNumber -> IO (Either FilePath [Double])
calculateCoordinates' CalcFlag
options JulianTime
time (Planet -> PlanetNumber
planetNumber Planet
planet)
Either FilePath EclipticPosition
-> IO (Either FilePath EclipticPosition)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either FilePath EclipticPosition
-> IO (Either FilePath EclipticPosition))
-> Either FilePath EclipticPosition
-> IO (Either FilePath EclipticPosition)
forall a b. (a -> b) -> a -> b
$ ([Double] -> EclipticPosition)
-> Either FilePath [Double] -> Either FilePath EclipticPosition
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Double] -> EclipticPosition
coordinatesFromList Either FilePath [Double]
rawCoords
calculateEquatorialPosition :: JulianTime -> Planet -> IO (Either String EquatorialPosition)
calculateEquatorialPosition :: JulianTime -> Planet -> IO (Either FilePath EquatorialPosition)
calculateEquatorialPosition JulianTime
time Planet
planet = do
let options :: CalcFlag
options = ([CalcFlag] -> CalcFlag
mkCalculationOptions ([CalcFlag] -> CalcFlag) -> [CalcFlag] -> CalcFlag
forall a b. (a -> b) -> a -> b
$ [CalcFlag]
defaultCalculationOptions [CalcFlag] -> [CalcFlag] -> [CalcFlag]
forall a. [a] -> [a] -> [a]
++ [CalcFlag
equatorialPositions])
Either FilePath [Double]
rawCoords <- CalcFlag
-> JulianTime -> PlanetNumber -> IO (Either FilePath [Double])
calculateCoordinates' CalcFlag
options JulianTime
time (Planet -> PlanetNumber
planetNumber Planet
planet)
Either FilePath EquatorialPosition
-> IO (Either FilePath EquatorialPosition)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either FilePath EquatorialPosition
-> IO (Either FilePath EquatorialPosition))
-> Either FilePath EquatorialPosition
-> IO (Either FilePath EquatorialPosition)
forall a b. (a -> b) -> a -> b
$ ([Double] -> EquatorialPosition)
-> Either FilePath [Double] -> Either FilePath EquatorialPosition
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Double] -> EquatorialPosition
equatorialFromList Either FilePath [Double]
rawCoords
calculateObliquity :: JulianTime -> IO (Either String ObliquityInformation)
calculateObliquity :: JulianTime -> IO (Either FilePath ObliquityInformation)
calculateObliquity JulianTime
time = do
let options :: CalcFlag
options = CInt -> CalcFlag
CalcFlag CInt
0
Either FilePath [Double]
rawCoords <- CalcFlag
-> JulianTime -> PlanetNumber -> IO (Either FilePath [Double])
calculateCoordinates' CalcFlag
options JulianTime
time PlanetNumber
specialEclNut
Either FilePath ObliquityInformation
-> IO (Either FilePath ObliquityInformation)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either FilePath ObliquityInformation
-> IO (Either FilePath ObliquityInformation))
-> Either FilePath ObliquityInformation
-> IO (Either FilePath ObliquityInformation)
forall a b. (a -> b) -> a -> b
$ ([Double] -> ObliquityInformation)
-> Either FilePath [Double] -> Either FilePath ObliquityInformation
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Double] -> ObliquityInformation
obliquityNutationFromList Either FilePath [Double]
rawCoords
calculateCoordinates' :: CalcFlag -> JulianTime -> PlanetNumber -> IO (Either String [Double])
calculateCoordinates' :: CalcFlag
-> JulianTime -> PlanetNumber -> IO (Either FilePath [Double])
calculateCoordinates' CalcFlag
options JulianTime
time PlanetNumber
planet =
Int
-> (Ptr CDouble -> IO (Either FilePath [Double]))
-> IO (Either FilePath [Double])
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
6 ((Ptr CDouble -> IO (Either FilePath [Double]))
-> IO (Either FilePath [Double]))
-> (Ptr CDouble -> IO (Either FilePath [Double]))
-> IO (Either FilePath [Double])
forall a b. (a -> b) -> a -> b
$ \Ptr CDouble
coords -> Int
-> (CString -> IO (Either FilePath [Double]))
-> IO (Either FilePath [Double])
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
256 ((CString -> IO (Either FilePath [Double]))
-> IO (Either FilePath [Double]))
-> (CString -> IO (Either FilePath [Double]))
-> IO (Either FilePath [Double])
forall a b. (a -> b) -> a -> b
$ \CString
serr -> do
CalcFlag
iflgret <-
CDouble
-> PlanetNumber
-> CalcFlag
-> Ptr CDouble
-> CString
-> IO CalcFlag
c_swe_calc_ut
(Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> CDouble)
-> (JulianTime -> Double) -> JulianTime -> CDouble
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JulianTime -> Double
unJulianTime (JulianTime -> CDouble) -> JulianTime -> CDouble
forall a b. (a -> b) -> a -> b
$ JulianTime
time)
PlanetNumber
planet
CalcFlag
options
Ptr CDouble
coords
CString
serr
if CalcFlag -> CInt
unCalcFlag CalcFlag
iflgret CInt -> CInt -> Bool
forall a. Ord a => a -> a -> Bool
< CInt
0
then do
FilePath
msg <- CString -> IO FilePath
peekCAString CString
serr
Either FilePath [Double] -> IO (Either FilePath [Double])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either FilePath [Double] -> IO (Either FilePath [Double]))
-> Either FilePath [Double] -> IO (Either FilePath [Double])
forall a b. (a -> b) -> a -> b
$ FilePath -> Either FilePath [Double]
forall a b. a -> Either a b
Left FilePath
msg
else do
[CDouble]
result <- Int -> Ptr CDouble -> IO [CDouble]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
6 Ptr CDouble
coords
Either FilePath [Double] -> IO (Either FilePath [Double])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either FilePath [Double] -> IO (Either FilePath [Double]))
-> Either FilePath [Double] -> IO (Either FilePath [Double])
forall a b. (a -> b) -> a -> b
$ [Double] -> Either FilePath [Double]
forall a b. b -> Either a b
Right ([Double] -> Either FilePath [Double])
-> [Double] -> Either FilePath [Double]
forall a b. (a -> b) -> a -> b
$ (CDouble -> Double) -> [CDouble] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac [CDouble]
result
eclipticToEquatorial :: ObliquityInformation -> EclipticPosition -> EquatorialPosition
eclipticToEquatorial :: ObliquityInformation -> EclipticPosition -> EquatorialPosition
eclipticToEquatorial ObliquityInformation
oAndN EclipticPosition
ecliptic =
let obliquityLn :: Double
obliquityLn = ObliquityInformation -> Double
eclipticObliquity ObliquityInformation
oAndN
eclipticPos :: [Double]
eclipticPos = EclipticPosition -> [Double]
eclipticToList EclipticPosition
ecliptic
transformed :: [Double]
transformed = Double -> [Double] -> [Double]
coordinateTransform' (Double -> Double
forall a. Num a => a -> a
negate Double
obliquityLn) [Double]
eclipticPos
in [Double] -> EquatorialPosition
equatorialFromList [Double]
transformed
equatorialToEcliptic :: ObliquityInformation -> EquatorialPosition -> EclipticPosition
equatorialToEcliptic :: ObliquityInformation -> EquatorialPosition -> EclipticPosition
equatorialToEcliptic ObliquityInformation
oAndN EquatorialPosition
equatorial =
let obliquityLn :: Double
obliquityLn = ObliquityInformation -> Double
eclipticObliquity ObliquityInformation
oAndN
equatorialPos :: [Double]
equatorialPos = EquatorialPosition -> [Double]
equatorialToList EquatorialPosition
equatorial
transformed :: [Double]
transformed = Double -> [Double] -> [Double]
coordinateTransform' Double
obliquityLn [Double]
equatorialPos
in [Double] -> EclipticPosition
eclipticFromList [Double]
transformed
coordinateTransform' :: Double -> [Double] -> [Double]
coordinateTransform' :: Double -> [Double] -> [Double]
coordinateTransform' Double
obliquity [Double]
ins =
IO [Double] -> [Double]
forall a. IO a -> a
unsafePerformIO (IO [Double] -> [Double]) -> IO [Double] -> [Double]
forall a b. (a -> b) -> a -> b
$ do
[CDouble] -> (Ptr CDouble -> IO [Double]) -> IO [Double]
forall a b. Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray ((Double -> CDouble) -> [Double] -> [CDouble]
forall a b. (a -> b) -> [a] -> [b]
map Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac ([Double] -> [CDouble]) -> [Double] -> [CDouble]
forall a b. (a -> b) -> a -> b
$ Int -> [Double] -> [Double]
forall a. Int -> [a] -> [a]
take Int
6 [Double]
ins) ((Ptr CDouble -> IO [Double]) -> IO [Double])
-> (Ptr CDouble -> IO [Double]) -> IO [Double]
forall a b. (a -> b) -> a -> b
$ \Ptr CDouble
xpo -> Int -> (Ptr CDouble -> IO [Double]) -> IO [Double]
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
6 ((Ptr CDouble -> IO [Double]) -> IO [Double])
-> (Ptr CDouble -> IO [Double]) -> IO [Double]
forall a b. (a -> b) -> a -> b
$ \Ptr CDouble
xpn -> do
()
_ <- Ptr CDouble -> Ptr CDouble -> CDouble -> IO ()
c_swe_cotrans_sp Ptr CDouble
xpo Ptr CDouble
xpn (Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
obliquity)
[CDouble]
result <- Int -> Ptr CDouble -> IO [CDouble]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
6 Ptr CDouble
xpn
[Double] -> IO [Double]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Double] -> IO [Double]) -> [Double] -> IO [Double]
forall a b. (a -> b) -> a -> b
$ (CDouble -> Double) -> [CDouble] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac [CDouble]
result
calculateCusps :: HouseSystem -> JulianTime -> GeographicPosition -> IO CuspsCalculation
calculateCusps :: HouseSystem
-> JulianTime -> GeographicPosition -> IO CuspsCalculation
calculateCusps = HouseSystem
-> JulianTime -> GeographicPosition -> IO CuspsCalculation
calculateCuspsLenient
calculateCuspsLenient :: HouseSystem -> JulianTime -> GeographicPosition -> IO CuspsCalculation
calculateCuspsLenient :: HouseSystem
-> JulianTime -> GeographicPosition -> IO CuspsCalculation
calculateCuspsLenient HouseSystem
sys JulianTime
time GeographicPosition
loc =
Int -> (Ptr CDouble -> IO CuspsCalculation) -> IO CuspsCalculation
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
13 ((Ptr CDouble -> IO CuspsCalculation) -> IO CuspsCalculation)
-> (Ptr CDouble -> IO CuspsCalculation) -> IO CuspsCalculation
forall a b. (a -> b) -> a -> b
$ \Ptr CDouble
cusps -> Int -> (Ptr CDouble -> IO CuspsCalculation) -> IO CuspsCalculation
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
10 ((Ptr CDouble -> IO CuspsCalculation) -> IO CuspsCalculation)
-> (Ptr CDouble -> IO CuspsCalculation) -> IO CuspsCalculation
forall a b. (a -> b) -> a -> b
$ \Ptr CDouble
ascmc -> do
CInt
rval <-
CDouble
-> CDouble
-> CDouble
-> CInt
-> Ptr CDouble
-> Ptr CDouble
-> IO CInt
c_swe_houses
(Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> CDouble)
-> (JulianTime -> Double) -> JulianTime -> CDouble
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JulianTime -> Double
unJulianTime (JulianTime -> CDouble) -> JulianTime -> CDouble
forall a b. (a -> b) -> a -> b
$ JulianTime
time)
(Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> CDouble) -> Double -> CDouble
forall a b. (a -> b) -> a -> b
$ GeographicPosition -> Double
geoLat GeographicPosition
loc)
(Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> CDouble) -> Double -> CDouble
forall a b. (a -> b) -> a -> b
$ GeographicPosition -> Double
geoLng GeographicPosition
loc)
(Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CInt) -> Int -> CInt
forall a b. (a -> b) -> a -> b
$ HouseSystem -> Int
toHouseSystemFlag HouseSystem
sys)
Ptr CDouble
cusps
Ptr CDouble
ascmc
(CDouble
_ : [CDouble]
cuspsL) <- Int -> Ptr CDouble -> IO [CDouble]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
13 Ptr CDouble
cusps
[CDouble]
anglesL <- Int -> Ptr CDouble -> IO [CDouble]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
10 Ptr CDouble
ascmc
CuspsCalculation -> IO CuspsCalculation
forall (m :: * -> *) a. Monad m => a -> m a
return (CuspsCalculation -> IO CuspsCalculation)
-> CuspsCalculation -> IO CuspsCalculation
forall a b. (a -> b) -> a -> b
$
[Double] -> Angles -> HouseSystem -> CuspsCalculation
CuspsCalculation
((CDouble -> Double) -> [CDouble] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac ([CDouble] -> [Double]) -> [CDouble] -> [Double]
forall a b. (a -> b) -> a -> b
$ [CDouble]
cuspsL)
([Double] -> Angles
anglesFromList ([Double] -> Angles) -> [Double] -> Angles
forall a b. (a -> b) -> a -> b
$ (CDouble -> Double) -> [CDouble] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac ([CDouble] -> [Double]) -> [CDouble] -> [Double]
forall a b. (a -> b) -> a -> b
$ [CDouble]
anglesL)
(if CInt
rval CInt -> CInt -> Bool
forall a. Ord a => a -> a -> Bool
< CInt
0 then HouseSystem
Porphyrius else HouseSystem
sys)
calculateCuspsStrict :: HouseSystem -> JulianTime -> GeographicPosition -> IO (Either String CuspsCalculation)
calculateCuspsStrict :: HouseSystem
-> JulianTime
-> GeographicPosition
-> IO (Either FilePath CuspsCalculation)
calculateCuspsStrict HouseSystem
sys JulianTime
time GeographicPosition
loc = do
calcs :: CuspsCalculation
calcs@(CuspsCalculation [Double]
_ Angles
_ HouseSystem
sys') <- HouseSystem
-> JulianTime -> GeographicPosition -> IO CuspsCalculation
calculateCuspsLenient HouseSystem
sys JulianTime
time GeographicPosition
loc
if HouseSystem
sys' HouseSystem -> HouseSystem -> Bool
forall a. Eq a => a -> a -> Bool
/= HouseSystem
sys
then Either FilePath CuspsCalculation
-> IO (Either FilePath CuspsCalculation)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either FilePath CuspsCalculation
-> IO (Either FilePath CuspsCalculation))
-> Either FilePath CuspsCalculation
-> IO (Either FilePath CuspsCalculation)
forall a b. (a -> b) -> a -> b
$ FilePath -> Either FilePath CuspsCalculation
forall a b. a -> Either a b
Left (FilePath -> Either FilePath CuspsCalculation)
-> FilePath -> Either FilePath CuspsCalculation
forall a b. (a -> b) -> a -> b
$ FilePath
"Unable to calculate cusps in the requested house system (used " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ (HouseSystem -> FilePath
forall a. Show a => a -> FilePath
show HouseSystem
sys') FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
" instead.)"
else Either FilePath CuspsCalculation
-> IO (Either FilePath CuspsCalculation)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either FilePath CuspsCalculation
-> IO (Either FilePath CuspsCalculation))
-> Either FilePath CuspsCalculation
-> IO (Either FilePath CuspsCalculation)
forall a b. (a -> b) -> a -> b
$ CuspsCalculation -> Either FilePath CuspsCalculation
forall a b. b -> Either a b
Right CuspsCalculation
calcs
calculateHousePositionSimple :: HouseSystem -> JulianTime -> GeographicPosition -> EclipticPosition -> IO (Either String HousePosition)
calculateHousePositionSimple :: HouseSystem
-> JulianTime
-> GeographicPosition
-> EclipticPosition
-> IO (Either FilePath HousePosition)
calculateHousePositionSimple HouseSystem
sys JulianTime
time GeographicPosition
loc EclipticPosition
pos = do
Either FilePath ObliquityInformation
obliquityAndNutation <- JulianTime -> IO (Either FilePath ObliquityInformation)
calculateObliquity JulianTime
time
case Either FilePath ObliquityInformation
obliquityAndNutation of
Left FilePath
e -> Either FilePath HousePosition -> IO (Either FilePath HousePosition)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either FilePath HousePosition
-> IO (Either FilePath HousePosition))
-> Either FilePath HousePosition
-> IO (Either FilePath HousePosition)
forall a b. (a -> b) -> a -> b
$ FilePath -> Either FilePath HousePosition
forall a b. a -> Either a b
Left FilePath
e
Right ObliquityInformation
on -> do
SiderealTime Double
siderealTime <- JulianTime -> ObliquityInformation -> IO SiderealTime
calculateSiderealTime JulianTime
time ObliquityInformation
on
let armc' :: Double
armc' = Double
siderealTime Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
15 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ GeographicPosition -> Double
geoLng GeographicPosition
loc
HouseSystem
-> Double
-> GeographicPosition
-> ObliquityInformation
-> EclipticPosition
-> IO (Either FilePath HousePosition)
calculateHousePosition HouseSystem
sys Double
armc' GeographicPosition
loc ObliquityInformation
on EclipticPosition
pos
calculateHousePosition :: HouseSystem -> Double -> GeographicPosition -> ObliquityInformation -> EclipticPosition -> IO (Either String HousePosition)
calculateHousePosition :: HouseSystem
-> Double
-> GeographicPosition
-> ObliquityInformation
-> EclipticPosition
-> IO (Either FilePath HousePosition)
calculateHousePosition HouseSystem
sys Double
armc' GeographicPosition
geoCoords ObliquityInformation
obliq EclipticPosition
eclipticCoords =
[CDouble]
-> (Ptr CDouble -> IO (Either FilePath HousePosition))
-> IO (Either FilePath HousePosition)
forall a b. Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray [Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> CDouble) -> Double -> CDouble
forall a b. (a -> b) -> a -> b
$ EclipticPosition -> Double
lng EclipticPosition
eclipticCoords, Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> CDouble) -> Double -> CDouble
forall a b. (a -> b) -> a -> b
$ EclipticPosition -> Double
lat EclipticPosition
eclipticCoords] ((Ptr CDouble -> IO (Either FilePath HousePosition))
-> IO (Either FilePath HousePosition))
-> (Ptr CDouble -> IO (Either FilePath HousePosition))
-> IO (Either FilePath HousePosition)
forall a b. (a -> b) -> a -> b
$ \Ptr CDouble
xpin -> Int
-> (CString -> IO (Either FilePath HousePosition))
-> IO (Either FilePath HousePosition)
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
256 ((CString -> IO (Either FilePath HousePosition))
-> IO (Either FilePath HousePosition))
-> (CString -> IO (Either FilePath HousePosition))
-> IO (Either FilePath HousePosition)
forall a b. (a -> b) -> a -> b
$ \CString
serr -> do
CDouble
housePos <-
CDouble
-> CDouble
-> CDouble
-> CInt
-> Ptr CDouble
-> CString
-> IO CDouble
c_swe_house_pos
(Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
armc')
(Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> CDouble) -> Double -> CDouble
forall a b. (a -> b) -> a -> b
$ GeographicPosition -> Double
geoLat GeographicPosition
geoCoords)
(Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> CDouble) -> Double -> CDouble
forall a b. (a -> b) -> a -> b
$ ObliquityInformation -> Double
eclipticObliquity ObliquityInformation
obliq)
(Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CInt) -> Int -> CInt
forall a b. (a -> b) -> a -> b
$ HouseSystem -> Int
toHouseSystemFlag HouseSystem
sys)
Ptr CDouble
xpin
CString
serr
if CDouble
housePos CDouble -> CDouble -> Bool
forall a. Ord a => a -> a -> Bool
<= CDouble
0
then do
FilePath
msg <- CString -> IO FilePath
peekCAString CString
serr
Either FilePath HousePosition -> IO (Either FilePath HousePosition)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either FilePath HousePosition
-> IO (Either FilePath HousePosition))
-> Either FilePath HousePosition
-> IO (Either FilePath HousePosition)
forall a b. (a -> b) -> a -> b
$ FilePath -> Either FilePath HousePosition
forall a b. a -> Either a b
Left FilePath
msg
else do
let houseN :: Int
houseN = CDouble -> Int
forall a b. (RealFrac a, Integral b) => a -> b
truncate CDouble
housePos
cuspD :: CDouble
cuspD = CDouble
housePos CDouble -> CDouble -> CDouble
forall a. Num a => a -> a -> a
- (Int -> CDouble
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
houseN)
Either FilePath HousePosition -> IO (Either FilePath HousePosition)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either FilePath HousePosition
-> IO (Either FilePath HousePosition))
-> Either FilePath HousePosition
-> IO (Either FilePath HousePosition)
forall a b. (a -> b) -> a -> b
$ HousePosition -> Either FilePath HousePosition
forall a b. b -> Either a b
Right (HousePosition -> Either FilePath HousePosition)
-> HousePosition -> Either FilePath HousePosition
forall a b. (a -> b) -> a -> b
$ Int -> Double -> HousePosition
HousePosition Int
houseN (CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
cuspD)
calculateSiderealTimeSimple :: JulianTime -> IO SiderealTime
calculateSiderealTimeSimple :: JulianTime -> IO SiderealTime
calculateSiderealTimeSimple JulianTime
jt = do
CDouble
sidTime <- CDouble -> IO CDouble
c_swe_sidtime (Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> CDouble)
-> (JulianTime -> Double) -> JulianTime -> CDouble
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JulianTime -> Double
unJulianTime (JulianTime -> CDouble) -> JulianTime -> CDouble
forall a b. (a -> b) -> a -> b
$ JulianTime
jt)
SiderealTime -> IO SiderealTime
forall (m :: * -> *) a. Monad m => a -> m a
return (SiderealTime -> IO SiderealTime)
-> SiderealTime -> IO SiderealTime
forall a b. (a -> b) -> a -> b
$ Double -> SiderealTime
SiderealTime (Double -> SiderealTime) -> Double -> SiderealTime
forall a b. (a -> b) -> a -> b
$ CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
sidTime
calculateSiderealTime :: JulianTime -> ObliquityInformation -> IO SiderealTime
calculateSiderealTime :: JulianTime -> ObliquityInformation -> IO SiderealTime
calculateSiderealTime JulianTime
jt ObliquityInformation
on = do
let obliq :: CDouble
obliq = Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> CDouble) -> Double -> CDouble
forall a b. (a -> b) -> a -> b
$ ObliquityInformation -> Double
eclipticObliquity ObliquityInformation
on
nut :: CDouble
nut = Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> CDouble) -> Double -> CDouble
forall a b. (a -> b) -> a -> b
$ ObliquityInformation -> Double
nutationLongitude ObliquityInformation
on
CDouble
sidTime <- CDouble -> CDouble -> CDouble -> IO CDouble
c_swe_sidtime0 (Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> CDouble)
-> (JulianTime -> Double) -> JulianTime -> CDouble
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JulianTime -> Double
unJulianTime (JulianTime -> CDouble) -> JulianTime -> CDouble
forall a b. (a -> b) -> a -> b
$ JulianTime
jt) CDouble
obliq CDouble
nut
SiderealTime -> IO SiderealTime
forall (m :: * -> *) a. Monad m => a -> m a
return (SiderealTime -> IO SiderealTime)
-> SiderealTime -> IO SiderealTime
forall a b. (a -> b) -> a -> b
$ Double -> SiderealTime
SiderealTime (Double -> SiderealTime) -> Double -> SiderealTime
forall a b. (a -> b) -> a -> b
$ CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
sidTime
deltaTime :: JulianTime -> IO Double
deltaTime :: JulianTime -> IO Double
deltaTime JulianTime
jt = do
CDouble
deltaT <- CDouble -> IO CDouble
c_swe_deltat (CDouble -> IO CDouble)
-> (JulianTime -> CDouble) -> JulianTime -> IO CDouble
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> CDouble)
-> (JulianTime -> Double) -> JulianTime -> CDouble
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JulianTime -> Double
unJulianTime (JulianTime -> IO CDouble) -> JulianTime -> IO CDouble
forall a b. (a -> b) -> a -> b
$ JulianTime
jt
Double -> IO Double
forall (m :: * -> *) a. Monad m => a -> m a
return (Double -> IO Double) -> Double -> IO Double
forall a b. (a -> b) -> a -> b
$ CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
deltaT
splitDegreesZodiac :: Double -> LongitudeComponents
splitDegreesZodiac :: Double -> LongitudeComponents
splitDegreesZodiac = [SplitDegreesOption] -> Double -> LongitudeComponents
splitDegrees ([SplitDegreesOption] -> Double -> LongitudeComponents)
-> [SplitDegreesOption] -> Double -> LongitudeComponents
forall a b. (a -> b) -> a -> b
$ [SplitDegreesOption]
defaultSplitDegreesOptions [SplitDegreesOption]
-> [SplitDegreesOption] -> [SplitDegreesOption]
forall a. Semigroup a => a -> a -> a
<> [SplitDegreesOption
SplitZodiacal, SplitDegreesOption
RoundSeconds]
splitDegrees :: [SplitDegreesOption] -> Double -> LongitudeComponents
splitDegrees :: [SplitDegreesOption] -> Double -> LongitudeComponents
splitDegrees [SplitDegreesOption]
options Double
d =
Maybe ZodiacSignName
-> Integer
-> Integer
-> Integer
-> Double
-> Maybe Int
-> Maybe NakshatraName
-> LongitudeComponents
LongitudeComponents Maybe ZodiacSignName
sign Integer
deg Integer
m Integer
s Double
sf Maybe Int
signum' Maybe NakshatraName
nak
where
(Int
z, Integer
deg, Integer
m, Integer
s, Double
sf) = SplitDegFlag -> Double -> (Int, Integer, Integer, Integer, Double)
splitDegrees' SplitDegFlag
flags Double
d
flags :: SplitDegFlag
flags = [SplitDegFlag] -> SplitDegFlag
foldSplitDegOptions ([SplitDegFlag] -> SplitDegFlag) -> [SplitDegFlag] -> SplitDegFlag
forall a b. (a -> b) -> a -> b
$ (SplitDegreesOption -> SplitDegFlag)
-> [SplitDegreesOption] -> [SplitDegFlag]
forall a b. (a -> b) -> [a] -> [b]
map SplitDegreesOption -> SplitDegFlag
splitOptionToFlag [SplitDegreesOption]
options
isZodiacSplit :: Bool
isZodiacSplit = SplitDegreesOption
SplitZodiacal SplitDegreesOption -> [SplitDegreesOption] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [SplitDegreesOption]
options
isNakshatraSplit :: Bool
isNakshatraSplit = SplitDegreesOption
SplitNakshatra SplitDegreesOption -> [SplitDegreesOption] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [SplitDegreesOption]
options
sign :: Maybe ZodiacSignName
sign = if Bool
isZodiacSplit then (ZodiacSignName -> Maybe ZodiacSignName
forall a. a -> Maybe a
Just (ZodiacSignName -> Maybe ZodiacSignName)
-> (Int -> ZodiacSignName) -> Int -> Maybe ZodiacSignName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ZodiacSignName
forall a. Enum a => Int -> a
toEnum (Int -> Maybe ZodiacSignName) -> Int -> Maybe ZodiacSignName
forall a b. (a -> b) -> a -> b
$ Int
z) else Maybe ZodiacSignName
forall a. Maybe a
Nothing
nak :: Maybe NakshatraName
nak = if Bool
isNakshatraSplit then (NakshatraName -> Maybe NakshatraName
forall a. a -> Maybe a
Just (NakshatraName -> Maybe NakshatraName)
-> (Int -> NakshatraName) -> Int -> Maybe NakshatraName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> NakshatraName
forall a. Enum a => Int -> a
toEnum (Int -> Maybe NakshatraName) -> Int -> Maybe NakshatraName
forall a b. (a -> b) -> a -> b
$ Int
z) else Maybe NakshatraName
forall a. Maybe a
Nothing
signum' :: Maybe Int
signum' = if (Bool -> Bool
not Bool
isZodiacSplit Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
isNakshatraSplit) then Int -> Maybe Int
forall a. a -> Maybe a
Just Int
z else Maybe Int
forall a. Maybe a
Nothing
splitDegrees' :: SplitDegFlag -> Double -> (Int, Integer, Integer, Integer, Double)
splitDegrees' :: SplitDegFlag -> Double -> (Int, Integer, Integer, Integer, Double)
splitDegrees' SplitDegFlag
options Double
deg =
IO (Int, Integer, Integer, Integer, Double)
-> (Int, Integer, Integer, Integer, Double)
forall a. IO a -> a
unsafePerformIO (IO (Int, Integer, Integer, Integer, Double)
-> (Int, Integer, Integer, Integer, Double))
-> IO (Int, Integer, Integer, Integer, Double)
-> (Int, Integer, Integer, Integer, Double)
forall a b. (a -> b) -> a -> b
$ do
(Ptr CInt -> IO (Int, Integer, Integer, Integer, Double))
-> IO (Int, Integer, Integer, Integer, Double)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CInt -> IO (Int, Integer, Integer, Integer, Double))
-> IO (Int, Integer, Integer, Integer, Double))
-> (Ptr CInt -> IO (Int, Integer, Integer, Integer, Double))
-> IO (Int, Integer, Integer, Integer, Double)
forall a b. (a -> b) -> a -> b
$ \Ptr CInt
ideg -> (Ptr CInt -> IO (Int, Integer, Integer, Integer, Double))
-> IO (Int, Integer, Integer, Integer, Double)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CInt -> IO (Int, Integer, Integer, Integer, Double))
-> IO (Int, Integer, Integer, Integer, Double))
-> (Ptr CInt -> IO (Int, Integer, Integer, Integer, Double))
-> IO (Int, Integer, Integer, Integer, Double)
forall a b. (a -> b) -> a -> b
$ \Ptr CInt
imin -> (Ptr CInt -> IO (Int, Integer, Integer, Integer, Double))
-> IO (Int, Integer, Integer, Integer, Double)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CInt -> IO (Int, Integer, Integer, Integer, Double))
-> IO (Int, Integer, Integer, Integer, Double))
-> (Ptr CInt -> IO (Int, Integer, Integer, Integer, Double))
-> IO (Int, Integer, Integer, Integer, Double)
forall a b. (a -> b) -> a -> b
$ \Ptr CInt
isec -> (Ptr CDouble -> IO (Int, Integer, Integer, Integer, Double))
-> IO (Int, Integer, Integer, Integer, Double)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CDouble -> IO (Int, Integer, Integer, Integer, Double))
-> IO (Int, Integer, Integer, Integer, Double))
-> (Ptr CDouble -> IO (Int, Integer, Integer, Integer, Double))
-> IO (Int, Integer, Integer, Integer, Double)
forall a b. (a -> b) -> a -> b
$ \Ptr CDouble
dsecfr -> (Ptr CInt -> IO (Int, Integer, Integer, Integer, Double))
-> IO (Int, Integer, Integer, Integer, Double)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CInt -> IO (Int, Integer, Integer, Integer, Double))
-> IO (Int, Integer, Integer, Integer, Double))
-> (Ptr CInt -> IO (Int, Integer, Integer, Integer, Double))
-> IO (Int, Integer, Integer, Integer, Double)
forall a b. (a -> b) -> a -> b
$ \Ptr CInt
isign -> do
Ptr CDouble -> CDouble -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CDouble
dsecfr CDouble
0
()
_ <-
CDouble
-> SplitDegFlag
-> Ptr CInt
-> Ptr CInt
-> Ptr CInt
-> Ptr CDouble
-> Ptr CInt
-> IO ()
c_swe_split_deg
(Double -> CDouble
forall a b. (Real a, Fractional b) => a -> b
realToFrac Double
deg)
SplitDegFlag
options
Ptr CInt
ideg
Ptr CInt
imin
Ptr CInt
isec
Ptr CDouble
dsecfr
Ptr CInt
isign
CInt
sign' <- Ptr CInt -> IO CInt
forall a. Storable a => Ptr a -> IO a
peek Ptr CInt
isign
CInt
deg' <- Ptr CInt -> IO CInt
forall a. Storable a => Ptr a -> IO a
peek Ptr CInt
ideg
CInt
min' <- Ptr CInt -> IO CInt
forall a. Storable a => Ptr a -> IO a
peek Ptr CInt
imin
CInt
sec' <- Ptr CInt -> IO CInt
forall a. Storable a => Ptr a -> IO a
peek Ptr CInt
isec
CDouble
secfr <- Ptr CDouble -> IO CDouble
forall a. Storable a => Ptr a -> IO a
peek Ptr CDouble
dsecfr
(Int, Integer, Integer, Integer, Double)
-> IO (Int, Integer, Integer, Integer, Double)
forall (m :: * -> *) a. Monad m => a -> m a
return ((Int, Integer, Integer, Integer, Double)
-> IO (Int, Integer, Integer, Integer, Double))
-> (Int, Integer, Integer, Integer, Double)
-> IO (Int, Integer, Integer, Integer, Double)
forall a b. (a -> b) -> a -> b
$ ((CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
sign'), (CInt -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
deg'), (CInt -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
min'), (CInt -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
sec'), (CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
secfr))