module Poseidon.CLI.Summarise where
import Poseidon.Janno (JannoDateBCADMedian (..),
JannoRow (..), JannoRows (..),
ListColumn (..))
import Poseidon.MathHelpers (meanAndSdInteger, meanAndSdRoundTo)
import Poseidon.Package (PackageReadOptions (..),
PoseidonPackage (..),
defaultPackageReadOptions,
readPoseidonPackageCollection)
import Poseidon.Utils (PoseidonIO, logInfo, uniquePO)
import Control.Monad.IO.Class (liftIO)
import Data.List (group, intercalate, sort, sortBy)
import Data.Maybe (mapMaybe)
import Poseidon.ColumnTypes (JannoCoverageOnTargets (..),
JannoEndogenous (JannoEndogenous),
JannoNrSNPs (..))
import Text.Layout.Table (asciiRoundS, column, def, expandUntil,
rowsG, tableString, titlesH)
data SummariseOptions = SummariseOptions
{ SummariseOptions -> [String]
_summariseBaseDirs :: [FilePath]
, SummariseOptions -> Bool
_summariseRawOutput :: Bool
}
pacReadOpts :: PackageReadOptions
pacReadOpts :: PackageReadOptions
pacReadOpts = PackageReadOptions
defaultPackageReadOptions {
_readOptIgnoreChecksums :: Bool
_readOptIgnoreChecksums = Bool
True
, _readOptIgnoreGeno :: Bool
_readOptIgnoreGeno = Bool
True
, _readOptGenoCheck :: Bool
_readOptGenoCheck = Bool
False
, _readOptOnlyLatest :: Bool
_readOptOnlyLatest = Bool
True
}
runSummarise :: SummariseOptions -> PoseidonIO ()
runSummarise :: SummariseOptions -> PoseidonIO ()
runSummarise (SummariseOptions [String]
baseDirs Bool
rawOutput) = do
[PoseidonPackage]
allPackages <- PackageReadOptions -> [String] -> PoseidonIO [PoseidonPackage]
readPoseidonPackageCollection PackageReadOptions
pacReadOpts [String]
baseDirs
let jannos :: [JannoRows]
jannos = (PoseidonPackage -> JannoRows) -> [PoseidonPackage] -> [JannoRows]
forall a b. (a -> b) -> [a] -> [b]
map PoseidonPackage -> JannoRows
posPacJanno [PoseidonPackage]
allPackages
String -> PoseidonIO ()
logInfo String
"Note that only the latest versions of packages are included in the summary"
IO () -> PoseidonIO ()
forall a. IO a -> ReaderT Env IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> PoseidonIO ()) -> IO () -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ JannoRows -> Bool -> IO ()
summariseJannoRows ([JannoRows] -> JannoRows
forall a. Monoid a => [a] -> a
mconcat [JannoRows]
jannos) Bool
rawOutput
summariseJannoRows :: JannoRows -> Bool -> IO ()
summariseJannoRows :: JannoRows -> Bool -> IO ()
summariseJannoRows (JannoRows [JannoRow]
rows) Bool
rawOutput = do
([String]
tableH, [[String]]
tableB) <- do
let tableH :: [String]
tableH = [String
"Summary", String
"Value"]
tableB :: [[String]]
tableB = [
[String
"Nr Samples"
, Int -> String
forall a. Show a => a -> String
show ([JannoRow] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [JannoRow]
rows)],
[String
"Samples"
, [String] -> String
paste ([String] -> String)
-> ([JannoRow] -> [String]) -> [JannoRow] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
forall a. Ord a => [a] -> [a]
sort ([String] -> [String])
-> ([JannoRow] -> [String]) -> [JannoRow] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoRow -> String) -> [JannoRow] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map JannoRow -> String
jPoseidonID ([JannoRow] -> String) -> [JannoRow] -> String
forall a b. (a -> b) -> a -> b
$ [JannoRow]
rows],
[String
"Nr Primary Groups"
, [GroupName] -> String
forall a. Ord a => [a] -> String
uniqueNumber ([GroupName] -> String)
-> ([JannoRow] -> [GroupName]) -> [JannoRow] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoRow -> GroupName) -> [JannoRow] -> [GroupName]
forall a b. (a -> b) -> [a] -> [b]
map ([GroupName] -> GroupName
forall a. HasCallStack => [a] -> a
head ([GroupName] -> GroupName)
-> (JannoRow -> [GroupName]) -> JannoRow -> GroupName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ListColumn GroupName -> [GroupName]
forall a. ListColumn a -> [a]
getListColumn (ListColumn GroupName -> [GroupName])
-> (JannoRow -> ListColumn GroupName) -> JannoRow -> [GroupName]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JannoRow -> ListColumn GroupName
jGroupName) ([JannoRow] -> String) -> [JannoRow] -> String
forall a b. (a -> b) -> a -> b
$ [JannoRow]
rows],
[String
"Primary Groups"
, String -> [(String, Int)] -> String
printFrequencyString String
", " ([(String, Int)] -> String)
-> ([JannoRow] -> [(String, Int)]) -> [JannoRow] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [(String, Int)]
forall a. Ord a => [a] -> [(a, Int)]
frequency ([String] -> [(String, Int)])
-> ([JannoRow] -> [String]) -> [JannoRow] -> [(String, Int)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoRow -> String) -> [JannoRow] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (GroupName -> String
forall a. Show a => a -> String
show (GroupName -> String)
-> (JannoRow -> GroupName) -> JannoRow -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [GroupName] -> GroupName
forall a. HasCallStack => [a] -> a
head ([GroupName] -> GroupName)
-> (JannoRow -> [GroupName]) -> JannoRow -> GroupName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ListColumn GroupName -> [GroupName]
forall a. ListColumn a -> [a]
getListColumn (ListColumn GroupName -> [GroupName])
-> (JannoRow -> ListColumn GroupName) -> JannoRow -> [GroupName]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JannoRow -> ListColumn GroupName
jGroupName) ([JannoRow] -> String) -> [JannoRow] -> String
forall a b. (a -> b) -> a -> b
$ [JannoRow]
rows],
[String
"Nr Publications"
, [JannoPublication] -> String
forall a. Ord a => [a] -> String
uniqueNumber ([JannoPublication] -> String)
-> ([JannoRow] -> [JannoPublication]) -> [JannoRow] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ListColumn JannoPublication -> [JannoPublication])
-> [ListColumn JannoPublication] -> [JannoPublication]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ListColumn JannoPublication -> [JannoPublication]
forall a. ListColumn a -> [a]
getListColumn ([ListColumn JannoPublication] -> [JannoPublication])
-> ([JannoRow] -> [ListColumn JannoPublication])
-> [JannoRow]
-> [JannoPublication]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoRow -> Maybe (ListColumn JannoPublication))
-> [JannoRow] -> [ListColumn JannoPublication]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe JannoRow -> Maybe (ListColumn JannoPublication)
jPublication ([JannoRow] -> String) -> [JannoRow] -> String
forall a b. (a -> b) -> a -> b
$ [JannoRow]
rows],
[String
"Publications"
, [String] -> String
paste ([String] -> String)
-> ([JannoRow] -> [String]) -> [JannoRow] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoPublication -> String) -> [JannoPublication] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map JannoPublication -> String
forall a. Show a => a -> String
show ([JannoPublication] -> [String])
-> ([JannoRow] -> [JannoPublication]) -> [JannoRow] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [JannoPublication] -> [JannoPublication]
forall a. Ord a => [a] -> [a]
uniquePO ([JannoPublication] -> [JannoPublication])
-> ([JannoRow] -> [JannoPublication])
-> [JannoRow]
-> [JannoPublication]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ListColumn JannoPublication -> [JannoPublication])
-> [ListColumn JannoPublication] -> [JannoPublication]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ListColumn JannoPublication -> [JannoPublication]
forall a. ListColumn a -> [a]
getListColumn ([ListColumn JannoPublication] -> [JannoPublication])
-> ([JannoRow] -> [ListColumn JannoPublication])
-> [JannoRow]
-> [JannoPublication]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoRow -> Maybe (ListColumn JannoPublication))
-> [JannoRow] -> [ListColumn JannoPublication]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe JannoRow -> Maybe (ListColumn JannoPublication)
jPublication ([JannoRow] -> String) -> [JannoRow] -> String
forall a b. (a -> b) -> a -> b
$ [JannoRow]
rows],
[String
"Nr Countries"
, [JannoCountry] -> String
forall a. Ord a => [a] -> String
uniqueNumber ([JannoCountry] -> String)
-> ([JannoRow] -> [JannoCountry]) -> [JannoRow] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoRow -> Maybe JannoCountry) -> [JannoRow] -> [JannoCountry]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe JannoRow -> Maybe JannoCountry
jCountry ([JannoRow] -> String) -> [JannoRow] -> String
forall a b. (a -> b) -> a -> b
$ [JannoRow]
rows],
[String
"Countries"
, String -> [(Maybe String, Int)] -> String
printFrequencyMaybeString String
", " ([(Maybe String, Int)] -> String)
-> ([JannoRow] -> [(Maybe String, Int)]) -> [JannoRow] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe String] -> [(Maybe String, Int)]
forall a. Ord a => [a] -> [(a, Int)]
frequency ([Maybe String] -> [(Maybe String, Int)])
-> ([JannoRow] -> [Maybe String])
-> [JannoRow]
-> [(Maybe String, Int)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoRow -> Maybe String) -> [JannoRow] -> [Maybe String]
forall a b. (a -> b) -> [a] -> [b]
map ((JannoCountry -> String) -> Maybe JannoCountry -> Maybe String
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap JannoCountry -> String
forall a. Show a => a -> String
show (Maybe JannoCountry -> Maybe String)
-> (JannoRow -> Maybe JannoCountry) -> JannoRow -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JannoRow -> Maybe JannoCountry
jCountry) ([JannoRow] -> String) -> [JannoRow] -> String
forall a b. (a -> b) -> a -> b
$ [JannoRow]
rows
],
[String
"Mean age BC/AD"
, [Double] -> String
meanAndSdInteger ([Double] -> String)
-> ([JannoRow] -> [Double]) -> [JannoRow] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoDateBCADMedian -> Double)
-> [JannoDateBCADMedian] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map (\(JannoDateBCADMedian Int
x) -> Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
x) ([JannoDateBCADMedian] -> [Double])
-> ([JannoRow] -> [JannoDateBCADMedian]) -> [JannoRow] -> [Double]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoRow -> Maybe JannoDateBCADMedian)
-> [JannoRow] -> [JannoDateBCADMedian]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe JannoRow -> Maybe JannoDateBCADMedian
jDateBCADMedian ([JannoRow] -> String) -> [JannoRow] -> String
forall a b. (a -> b) -> a -> b
$ [JannoRow]
rows],
[String
"Dating type"
, String -> [(Maybe JannoDateType, Int)] -> String
forall a. Show a => String -> [(Maybe a, Int)] -> String
printFrequencyMaybe String
", " ([(Maybe JannoDateType, Int)] -> String)
-> ([JannoRow] -> [(Maybe JannoDateType, Int)])
-> [JannoRow]
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe JannoDateType] -> [(Maybe JannoDateType, Int)]
forall a. Ord a => [a] -> [(a, Int)]
frequency ([Maybe JannoDateType] -> [(Maybe JannoDateType, Int)])
-> ([JannoRow] -> [Maybe JannoDateType])
-> [JannoRow]
-> [(Maybe JannoDateType, Int)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoRow -> Maybe JannoDateType)
-> [JannoRow] -> [Maybe JannoDateType]
forall a b. (a -> b) -> [a] -> [b]
map JannoRow -> Maybe JannoDateType
jDateType ([JannoRow] -> String) -> [JannoRow] -> String
forall a b. (a -> b) -> a -> b
$ [JannoRow]
rows],
[String
"Sex distribution"
, String -> [(GeneticSex, Int)] -> String
forall a. Show a => String -> [(a, Int)] -> String
printFrequency String
", " ([(GeneticSex, Int)] -> String)
-> ([JannoRow] -> [(GeneticSex, Int)]) -> [JannoRow] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [GeneticSex] -> [(GeneticSex, Int)]
forall a. Ord a => [a] -> [(a, Int)]
frequency ([GeneticSex] -> [(GeneticSex, Int)])
-> ([JannoRow] -> [GeneticSex])
-> [JannoRow]
-> [(GeneticSex, Int)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoRow -> GeneticSex) -> [JannoRow] -> [GeneticSex]
forall a b. (a -> b) -> [a] -> [b]
map JannoRow -> GeneticSex
jGeneticSex ([JannoRow] -> String) -> [JannoRow] -> String
forall a b. (a -> b) -> a -> b
$ [JannoRow]
rows],
[String
"MT haplogroups"
, String -> [(Maybe String, Int)] -> String
printFrequencyMaybeString String
", " ([(Maybe String, Int)] -> String)
-> ([JannoRow] -> [(Maybe String, Int)]) -> [JannoRow] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe String] -> [(Maybe String, Int)]
forall a. Ord a => [a] -> [(a, Int)]
frequency ([Maybe String] -> [(Maybe String, Int)])
-> ([JannoRow] -> [Maybe String])
-> [JannoRow]
-> [(Maybe String, Int)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoRow -> Maybe String) -> [JannoRow] -> [Maybe String]
forall a b. (a -> b) -> [a] -> [b]
map ((JannoMTHaplogroup -> String)
-> Maybe JannoMTHaplogroup -> Maybe String
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap JannoMTHaplogroup -> String
forall a. Show a => a -> String
show (Maybe JannoMTHaplogroup -> Maybe String)
-> (JannoRow -> Maybe JannoMTHaplogroup)
-> JannoRow
-> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JannoRow -> Maybe JannoMTHaplogroup
jMTHaplogroup) ([JannoRow] -> String) -> [JannoRow] -> String
forall a b. (a -> b) -> a -> b
$ [JannoRow]
rows],
[String
"Y haplogroups"
, String -> [(Maybe String, Int)] -> String
printFrequencyMaybeString String
", " ([(Maybe String, Int)] -> String)
-> ([JannoRow] -> [(Maybe String, Int)]) -> [JannoRow] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe String] -> [(Maybe String, Int)]
forall a. Ord a => [a] -> [(a, Int)]
frequency ([Maybe String] -> [(Maybe String, Int)])
-> ([JannoRow] -> [Maybe String])
-> [JannoRow]
-> [(Maybe String, Int)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoRow -> Maybe String) -> [JannoRow] -> [Maybe String]
forall a b. (a -> b) -> [a] -> [b]
map ((JannoYHaplogroup -> String)
-> Maybe JannoYHaplogroup -> Maybe String
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap JannoYHaplogroup -> String
forall a. Show a => a -> String
show (Maybe JannoYHaplogroup -> Maybe String)
-> (JannoRow -> Maybe JannoYHaplogroup) -> JannoRow -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JannoRow -> Maybe JannoYHaplogroup
jYHaplogroup) ([JannoRow] -> String) -> [JannoRow] -> String
forall a b. (a -> b) -> a -> b
$ [JannoRow]
rows],
[String
"% endogenous DNA"
, Int -> [Double] -> String
meanAndSdRoundTo Int
2 ([Double] -> String)
-> ([JannoRow] -> [Double]) -> [JannoRow] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoEndogenous -> Double) -> [JannoEndogenous] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map (\(JannoEndogenous Double
x) -> Double
x) ([JannoEndogenous] -> [Double])
-> ([JannoRow] -> [JannoEndogenous]) -> [JannoRow] -> [Double]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoRow -> Maybe JannoEndogenous)
-> [JannoRow] -> [JannoEndogenous]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe JannoRow -> Maybe JannoEndogenous
jEndogenous ([JannoRow] -> String) -> [JannoRow] -> String
forall a b. (a -> b) -> a -> b
$ [JannoRow]
rows],
[String
"Nr of SNPs"
, [Double] -> String
meanAndSdInteger ([Double] -> String)
-> ([JannoRow] -> [Double]) -> [JannoRow] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Double) -> [Int] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([Int] -> [Double])
-> ([JannoRow] -> [Int]) -> [JannoRow] -> [Double]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoRow -> Maybe Int) -> [JannoRow] -> [Int]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe ((JannoNrSNPs -> Int) -> Maybe JannoNrSNPs -> Maybe Int
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(JannoNrSNPs Int
x) -> Int
x) (Maybe JannoNrSNPs -> Maybe Int)
-> (JannoRow -> Maybe JannoNrSNPs) -> JannoRow -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JannoRow -> Maybe JannoNrSNPs
jNrSNPs) ([JannoRow] -> String) -> [JannoRow] -> String
forall a b. (a -> b) -> a -> b
$ [JannoRow]
rows],
[String
"Coverage on target"
, Int -> [Double] -> String
meanAndSdRoundTo Int
2 ([Double] -> String)
-> ([JannoRow] -> [Double]) -> [JannoRow] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoRow -> Maybe Double) -> [JannoRow] -> [Double]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe ((JannoCoverageOnTargets -> Double)
-> Maybe JannoCoverageOnTargets -> Maybe Double
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(JannoCoverageOnTargets Double
x) -> Double
x) (Maybe JannoCoverageOnTargets -> Maybe Double)
-> (JannoRow -> Maybe JannoCoverageOnTargets)
-> JannoRow
-> Maybe Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JannoRow -> Maybe JannoCoverageOnTargets
jCoverageOnTargets) ([JannoRow] -> String) -> [JannoRow] -> String
forall a b. (a -> b) -> a -> b
$ [JannoRow]
rows],
[String
"Library type"
, String -> [(Maybe JannoLibraryBuilt, Int)] -> String
forall a. Show a => String -> [(Maybe a, Int)] -> String
printFrequencyMaybe String
", " ([(Maybe JannoLibraryBuilt, Int)] -> String)
-> ([JannoRow] -> [(Maybe JannoLibraryBuilt, Int)])
-> [JannoRow]
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe JannoLibraryBuilt] -> [(Maybe JannoLibraryBuilt, Int)]
forall a. Ord a => [a] -> [(a, Int)]
frequency ([Maybe JannoLibraryBuilt] -> [(Maybe JannoLibraryBuilt, Int)])
-> ([JannoRow] -> [Maybe JannoLibraryBuilt])
-> [JannoRow]
-> [(Maybe JannoLibraryBuilt, Int)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoRow -> Maybe JannoLibraryBuilt)
-> [JannoRow] -> [Maybe JannoLibraryBuilt]
forall a b. (a -> b) -> [a] -> [b]
map JannoRow -> Maybe JannoLibraryBuilt
jLibraryBuilt ([JannoRow] -> String) -> [JannoRow] -> String
forall a b. (a -> b) -> a -> b
$ [JannoRow]
rows],
[String
"UDG treatment"
, String -> [(Maybe JannoUDG, Int)] -> String
forall a. Show a => String -> [(Maybe a, Int)] -> String
printFrequencyMaybe String
", " ([(Maybe JannoUDG, Int)] -> String)
-> ([JannoRow] -> [(Maybe JannoUDG, Int)]) -> [JannoRow] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe JannoUDG] -> [(Maybe JannoUDG, Int)]
forall a. Ord a => [a] -> [(a, Int)]
frequency ([Maybe JannoUDG] -> [(Maybe JannoUDG, Int)])
-> ([JannoRow] -> [Maybe JannoUDG])
-> [JannoRow]
-> [(Maybe JannoUDG, Int)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoRow -> Maybe JannoUDG) -> [JannoRow] -> [Maybe JannoUDG]
forall a b. (a -> b) -> [a] -> [b]
map JannoRow -> Maybe JannoUDG
jUDG ([JannoRow] -> String) -> [JannoRow] -> String
forall a b. (a -> b) -> a -> b
$ [JannoRow]
rows]
]
([String], [[String]]) -> IO ([String], [[String]])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([String]
tableH, [[String]]
tableB)
let colSpecs :: [ColSpec]
colSpecs = Int -> ColSpec -> [ColSpec]
forall a. Int -> a -> [a]
replicate Int
2 (LenSpec -> Position H -> AlignSpec -> CutMark -> ColSpec
column (Int -> LenSpec
expandUntil Int
60) Position H
forall a. Default a => a
def AlignSpec
forall a. Default a => a
def CutMark
forall a. Default a => a
def)
if Bool
rawOutput
then String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"\n" [String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"\t" [String]
row | [String]
row <- [[String]]
tableB]
else String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ [ColSpec]
-> TableStyle -> HeaderSpec -> [RowGroup String] -> String
forall a.
Cell a =>
[ColSpec] -> TableStyle -> HeaderSpec -> [RowGroup a] -> String
tableString [ColSpec]
colSpecs TableStyle
asciiRoundS ([String] -> HeaderSpec
titlesH [String]
tableH) [[[String]] -> RowGroup String
forall a. [Row a] -> RowGroup a
rowsG [[String]]
tableB]
paste :: [String] -> String
paste :: [String] -> String
paste [] = String
"no values"
paste [String]
xs = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " [String]
xs
uniqueNumber :: Ord a => [a] -> String
uniqueNumber :: forall a. Ord a => [a] -> String
uniqueNumber = Int -> String
forall a. Show a => a -> String
show (Int -> String) -> ([a] -> Int) -> [a] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([a] -> Int) -> ([a] -> [a]) -> [a] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [a]
forall a. Ord a => [a] -> [a]
uniquePO
frequency :: Ord a => [a] -> [(a,Int)]
frequency :: forall a. Ord a => [a] -> [(a, Int)]
frequency [a]
list = ((a, Int) -> (a, Int) -> Ordering) -> [(a, Int)] -> [(a, Int)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (a, Int) -> (a, Int) -> Ordering
forall a b. (Ord a, Ord b) => (a, b) -> (a, b) -> Ordering
sortTupelsBySndDesc ([(a, Int)] -> [(a, Int)]) -> [(a, Int)] -> [(a, Int)]
forall a b. (a -> b) -> a -> b
$ ([a] -> (a, Int)) -> [[a]] -> [(a, Int)]
forall a b. (a -> b) -> [a] -> [b]
map (\[a]
l -> ([a] -> a
forall a. HasCallStack => [a] -> a
head [a]
l, [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
l)) ([a] -> [[a]]
forall a. Eq a => [a] -> [[a]]
group ([a] -> [a]
forall a. Ord a => [a] -> [a]
sort [a]
list))
sortTupelsBySndDesc :: (Ord a, Ord b) => (a, b) -> (a, b) -> Ordering
sortTupelsBySndDesc :: forall a b. (Ord a, Ord b) => (a, b) -> (a, b) -> Ordering
sortTupelsBySndDesc (a
a1, b
b1) (a
a2, b
b2)
| b
b1 b -> b -> Bool
forall a. Ord a => a -> a -> Bool
< b
b2 = Ordering
GT
| b
b1 b -> b -> Bool
forall a. Ord a => a -> a -> Bool
> b
b2 = Ordering
LT
| b
b1 b -> b -> Bool
forall a. Eq a => a -> a -> Bool
== b
b2 = a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
a1 a
a2
| Bool
otherwise = String -> Ordering
forall a. HasCallStack => String -> a
error String
"sortTuplesBySndDesc: should never happen"
printFrequency :: Show a => String -> [(a,Int)] -> String
printFrequency :: forall a. Show a => String -> [(a, Int)] -> String
printFrequency String
_ [] = String
"no values"
printFrequency String
_ [(a, Int)
x] = a -> String
forall a. Show a => a -> String
show ((a, Int) -> a
forall a b. (a, b) -> a
fst (a, Int)
x) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show ((a, Int) -> Int
forall a b. (a, b) -> b
snd (a, Int)
x)
printFrequency String
sep ((a, Int)
x:[(a, Int)]
xs) = a -> String
forall a. Show a => a -> String
show ((a, Int) -> a
forall a b. (a, b) -> a
fst (a, Int)
x) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show ((a, Int) -> Int
forall a b. (a, b) -> b
snd (a, Int)
x) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
sep String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [(a, Int)] -> String
forall a. Show a => String -> [(a, Int)] -> String
printFrequency String
sep [(a, Int)]
xs
printFrequencyMaybe :: Show a => String -> [(Maybe a,Int)] -> String
printFrequencyMaybe :: forall a. Show a => String -> [(Maybe a, Int)] -> String
printFrequencyMaybe String
_ [] = String
"no values"
printFrequencyMaybe String
_ [(Maybe a, Int)
x] = Maybe a -> String
forall a. Show a => Maybe a -> String
maybeShow ((Maybe a, Int) -> Maybe a
forall a b. (a, b) -> a
fst (Maybe a, Int)
x) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show ((Maybe a, Int) -> Int
forall a b. (a, b) -> b
snd (Maybe a, Int)
x)
printFrequencyMaybe String
sep ((Maybe a, Int)
x:[(Maybe a, Int)]
xs) = Maybe a -> String
forall a. Show a => Maybe a -> String
maybeShow ((Maybe a, Int) -> Maybe a
forall a b. (a, b) -> a
fst (Maybe a, Int)
x) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show ((Maybe a, Int) -> Int
forall a b. (a, b) -> b
snd (Maybe a, Int)
x) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
sep String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [(Maybe a, Int)] -> String
forall a. Show a => String -> [(Maybe a, Int)] -> String
printFrequencyMaybe String
sep [(Maybe a, Int)]
xs
maybeShow :: Show a => Maybe a -> String
maybeShow :: forall a. Show a => Maybe a -> String
maybeShow (Just a
x) = a -> String
forall a. Show a => a -> String
show a
x
maybeShow Maybe a
Nothing = String
"n/a"
printFrequencyString :: String -> [(String,Int)] -> String
printFrequencyString :: String -> [(String, Int)] -> String
printFrequencyString String
_ [] = String
"no values"
printFrequencyString String
_ [(String, Int)
x] = (String, Int) -> String
forall a b. (a, b) -> a
fst (String, Int)
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show ((String, Int) -> Int
forall a b. (a, b) -> b
snd (String, Int)
x)
printFrequencyString String
sep ((String, Int)
x:[(String, Int)]
xs) = (String, Int) -> String
forall a b. (a, b) -> a
fst (String, Int)
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show ((String, Int) -> Int
forall a b. (a, b) -> b
snd (String, Int)
x) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
sep String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [(String, Int)] -> String
printFrequencyString String
sep [(String, Int)]
xs
printFrequencyMaybeString :: String -> [(Maybe String,Int)] -> String
printFrequencyMaybeString :: String -> [(Maybe String, Int)] -> String
printFrequencyMaybeString String
_ [] = String
"no values"
printFrequencyMaybeString String
_ [(Maybe String, Int)
x] = Maybe String -> String
maybeShowString ((Maybe String, Int) -> Maybe String
forall a b. (a, b) -> a
fst (Maybe String, Int)
x) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show ((Maybe String, Int) -> Int
forall a b. (a, b) -> b
snd (Maybe String, Int)
x)
printFrequencyMaybeString String
sep ((Maybe String, Int)
x:[(Maybe String, Int)]
xs) = Maybe String -> String
maybeShowString ((Maybe String, Int) -> Maybe String
forall a b. (a, b) -> a
fst (Maybe String, Int)
x) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show ((Maybe String, Int) -> Int
forall a b. (a, b) -> b
snd (Maybe String, Int)
x) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
sep String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [(Maybe String, Int)] -> String
printFrequencyMaybeString String
sep [(Maybe String, Int)]
xs
maybeShowString :: Maybe String -> String
maybeShowString :: Maybe String -> String
maybeShowString (Just String
x) = String
x
maybeShowString Maybe String
Nothing = String
"n/a"