packages feed

currycarbon 0.2.1.1 → 0.2.1.2

raw patch · 15 files changed

+187/−184 lines, 15 filesdep ~optparse-applicativePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: optparse-applicative

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -1,3 +1,4 @@+- V 0.2.1.2: Maintenance: Switched to a newer compiler/resolver version, lifted some dependency restrictions, ran stylish-haskell on the entire codebase, updated the github actions, deprecated the haddock documentation for the dev version on GitHub - V 0.2.1.1: Lifted some restrictions regarding the upper version bounds of dependencies - V 0.2.1.0: Added a mechanism to detect terminal encoding and fall back on a simpler CLI plot if it is not UTF-8 - V 0.2.0.1: Brought sample names back to default CLI output
README.md view
@@ -8,14 +8,13 @@  ### Library -The Haskell library is available on Hackage [here](https://hackage.haskell.org/package/currycarbon).-This repository stores the dev version with up-to-date documentation available [here](https://nevrome.github.io/currycarbon).+The Haskell library is available on Hackage [here](https://hackage.haskell.org/package/currycarbon) and on Stackage [here](https://www.stackage.org/package/currycarbon).  ### CLI app  For stable release versions we automatically prepare statically built binaries that can be downloaded and run directly. -You can download them here: [ [Linux 📥](https://github.com/nevrome/currycarbon/releases/latest/download/currycarbon-Linux) | [macOS 📥](https://github.com/nevrome/currycarbon/releases/latest/download/currycarbon-macOS) | [Windows 📥](https://github.com/nevrome/currycarbon/releases/latest/download/currycarbon-Windows.exe) ]. Older release versions are available [here](https://github.com/nevrome/currycarbon/releases).+You can download them here: [ [Linux 📥](https://github.com/nevrome/currycarbon/releases/latest/download/currycarbon-Linux) | [macOS 📥](https://github.com/nevrome/currycarbon/releases/latest/download/currycarbon-macOS) ]. Older release versions (some with Windows builds) are available [here](https://github.com/nevrome/currycarbon/releases).  So in Linux you can run the following commands to get started: @@ -113,7 +112,7 @@  ### For developers who want to edit the code -To install the latest development version (!) you can follow these steps:+To install the latest development version you can follow these steps:  1. Install the Haskell build tool [Stack](https://docs.haskellstack.org/en/stable/README/) 2. Clone the repository
currycarbon.cabal view
@@ -1,5 +1,5 @@ name:                currycarbon-version:             0.2.1.1+version:             0.2.1.2 synopsis:            A package for simple, fast radiocarbon calibration description:         Radiocarbon calibration with the intercept method optimised for fast calibration of many dates. homepage:            https://github.com/nevrome/currycarbon@@ -49,11 +49,11 @@     build-depends:               currycarbon       , base-      , optparse-applicative >= 0.16 && < 0.18+      , optparse-applicative >= 0.16 && < 0.19       , filepath     other-modules:       Paths_currycarbon     default-language:       Haskell2010     ghc-options: -      -threaded -with-rtsopts=-N+      -threaded -with-rtsopts=-N -optP-Wno-nonportable-include-path
src-executables/Main-currycarbon.hs view
@@ -1,17 +1,18 @@ {-# LANGUAGE OverloadedStrings #-} -import           Currycarbon.CLI.RunCalibrate       (runCalibrate, -                                                     CalibrateOptions (..))+import           Currycarbon.CLI.RunCalibrate (CalibrateOptions (..),+                                               runCalibrate) import           Currycarbon.Parsers import           Currycarbon.Types import           Currycarbon.Utils-import           Paths_currycarbon                  (version)+import           Paths_currycarbon            (version) -import           Control.Exception                  (catch)-import           Data.Version                       (showVersion)-import qualified Options.Applicative                as OP-import           System.Exit                        (exitFailure)-import           System.IO                          (hPutStrLn, stderr, stdout, hGetEncoding)+import           Control.Exception            (catch)+import           Data.Version                 (showVersion)+import qualified Options.Applicative          as OP+import           System.Exit                  (exitFailure)+import           System.IO                    (hGetEncoding, hPutStrLn, stderr,+                                               stdout) -- * CLI interface configuration -- -- $cliInterface@@ -120,19 +121,19 @@  optParseAllowOutside :: OP.Parser (Bool) optParseAllowOutside = OP.switch (-    OP.long "allowOutside" <> +    OP.long "allowOutside" <>     OP.help "Allow calibrations to run outside the range of the calibration curve"     )  optParseDontInterpolateCalCurve :: OP.Parser (Bool) optParseDontInterpolateCalCurve = OP.switch (-    OP.long "noInterpolation" <> +    OP.long "noInterpolation" <>     OP.help "Don't interpolate the calibration curve"     )  optParseQuiet :: OP.Parser (Bool) optParseQuiet = OP.switch (-    OP.long "quiet" <> +    OP.long "quiet" <>     OP.short 'q' <>     OP.help "Suppress the printing of calibration results to the command line"     )
src/Currycarbon.hs view
@@ -1,10 +1,10 @@--- | This module implements an algorithm for the calibration of +-- | This module implements an algorithm for the calibration of -- [radiocarbon dates](https://en.wikipedia.org/wiki/Radiocarbon_dating). -- This is a standard procedure in Archaeology and other fields working -- with radiocarbon dating.  module Currycarbon (-    +     -- * Calibration     -- $calibration     calibrateDates,@@ -48,18 +48,18 @@     normalizeCalPDF     ) where -import Currycarbon.Calibration.Calibration-import Currycarbon.Parsers-import Currycarbon.SumCalibration-import Currycarbon.Types-import Currycarbon.CalCurves.Intcal20-import Currycarbon.Calibration.Utils (normalizeCalPDF)+import           Currycarbon.CalCurves.Intcal20+import           Currycarbon.Calibration.Calibration+import           Currycarbon.Calibration.Utils       (normalizeCalPDF)+import           Currycarbon.Parsers+import           Currycarbon.SumCalibration+import           Currycarbon.Types  {- $calibration -The main function in this module 'calibrateDates' calibrates -radiocarbon dates, given the uncalibrated input dates, a calibration -curve and some configuration options. +The main function in this module 'calibrateDates' calibrates+radiocarbon dates, given the uncalibrated input dates, a calibration+curve and some configuration options.  * For the input dates there is a dedicated data type 'UncalC14'. These can be read from a .csv file with 'readUncalC14FromFile'.@@ -111,7 +111,7 @@  These can also be written to a file with 'writeCalC14s'. -'renderCalDatesPretty' finally combines 'UncalC14', 'CalPDF' and +'renderCalDatesPretty' finally combines 'UncalC14', 'CalPDF' and 'CalC14' to produce nice command line output summarising the calibration result for a given sample. -}
src/Currycarbon/CLI/RunCalibrate.hs view
@@ -10,24 +10,25 @@ import           Currycarbon.Types import           Currycarbon.Utils -import           Control.Monad      (when, unless)-import           Data.Maybe         (fromJust, isJust, fromMaybe)-import           System.IO          (hPutStrLn, stderr, stdout)+import           Control.Monad                       (unless, when)+import           Data.Maybe                          (fromJust, fromMaybe,+                                                      isJust)+import           System.IO                           (hPutStrLn, stderr, stdout)  -- | A data type to represent the options to the CLI module function runCalibrate data CalibrateOptions = CalibrateOptions {-        _calibrateExprs :: [CalExpr] -- ^ String listing the uncalibrated dates that should be calibrated-      , _calibrateExprFiles :: [FilePath] -- ^ List of files with uncalibrated dates to be calibrated-      , _calibrateCalCurveFile :: Maybe FilePath -- ^ Path to a .14c file-      , _calibrateCalibrationMethod :: CalibrationMethod -- ^ Calibration algorithm that should be used-      , _calibrateAllowOutside :: Bool -- ^ Allow calibration to run outside of the range of the calibration curve +        _calibrateExprs                   :: [CalExpr] -- ^ String listing the uncalibrated dates that should be calibrated+      , _calibrateExprFiles               :: [FilePath] -- ^ List of files with uncalibrated dates to be calibrated+      , _calibrateCalCurveFile            :: Maybe FilePath -- ^ Path to a .14c file+      , _calibrateCalibrationMethod       :: CalibrationMethod -- ^ Calibration algorithm that should be used+      , _calibrateAllowOutside            :: Bool -- ^ Allow calibration to run outside of the range of the calibration curve       , _calibrateDontInterpolateCalCurve :: Bool -- ^ Don't interpolate the calibration curve-      , _calibrateQuiet :: Bool -- ^ Suppress the printing of calibration results to the command line-      , _calibrateStdOutEncoding :: String -- ^ Encoding of the stdout stream (show TextEncoding)-      , _calibrateDensityFile :: Maybe FilePath -- ^ Path to an output file (see CLI documentation)-      , _calibrateHDRFile :: Maybe FilePath -- ^ Path to an output file-      , _calibrateCalCurveSegmentFile :: Maybe FilePath -- ^ Path to an output file -      , _calibrateCalCurveMatrixFile :: Maybe FilePath -- ^ Path to an output file +      , _calibrateQuiet                   :: Bool -- ^ Suppress the printing of calibration results to the command line+      , _calibrateStdOutEncoding          :: String -- ^ Encoding of the stdout stream (show TextEncoding)+      , _calibrateDensityFile             :: Maybe FilePath -- ^ Path to an output file (see CLI documentation)+      , _calibrateHDRFile                 :: Maybe FilePath -- ^ Path to an output file+      , _calibrateCalCurveSegmentFile     :: Maybe FilePath -- ^ Path to an output file+      , _calibrateCalCurveMatrixFile      :: Maybe FilePath -- ^ Path to an output file     }  -- | Interface function to trigger calibration from the command line@@ -99,7 +100,7 @@         printE :: CurrycarbonException -> IO ()         printE e = hPutStrLn stderr $ renderCurrycarbonException e --- | Helper function to replace empty input names with a sequence of numbers, +-- | Helper function to replace empty input names with a sequence of numbers, -- to get each input date an unique identifier replaceEmptyNames :: [CalExpr] -> [CalExpr] replaceEmptyNames = zipWith (replaceName . show) ([1..] :: [Integer])@@ -109,7 +110,7 @@             if name == "unknownSampleName"             then UnCalDate $ UncalC14 i x y             else UnCalDate $ UncalC14 name x y-        replaceName i (CalDate (CalPDF name x y)) = +        replaceName i (CalDate (CalPDF name x y)) =             if name == "unknownSampleName"             then CalDate $ CalPDF i x y             else CalDate $ CalPDF name x y
src/Currycarbon/CalCurves/Intcal20.hs view
@@ -1,7 +1,7 @@ module Currycarbon.CalCurves.Intcal20 where -import Currycarbon.Parsers ( readCalCurve )-import Currycarbon.Types ( CalCurveBP )+import           Currycarbon.Parsers (readCalCurve)+import           Currycarbon.Types   (CalCurveBP)  -- | The intcal20 calibration curve -- (Reimer et al. 2020, doi: [10.1017/RDC.2020.41](https://doi.org/10.1017/RDC.2020.41))
src/Currycarbon/Calibration/Bchron.hs view
@@ -2,19 +2,19 @@  module Currycarbon.Calibration.Bchron (calibrateDateBchron) where -import Currycarbon.Calibration.Utils-import Currycarbon.Parsers-import Currycarbon.Types-import Currycarbon.Utils+import           Currycarbon.Calibration.Utils+import           Currycarbon.Parsers+import           Currycarbon.Types+import           Currycarbon.Utils -import qualified Data.Vector.Unboxed as VU+import qualified Data.Vector.Unboxed           as VU  -- | Intercept calibration as implemented in the Bchron R package (see 'Bchron') calibrateDateBchron :: CalibrationDistribution -> Bool -> Bool -> CalCurveBP -> UncalC14 -> Either CurrycarbonException CalPDF calibrateDateBchron distr allowOutside interpolate calCurve uncalC14@(UncalC14 name age ageSd) =     if not allowOutside && isOutsideRangeOfCalCurve calCurve uncalC14     then Left $ CurrycarbonCalibrationRangeException $ renderUncalC14 uncalC14-    else +    else         let rawCalCurveSegment = getRelevantCalCurveSegment uncalC14 calCurve             CalCurveBCAD cals mus tau1s = prepareCalCurveSegment interpolate rawCalCurveSegment             ageFloat = -(fromIntegral age)+1950@@ -23,8 +23,8 @@             musFloat = VU.map fromIntegral mus             tau1sFloat = VU.map fromIntegral tau1s             dens = case distr of-                NormalDist -> +                NormalDist ->                     VU.zipWith (\mu tau1 -> dnorm 0 1 ((ageFloat - mu) / sqrt (ageSd2Float + tau1 * tau1))) musFloat tau1sFloat-                StudentTDist degreesOfFreedom -> +                StudentTDist degreesOfFreedom ->                     VU.zipWith (\mu tau1 -> dt degreesOfFreedom ((ageFloat - mu) / sqrt (ageSd2Float + tau1 * tau1))) musFloat tau1sFloat         in Right $ trimLowDensityEdgesCalPDF $ normalizeCalPDF $ CalPDF name cals dens
src/Currycarbon/Calibration/Calibration.hs view
@@ -18,44 +18,45 @@       , defaultCalConf     ) where -import Currycarbon.Calibration.Utils-import Currycarbon.Calibration.Bchron-import Currycarbon.Calibration.MatrixMult-import Currycarbon.Types-import Currycarbon.Utils+import           Currycarbon.Calibration.Bchron+import           Currycarbon.Calibration.MatrixMult+import           Currycarbon.Calibration.Utils+import           Currycarbon.Types+import           Currycarbon.Utils -import Data.List (sort, sortBy, groupBy, elemIndex)-import Data.Maybe (fromJust)-import qualified Data.Vector.Unboxed as VU+import           Data.List                          (elemIndex, groupBy, sort,+                                                     sortBy)+import           Data.Maybe                         (fromJust)+import qualified Data.Vector.Unboxed                as VU  -- | A data type to cover the configuration options of the calibrateDates function data CalibrateDatesConf = CalibrateDatesConf {-      -- | The calibration algorithm that should be used  -        _calConfMethod :: CalibrationMethod+      -- | The calibration algorithm that should be used+        _calConfMethod              :: CalibrationMethod       -- | Allow calibration to run outside of the range of the calibration curve-      , _calConfAllowOutside :: Bool+      , _calConfAllowOutside        :: Bool       -- | Interpolate the calibration curve before calibration.       -- This is a simple linear interpolation only to increase the output       -- resolution for earlier time periods, where the typical calibration       -- curves are less dense by default. With the interpolation, the output-      -- will be a per-year density. The mechanism is inspired by the +      -- will be a per-year density. The mechanism is inspired by the       -- [implementation in the Bchron R package](https://github.com/andrewcparnell/Bchron/blob/b202d18550319b488e676a8b542aba55853f6fa3/R/BchronCalibrate.R#L118-L119)-      , _calConfInterpolateCalCurve :: Bool +      , _calConfInterpolateCalCurve :: Bool     } deriving (Show, Eq) --- | A default configuration that should yield almost identical calibration results +-- | A default configuration that should yield almost identical calibration results -- to the [Bchron R package](https://github.com/andrewcparnell/Bchron) defaultCalConf :: CalibrateDatesConf defaultCalConf = CalibrateDatesConf {         _calConfMethod = Bchron { distribution = StudentTDist 100 }-      , _calConfAllowOutside = False +      , _calConfAllowOutside = False       , _calConfInterpolateCalCurve = True     }  -- | Calibrates a list of dates with the provided calibration curve calibrateDates :: CalibrateDatesConf -- ^ Configuration options to consider                   -> CalCurveBP -- ^ A calibration curve-                  -> [UncalC14] -- ^ A list of uncalibrated radiocarbon dates  +                  -> [UncalC14] -- ^ A list of uncalibrated radiocarbon dates                   -> [Either CurrycarbonException CalPDF] -- ^ The function returns a list for each input date, with                                                           -- either an exception if the calibration failed for some                                                           -- reason, or a 'CalPDF'@@ -69,7 +70,7 @@ calibrateDate :: CalibrateDatesConf -- ^ Configuration options to consider                  -> CalCurveBP -- ^ A calibration curve                  -> UncalC14 -- ^ An uncalibrated radiocarbon date-                 -> Either CurrycarbonException CalPDF -- ^ The function returns either an exception if the +                 -> Either CurrycarbonException CalPDF -- ^ The function returns either an exception if the                                                         -- calibration failed for some reason, or a 'CalPDF' calibrateDate (CalibrateDatesConf MatrixMultiplication allowOutside interpolate) calCurve uncalDate =     calibrateDateMatrixMult allowOutside interpolate calCurve uncalDate@@ -110,17 +111,17 @@         hdrs68 = densities2HDR68 contextualizedDensities         hdrs95 = densities2HDR95 contextualizedDensities         -- helper functions-        indexVU _ Nothing = Nothing+        indexVU _ Nothing  = Nothing         indexVU x (Just i) = x VU.!? i         cumsumDens :: [(YearBCAD, Float)] -> [Float]         cumsumDens x = scanl1 (+) $ map snd x         densities2HDR68 :: [(Int, Float, Bool, Bool)] -> [HDR]-        densities2HDR68 cDensities = +        densities2HDR68 cDensities =             let highDensityGroups = groupBy (\(_,_,in681,_) (_,_,in682,_) -> in681 == in682) cDensities                 filteredDensityGroups = filter (all getIn68) highDensityGroups             in map (\xs -> let yearRange = map getYear xs in HDR (head yearRange) (last yearRange)) filteredDensityGroups         densities2HDR95 :: [(Int, Float, Bool, Bool)] -> [HDR]-        densities2HDR95 cDensities = +        densities2HDR95 cDensities =             let highDensityGroups = groupBy (\(_,_,_,in951) (_,_,_,in952) -> in951 == in952) cDensities                 filteredDensityGroups = filter (all getIn95) highDensityGroups             in map (\xs -> let yearRange = map getYear xs in HDR (head yearRange) (last yearRange)) filteredDensityGroups
src/Currycarbon/Calibration/MatrixMult.hs view
@@ -6,14 +6,14 @@       , uncalToPDF     ) where -import Currycarbon.Calibration.Utils-import Currycarbon.Parsers-import Currycarbon.Types-import Currycarbon.Utils+import           Currycarbon.Calibration.Utils+import           Currycarbon.Parsers+import           Currycarbon.Types+import           Currycarbon.Utils -import qualified Data.Vector.Unboxed as VU-import qualified Data.Vector as V-import Data.Vector.Generic (convert)+import qualified Data.Vector                   as V+import           Data.Vector.Generic           (convert)+import qualified Data.Vector.Unboxed           as VU  -- | Intercept calibration implemented with matrix multiplication (see 'MatrixMultiplication') calibrateDateMatrixMult :: Bool -> Bool -> CalCurveBP -> UncalC14 -> Either CurrycarbonException CalPDF@@ -40,15 +40,15 @@     where         buildMatrix :: VU.Vector Float -> VU.Vector Float -> VU.Vector Float -> V.Vector (VU.Vector Float)         buildMatrix curveuncal_ sigmas_ uncal_ =-          V.map (\x -> VU.map (fillCell x) uncal_) $ +          V.map (\x -> VU.map (fillCell x) uncal_) $             V.zip (convert curveuncal_) (convert sigmas_)         fillCell :: (Float, Float) -> Float -> Float-        fillCell (mean, sigma) matrixPosBP = +        fillCell (mean, sigma) matrixPosBP =             if abs (mean - matrixPosBP) < 6*sigma             then dnorm mean sigma matrixPosBP             else 0 --- | Transform an uncalibrated date to an uncalibrated +-- | Transform an uncalibrated date to an uncalibrated -- probability density table uncalToPDF :: UncalC14 -> UncalPDF uncalToPDF (UncalC14 name mean std) =
src/Currycarbon/Calibration/Utils.hs view
@@ -2,22 +2,22 @@  module Currycarbon.Calibration.Utils where -import Currycarbon.Types+import           Currycarbon.Types -import qualified Data.Vector.Unboxed as VU-import Data.Maybe (fromMaybe)-import Numeric.SpecFunctions (logBeta)+import           Data.Maybe            (fromMaybe)+import qualified Data.Vector.Unboxed   as VU+import           Numeric.SpecFunctions (logBeta)  -- | Rescale a CalPDF so that the sum of the densities is approx. 1.0 normalizeCalPDF :: CalPDF -> CalPDF-normalizeCalPDF (CalPDF name cals dens) = +normalizeCalPDF (CalPDF name cals dens) =     case VU.sum dens of       0.0 -> CalPDF name cals dens -- product calibration can yield empty calPDFs       s   -> CalPDF name cals $ VU.map (/s) dens  -- | get the density of a normal distribution at a point x-dnorm :: Float -> Float -> Float -> Float -dnorm mu sigma x = +dnorm :: Float -> Float -> Float -> Float+dnorm mu sigma x =     let a = recip (sqrt (2 * pi * sigma2))         b = exp (-c2 / (2 * sigma2))         c = x - mu@@ -39,7 +39,7 @@     -- realToFrac $ density (studentT (realToFrac dof)) (realToFrac x) -- dof: number of degrees of freedom  isOutsideRangeOfCalCurve :: CalCurveBP -> UncalC14 -> Bool-isOutsideRangeOfCalCurve (CalCurveBP _ uncals _) (UncalC14 _ age _) = +isOutsideRangeOfCalCurve (CalCurveBP _ uncals _) (UncalC14 _ age _) =     age < VU.minimum uncals || age > VU.maximum uncals  -- | Take an uncalibrated date and a raw calibration curve and return@@ -53,7 +53,7 @@         toIndex = stopIndex - startIndex     in CalCurveBP (VU.slice startIndex toIndex cals) (VU.slice startIndex toIndex uncals) (VU.slice startIndex toIndex sigmas) --- | Modify a calibration curve (segment) with multiple optional steps, +-- | Modify a calibration curve (segment) with multiple optional steps, -- including interpolation and transforming dates to BC/AD format prepareCalCurveSegment :: Bool -> CalCurveBP -> CalCurveBCAD prepareCalCurveSegment interpolate calCurve =@@ -76,9 +76,9 @@         getTimeWindows xs = VU.zipWith (,) (VU.init xs) (VU.tail xs)         fillTimeWindows :: ((YearBP,YearBP,YearRange),(YearBP,YearBP,YearRange)) -> VU.Vector (YearBP,YearBP,YearRange)         fillTimeWindows ((calbp1,bp1,sigma1),(calbp2,bp2,sigma2)) =-            if calbp1 == calbp2 || calbp1+1 == calbp2 || calbp1-1 == calbp2 +            if calbp1 == calbp2 || calbp1+1 == calbp2 || calbp1-1 == calbp2             then VU.singleton (calbp1,bp1,sigma1)-            else +            else                 let newCals = VU.fromList [calbp1,calbp1-1..calbp2+1] -- range definition like this to trigger counting down                     newBPs = VU.map (snd . getInBetweenPointsInt (calbp1,bp1) (calbp2,bp2)) newCals                     newSigmas = VU.map (snd . getInBetweenPointsInt (calbp1,sigma1) (calbp2,sigma2)) newCals
src/Currycarbon/Parsers.hs view
@@ -2,21 +2,21 @@  module Currycarbon.Parsers where -import Currycarbon.Types-import Currycarbon.Utils+import           Currycarbon.Types+import           Currycarbon.Utils -import           Control.Exception              (throwIO)-import           Data.List                      (intercalate, transpose)-import qualified Text.Parsec                    as P-import qualified Text.Parsec.String             as P-import qualified Data.Vector.Unboxed            as VU-import qualified Data.Vector                    as V+import           Control.Exception   (throwIO)+import           Data.List           (intercalate, transpose)+import qualified Data.Vector         as V+import qualified Data.Vector.Unboxed as VU+import qualified Text.Parsec         as P+import qualified Text.Parsec.String  as P  -- * Parsing, rendering and writing functions -- -- $importExport ----- This module contains a number of functions to manage data input and +-- This module contains a number of functions to manage data input and -- output plumbing for different datatypes  -- CalibrationMethod@@ -46,26 +46,26 @@  -- | Combine 'CalExpr', 'CalPDF' and 'CalC14' to render pretty command line output -- like this:--- +-- -- @ -- DATE: (5000±30BP + 5100±100BP) -- Calibrated: 4150BC \>\> 3941BC \> 3814BC \< 3660BC \<\< 3651BC -- 1-sigma: 3941-3864BC, 3810-3707BC, 3667-3660BC -- 2-sigma: 4150-4148BC, 4048-3651BC---                                           ▁                ---                                           ▒▁ ▁▁            ---                                   ▁▁▁    ▁▒▒▁▒▒            ---                                 ▁▁▒▒▒    ▒▒▒▒▒▒            ---                               ▁▁▒▒▒▒▒▁▁▁▁▒▒▒▒▒▒▁ ▁         ---                           ▁▁▁▁▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▁▒▁        +--                                           ▁+--                                           ▒▁ ▁▁+--                                   ▁▁▁    ▁▒▒▁▒▒+--                                 ▁▁▒▒▒    ▒▒▒▒▒▒+--                               ▁▁▒▒▒▒▒▁▁▁▁▒▒▒▒▒▒▁ ▁+--                           ▁▁▁▁▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▁▒▁ --         ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▁▁▁▁▁▁▁▁ --  -4330 ┄──┬─────┬─────┬─────┬──────┬─────┬─────┬─────┬─────┄ -3530---                    \>            \>       \^         \<        ---                                 ──────  ──────── ──        +--                    \>            \>       \^         \<+--                                 ──────  ──────── ── --                    ─     ────────────────────────── -- @ ---renderCalDatePretty :: +renderCalDatePretty ::        Bool -- ^ Should the CLI plot be restricted to (boring) ASCII symbols?     -> (CalExpr, CalPDF, CalC14)     -> String@@ -119,14 +119,14 @@     s <- readFile uncalFile     case P.runParser parseCalExprSepByNewline () "" s of         Left err -> throwIO $ CurrycarbonCLIParsingException $ show err-        Right x -> return x+        Right x  -> return x     where         parseCalExprSepByNewline :: P.Parser [CalExpr]         parseCalExprSepByNewline = P.endBy expr (P.newline <* P.spaces) <* P.eof  -- CalC14 -- | Write 'CalC14's to the file system. The output file is a long .csv file with the following structure:--- +-- -- @ -- sample,hdrSigma,hdrStartBCAD,hdrStopBCAD -- Sample1,1,-3797,-3709@@ -142,15 +142,15 @@ -- Sample2,2,-1323,-1112 -- Sample2,2,-1393,-1334 -- @--- +-- writeCalC14s :: FilePath -> [CalC14] -> IO ()-writeCalC14s path calC14s = writeFile path $ -    "sample,hdrSigma,hdrStartBCAD,hdrStopBCAD\n" +writeCalC14s path calC14s = writeFile path $+    "sample,hdrSigma,hdrStartBCAD,hdrStopBCAD\n"     ++ intercalate "\n" (map renderCalC14ForFile calC14s)  writeCalC14 :: FilePath -> CalC14 -> IO ()-writeCalC14 path calC14 = writeFile path $ -    "sample,hdrSigma,hdrStartBCAD,hdrStopBCAD\n" +writeCalC14 path calC14 = writeFile path $+    "sample,hdrSigma,hdrStartBCAD,hdrStopBCAD\n"     ++ renderCalC14ForFile calC14  appendCalC14 :: FilePath -> CalC14 -> IO ()@@ -159,7 +159,7 @@  renderCalC14ForFile :: CalC14 -> String renderCalC14ForFile (CalC14 name _ hdrs68 hdrs95) =-    intercalate "\n" $ +    intercalate "\n" $         map renderRow $         zip3 (repeat name) (repeat "1") (renderHDRsForFile hdrs68) ++         zip3 (repeat name) (repeat "2") (renderHDRsForFile hdrs95)@@ -168,8 +168,8 @@         renderRow (a, b, (c, d)) = intercalate "," [a,b,c,d]  renderCalC14s :: [CalC14] -> String-renderCalC14s xs = -    "Calibrated high density ranges (HDR):\n" +renderCalC14s xs =+    "Calibrated high density ranges (HDR):\n"     ++ intercalate "\n" (map renderCalC14 xs)  renderCalC14 :: CalC14 -> String@@ -212,7 +212,7 @@  -- CalCurveMatrix writeCalCurveMatrix :: FilePath -> CalCurveMatrix -> IO ()-writeCalCurveMatrix path calCurveMatrix = +writeCalCurveMatrix path calCurveMatrix =     writeFile path $ renderCalCurveMatrix calCurveMatrix  renderCalCurveMatrix :: CalCurveMatrix -> String@@ -220,12 +220,12 @@     let header = "," ++ intercalate "," (map show $ VU.toList cals) ++ "\n"         body = zipWith makeRow (VU.toList uncals) (transpose $ V.toList (V.map VU.toList curveDensities))     in header ++ intercalate "\n" body-    where +    where       makeRow uncal dens = show uncal ++ "," ++ intercalate "," (map show dens)  -- CalPDF -- | Write 'CalPDF's to the file system. The output file is a long .csv file with the following structure:--- +-- -- @ -- sample,calBCAD,density -- ...@@ -240,7 +240,7 @@ -- Sample2,-3675,2.095691e-3 -- ... -- @--- +-- writeCalPDFs :: FilePath -> [CalPDF] -> IO () writeCalPDFs path calPDFs =     writeFile path $@@ -266,7 +266,7 @@     where       makeRow (x,y) = show name ++ "," ++ show x ++ "," ++ show y ++ "\n" -data PlotSymbol = HistFill | HistTop | AxisEnd | AxisLine | AxisTick | HDRLine +data PlotSymbol = HistFill | HistTop | AxisEnd | AxisLine | AxisTick | HDRLine  renderCLIPlotCalPDF :: Bool -> Int -> Int -> CalPDF -> CalC14 -> String renderCLIPlotCalPDF ascii rows cols (CalPDF _ cals dens) c14 =@@ -364,31 +364,31 @@ renderUncalC14 (UncalC14 name bp sigma) = name ++ ":" ++ show bp ++ "±" ++ show sigma ++ "BP"  -- | Read uncalibrated radiocarbon dates from a file. The file should feature one radiocarbon date--- per line in the form "\<sample name\>,\<mean age BP\>,\<one sigma standard deviation\>", where +-- per line in the form "\<sample name\>,\<mean age BP\>,\<one sigma standard deviation\>", where -- \<sample name\> is optional. A valid file could look like this:--- +-- -- @ -- Sample1,5000,30 -- 6000,50 -- Sample3,4000,25 -- @--- +-- readUncalC14FromFile :: FilePath -> IO [UncalC14] readUncalC14FromFile uncalFile = do     s <- readFile uncalFile     case P.runParser uncalC14SepByNewline () "" s of         Left err -> throwIO $ CurrycarbonCLIParsingException $ show err-        Right x -> return x+        Right x  -> return x     where         uncalC14SepByNewline :: P.Parser [UncalC14]         uncalC14SepByNewline = P.endBy parseUncalC14 (P.newline <* P.spaces) <* P.eof  readUncalC14 :: String -> Either String [UncalC14]-readUncalC14 s = +readUncalC14 s =     case P.runParser uncalC14SepBySemicolon () "" s of         Left err -> Left $ renderCurrycarbonException $ CurrycarbonCLIParsingException $ show err         Right x -> Right x-    where +    where         uncalC14SepBySemicolon :: P.Parser [UncalC14]         uncalC14SepBySemicolon = P.sepBy parseUncalC14 (P.char ';' <* P.spaces) <* P.eof @@ -411,7 +411,7 @@  -- CalCurve writeCalCurve :: FilePath -> CalCurveBCAD -> IO ()-writeCalCurve path calCurve = +writeCalCurve path calCurve =     writeFile path $ renderCalCurve calCurve  renderCalCurve :: CalCurveBCAD -> String@@ -422,7 +422,7 @@     where       makeRow (x,y,z) = show x ++ "," ++ show y ++ "," ++ show z --- | Read a calibration curve file. The file must adhere to the current version of the +-- | Read a calibration curve file. The file must adhere to the current version of the -- .c14 file format (e.g. [here](http://intcal.org/curves/intcal20.14c)). Look -- [here](http://intcal.org/blurb.html) for other calibration curves readCalCurveFromFile :: FilePath -> IO CalCurveBP@@ -434,7 +434,7 @@ readCalCurve calCurveString = do     case P.runParser parseCalCurve () "" calCurveString of         Left p  -> error $ "This should never happen." ++ show p-        Right x -> CalCurveBP +        Right x -> CalCurveBP             (VU.fromList $ map (\(a,_,_) -> a) x)             (VU.fromList $ map (\(_,b,_) -> b) x)             (VU.fromList $ map (\(_,_,c) -> c) x)@@ -444,7 +444,7 @@     P.skipMany comments     P.sepEndBy parseCalCurveLine (P.manyTill P.anyToken (P.try P.newline)) -parseCalCurveLine :: P.Parser (YearBP, YearBP, YearRange) +parseCalCurveLine :: P.Parser (YearBP, YearBP, YearRange) parseCalCurveLine = do   calBP <- read <$> P.many1 P.digit   _ <- P.oneOf ","@@ -454,7 +454,7 @@   return (calBP, bp, sigma)  comments :: P.Parser String-comments = do +comments = do     _ <- P.string "#"     _ <- P.manyTill P.anyChar P.newline     return ""
src/Currycarbon/SumCalibration.hs view
@@ -2,17 +2,17 @@  module Currycarbon.SumCalibration where -import Currycarbon.Types-import Currycarbon.Utils-import Currycarbon.Calibration.Calibration-import Currycarbon.Calibration.Utils+import           Currycarbon.Calibration.Calibration+import           Currycarbon.Calibration.Utils+import           Currycarbon.Types+import           Currycarbon.Utils -import           Data.Foldable                  (foldl')-import qualified Data.Vector.Unboxed            as VU-import Data.List (sortBy, groupBy)-import Data.Ord (comparing)+import           Data.Foldable                       (foldl')+import           Data.List                           (groupBy, sortBy)+import           Data.Ord                            (comparing)+import qualified Data.Vector.Unboxed                 as VU --- | Evaluate a dating expression by calibrating the individual dates and forming the respective +-- | Evaluate a dating expression by calibrating the individual dates and forming the respective --   sums and products of post-calibration density distributions evalCalExpr :: CalibrateDatesConf -> CalCurveBP -> CalExpr -> Either CurrycarbonException CalPDF evalCalExpr conf curve calExpr = mapEither id normalizeCalPDF $ evalE calExpr@@ -21,17 +21,17 @@         evalE (UnCalDate a)    = calibrateDate conf curve a         evalE (CalDate a)      = Right a         evalE (SumCal a b)     = eitherCombinePDFs (+) 0 (evalE a) (evalE b)-        evalE (ProductCal a b) = mapEither id normalizeCalPDF $ eitherCombinePDFs (*) 1 +        evalE (ProductCal a b) = mapEither id normalizeCalPDF $ eitherCombinePDFs (*) 1             (mapEither id normalizeCalPDF $ evalE a) (mapEither id normalizeCalPDF $ evalE b) -- product needs extra normalization         -- https://hackage.haskell.org/package/either-5.0.2/docs/Data-Either-Combinators.html         mapEither :: (a -> c) -> (b -> d) -> Either a b -> Either c d         mapEither f _ (Left x)  = Left (f x)         mapEither _ f (Right x) = Right (f x) -eitherCombinePDFs :: -    (Float -> Float -> Float) -> Float -> -    Either CurrycarbonException CalPDF -> -    Either CurrycarbonException CalPDF -> +eitherCombinePDFs ::+    (Float -> Float -> Float) -> Float ->+    Either CurrycarbonException CalPDF ->+    Either CurrycarbonException CalPDF ->     Either CurrycarbonException CalPDF eitherCombinePDFs _ _ (Left e) _ = Left e eitherCombinePDFs _ _ _ (Left e) = Left e@@ -60,7 +60,7 @@             pdfGrouped = groupBy (\a b -> fst a == fst b) pdfSorted             pdfRes = map foldYearGroup pdfGrouped         in CalPDF (name1 ++ ":" ++ name2) (VU.fromList $ map fst pdfRes) (VU.fromList $ map snd pdfRes)-        where +        where             getMiss :: YearBCAD -> YearBCAD -> YearBCAD -> YearBCAD -> [YearBCAD]             getMiss a1 a2 b1 b2                 | a1 <  b1 && a2 >  b2 = [a1..b1] ++ [b2..a2]
src/Currycarbon/Types.hs view
@@ -2,8 +2,8 @@  module Currycarbon.Types where +import qualified Data.Vector         as V import qualified Data.Vector.Unboxed as VU-import qualified Data.Vector as V  -- * Data types --@@ -11,18 +11,18 @@ -- -- This module defines the relevant data types for handling radiocarbon dates --- | Different calibration algorithms implemented in currycarbon. Currently two distinct +-- | Different calibration algorithms implemented in currycarbon. Currently two distinct -- implementations are available, although both of them are similar [Intercept calibration](https://en.wikipedia.org/wiki/Radiocarbon_calibration#Intercept) -- algorithms. Maybe more algorithms will be added in the future data CalibrationMethod =   -- | A matrix multiplication method generally following [this blog post by Martin Hinz](https://www.martinhinz.info/jekyll/update/blog/2016/06/03/simple_calibration.html).-  -- This method is slower and the underlying code more verbose than 'Bchron', but it +  -- This method is slower and the underlying code more verbose than 'Bchron', but it   -- has some advantages regarding didactics and the inspection of intermediate data   -- products for debugging.   -- Using this method is thus generally not advisable, except for specific applications,   -- where a more technical insight into C14 calibration is needed     MatrixMultiplication-  -- | A fast and reliable calibration algorithm very similar to the implementation in the +  -- | A fast and reliable calibration algorithm very similar to the implementation in the   -- [R package Bchron by Andrew Parnell](https://github.com/andrewcparnell/Bchron/blob/master/R/BchronCalibrate.R).   -- This algorithm can be run with a simple normal distribution ('NormalDist') or   -- Student's t-distribution ('StudentTDist'), which is recommended@@ -30,12 +30,12 @@   deriving (Show, Eq)  -- | Statistical distributions to be used with the 'CalibrationMethod' 'Bchron'-data CalibrationDistribution = +data CalibrationDistribution =   -- | Normal distribution     NormalDist   -- | Student's t-distribution.   | StudentTDist {-      ndf :: Double -- ^ number of degrees of freedom +      ndf :: Double -- ^ number of degrees of freedom     }   deriving (Show, Eq) @@ -49,9 +49,9 @@ type YearRange = Word  -- | A data type to represent an uncalibrated radiocarbon date-data UncalC14 = UncalC14 { -    -- | Sample identifier, e.g. a lab number  -      _uncalC14Id :: String+data UncalC14 = UncalC14 {+    -- | Sample identifier, e.g. a lab number+      _uncalC14Id    :: String     -- | C14 age in years BP     , _uncalC14UnCal :: YearBP     -- | C14 standard deviation (one sigma in years)@@ -62,17 +62,17 @@ -- Although technically not correct, we still call this a probability density function (PDF) data UncalPDF = UncalPDF {     -- | Sample identifier, e.g. a lab number-      _uncalPDFid :: String+      _uncalPDFid     :: String     -- | Years BP     , _uncalPDFUnCals :: VU.Vector YearBP     -- | Probability densities-    , _uncalPDFDens :: VU.Vector Float+    , _uncalPDFDens   :: VU.Vector Float     } deriving Show  -- | A data type to represent a calibration curve with 'YearBP' data CalCurveBP = CalCurveBP {     -- | Years calBP-      _calCurveBPCals :: VU.Vector YearBP+      _calCurveBPCals   :: VU.Vector YearBP     -- | Years BP     , _calCurveBPUnCals :: VU.Vector YearBP     -- | Standard deviation (one sigma in years)@@ -82,7 +82,7 @@ -- | A second data type to represent a calibration curve, here now with 'YearBCAD' data CalCurveBCAD = CalCurveBCAD {     -- | Years calBCAD-      _calCurveBCADCals :: VU.Vector YearBCAD+      _calCurveBCADCals   :: VU.Vector YearBCAD     -- | Years BCAD     , _calCurveBCADUnCals :: VU.Vector YearBCAD     -- | Standard deviation (one sigma in years)@@ -94,16 +94,16 @@     -- | Row names of the calibration curve matrix: Years BCAD       _calCurveMatrixUnCals :: VU.Vector YearBCAD     -- | Column names of the calibration curve matrix: Years calBCAD-    , _calCurveMatrixCals :: VU.Vector YearBCAD+    , _calCurveMatrixCals   :: VU.Vector YearBCAD     -- | Matrix (as a list of columns) with the probability densities-    , _calCurveMatrixDens :: V.Vector (VU.Vector Float)+    , _calCurveMatrixDens   :: V.Vector (VU.Vector Float)     } deriving Show  -- | A data type to represent a year-wise probability density for calibrated dates. -- Although technically not correct, we still call this a probability density function (PDF) data CalPDF = CalPDF {     -- | Sample identifier, e.g. a lab number-      _calPDFid :: String+      _calPDFid   :: String     -- | Years calBCAD     , _calPDFCals :: VU.Vector YearBCAD     -- | Probability densities for each year in '_calPDFCals'@@ -122,16 +122,16 @@ -- | A data type to represent a human readable summary of a calibrated radiocarbon date data CalC14 = CalC14 {     -- | Identifier, e.g. a lab number-      _calC14id :: String+      _calC14id           :: String     -- | Summary of the range of the calibrated date     , _calC14RangeSummary :: CalRangeSummary     -- | One-sigma high density regions-    , _calC14HDROneSigma :: [HDR]+    , _calC14HDROneSigma  :: [HDR]     -- | Two-sigma high density regions-    , _calC14HDRTwoSigma :: [HDR]+    , _calC14HDRTwoSigma  :: [HDR]     } deriving Show --- | A data type to store a simple range summary of the calibrated date, including +-- | A data type to store a simple range summary of the calibrated date, including -- the median age data CalRangeSummary = CalRangeSummary {     -- | Start of the two-sigma age range@@ -147,12 +147,12 @@ } deriving Show  -- | A data type to represent a high density region of a probability distribution.--- A high density region is here defined as an age range, within which the respective --- cummulative probability (e.g. of an calibrated radiocarbon date density curve) +-- A high density region is here defined as an age range, within which the respective+-- cummulative probability (e.g. of an calibrated radiocarbon date density curve) -- is above a certain threshold data HDR = HDR {     -- | Start of the high density region in years calBCAD       _hdrstart :: YearBCAD     -- | End of the high density region in years calBCAD-    , _hdrstop :: YearBCAD+    , _hdrstop  :: YearBCAD     } deriving (Show, Eq)
src/Currycarbon/Utils.hs view
@@ -3,19 +3,19 @@     renderCurrycarbonException ) where -import           Control.Exception      (Exception)+import           Control.Exception (Exception)  -- | Different exceptions for currycarbon data CurrycarbonException =       CurrycarbonCLIParsingException String -- ^ An exception to describe an issue in the currycarbon CLI input parsing-    | CurrycarbonCalibrationRangeException String -- ^ An exection to describe the case that a +    | CurrycarbonCalibrationRangeException String -- ^ An exection to describe the case that a                                                   -- date is not in the range of the supplied calibration curve     deriving (Show)  instance Exception CurrycarbonException -renderCurrycarbonException :: CurrycarbonException -> String -renderCurrycarbonException (CurrycarbonCLIParsingException s) = +renderCurrycarbonException :: CurrycarbonException -> String+renderCurrycarbonException (CurrycarbonCLIParsingException s) =     "<!> Error: Input can not be parsed\n" ++ s renderCurrycarbonException (CurrycarbonCalibrationRangeException s) =     s ++ " <!> Error: Date outside of calibration range"