{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
module Poseidon.Package (
PoseidonYamlStruct (..),
PoseidonPackage(..),
PoseidonException(..),
PackageReadOptions (..),
findAllPoseidonYmlFiles,
readPoseidonPackageCollection,
readPoseidonPackageCollectionWithSkipIndicator,
getJointGenotypeData,
getJointJanno,
getJointIndividualInfo,
getExtendedIndividualInfo,
newMinimalPackageTemplate,
newPackageTemplate,
renderMismatch,
zipWithPadding,
writePoseidonPackage,
defaultPackageReadOptions,
readPoseidonPackage,
makePseudoPackageFromGenotypeData,
getJannoRowsFromPac,
packagesToPackageInfos,
getAllGroupInfo,
validateGeno,
filterToRelevantPackages
) where
import Poseidon.BibFile (BibEntry (..), BibTeX,
readBibTeXFile)
import Poseidon.Contributor (ContributorSpec (..))
import Poseidon.EntityTypes (EntitySpec, HasNameAndVersion (..),
IndividualInfo (..),
IndividualInfoCollection,
PacNameAndVersion (..),
determineRelevantPackages,
isLatestInCollection,
makePacNameAndVersion,
renderNameWithVersion)
import Poseidon.GenotypeData (GenotypeDataSpec (..), joinEntries,
loadGenotypeData, loadIndividuals,
printSNPCopyProgress)
import Poseidon.Janno (JannoLibraryBuilt (..),
JannoList (..), JannoRow (..),
JannoRows (..), JannoSex (..),
JannoUDG (..), createMinimalJanno,
getMaybeJannoList,
jannoHeaderString, readJannoFile)
import Poseidon.PoseidonVersion (asVersion, latestPoseidonVersion,
showPoseidonVersion,
validPoseidonVersions)
import Poseidon.SequencingSource (SSFLibraryBuilt (..), SSFUDG (..),
SeqSourceRow (..),
SeqSourceRows (..),
readSeqSourceFile)
import Poseidon.ServerClient (AddJannoColSpec (..),
ExtendedIndividualInfo (..),
GroupInfo (..), PackageInfo (..))
import Poseidon.Utils (LogA, PoseidonException (..),
PoseidonIO, checkFile,
envErrorLength, envInputPlinkMode,
envLogAction, logDebug, logError,
logInfo, logWarning, logWithEnv,
renderPoseidonException)
import Control.DeepSeq (($!!))
import Control.Exception (catch, throwIO)
import Control.Monad (filterM, forM, forM_, unless, void,
when)
import Control.Monad.Catch (MonadThrow, throwM, try)
import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.Aeson (FromJSON, ToJSON, object,
parseJSON, toJSON, withObject,
(.!=), (.:), (.:?), (.=))
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as BSC
import Data.Char (isSpace)
import Data.Csv (toNamedRecord)
import Data.Either (lefts, rights)
import Data.Function (on)
import qualified Data.HashMap.Strict as HM
import Data.List (elemIndex, group, groupBy,
intercalate, nub, sort, sortOn,
(\\))
import Data.Maybe (catMaybes, fromMaybe, isNothing,
mapMaybe)
import Data.Time (Day, UTCTime (..), getCurrentTime)
import qualified Data.Vector as V
import Data.Version (Version (..), makeVersion)
import Data.Yaml (decodeEither')
import Data.Yaml.Pretty (defConfig, encodePretty,
setConfCompare, setConfDropNull)
import GHC.Generics (Generic)
import Pipes (Pipe, Producer, cat, for,
runEffect, yield, (>->))
import Pipes.OrderedZip (orderCheckPipe, orderedZip,
orderedZipAll)
import qualified Pipes.Prelude as P
import Pipes.Safe (MonadSafe, runSafeT)
import SequenceFormats.Eigenstrat (EigenstratIndEntry (..),
EigenstratSnpEntry (..),
GenoEntry (..), GenoLine,
readEigenstratSnpFile)
import SequenceFormats.Plink (PlinkPopNameMode (..), readBimFile)
import System.Directory (doesDirectoryExist, listDirectory)
import System.FilePath (takeBaseName, takeDirectory,
takeExtension, takeFileName, (</>))
import System.IO (IOMode (ReadMode), hGetContents,
withFile)
data PoseidonYamlStruct = PoseidonYamlStruct
{ PoseidonYamlStruct -> Version
_posYamlPoseidonVersion :: Version
, PoseidonYamlStruct -> FilePath
_posYamlTitle :: String
, PoseidonYamlStruct -> Maybe FilePath
_posYamlDescription :: Maybe String
, PoseidonYamlStruct -> [ContributorSpec]
_posYamlContributor :: [ContributorSpec]
, PoseidonYamlStruct -> Maybe Version
_posYamlPackageVersion :: Maybe Version
, PoseidonYamlStruct -> Maybe Day
_posYamlLastModified :: Maybe Day
, PoseidonYamlStruct -> GenotypeDataSpec
_posYamlGenotypeData :: GenotypeDataSpec
, PoseidonYamlStruct -> Maybe FilePath
_posYamlJannoFile :: Maybe FilePath
, PoseidonYamlStruct -> Maybe FilePath
_posYamlJannoFileChkSum :: Maybe String
, PoseidonYamlStruct -> Maybe FilePath
_posYamlSeqSourceFile :: Maybe FilePath
, PoseidonYamlStruct -> Maybe FilePath
_posYamlSeqSourceFileChkSum :: Maybe String
, PoseidonYamlStruct -> Maybe FilePath
_posYamlBibFile :: Maybe FilePath
, PoseidonYamlStruct -> Maybe FilePath
_posYamlBibFileChkSum :: Maybe String
, PoseidonYamlStruct -> Maybe FilePath
_posYamlReadmeFile :: Maybe FilePath
, PoseidonYamlStruct -> Maybe FilePath
_posYamlChangelogFile :: Maybe FilePath
}
deriving (Int -> PoseidonYamlStruct -> ShowS
[PoseidonYamlStruct] -> ShowS
PoseidonYamlStruct -> FilePath
(Int -> PoseidonYamlStruct -> ShowS)
-> (PoseidonYamlStruct -> FilePath)
-> ([PoseidonYamlStruct] -> ShowS)
-> Show PoseidonYamlStruct
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PoseidonYamlStruct -> ShowS
showsPrec :: Int -> PoseidonYamlStruct -> ShowS
$cshow :: PoseidonYamlStruct -> FilePath
show :: PoseidonYamlStruct -> FilePath
$cshowList :: [PoseidonYamlStruct] -> ShowS
showList :: [PoseidonYamlStruct] -> ShowS
Show, PoseidonYamlStruct -> PoseidonYamlStruct -> Bool
(PoseidonYamlStruct -> PoseidonYamlStruct -> Bool)
-> (PoseidonYamlStruct -> PoseidonYamlStruct -> Bool)
-> Eq PoseidonYamlStruct
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PoseidonYamlStruct -> PoseidonYamlStruct -> Bool
== :: PoseidonYamlStruct -> PoseidonYamlStruct -> Bool
$c/= :: PoseidonYamlStruct -> PoseidonYamlStruct -> Bool
/= :: PoseidonYamlStruct -> PoseidonYamlStruct -> Bool
Eq, (forall x. PoseidonYamlStruct -> Rep PoseidonYamlStruct x)
-> (forall x. Rep PoseidonYamlStruct x -> PoseidonYamlStruct)
-> Generic PoseidonYamlStruct
forall x. Rep PoseidonYamlStruct x -> PoseidonYamlStruct
forall x. PoseidonYamlStruct -> Rep PoseidonYamlStruct x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. PoseidonYamlStruct -> Rep PoseidonYamlStruct x
from :: forall x. PoseidonYamlStruct -> Rep PoseidonYamlStruct x
$cto :: forall x. Rep PoseidonYamlStruct x -> PoseidonYamlStruct
to :: forall x. Rep PoseidonYamlStruct x -> PoseidonYamlStruct
Generic)
poseidonJannoFilePath :: FilePath -> PoseidonYamlStruct -> Maybe FilePath
poseidonJannoFilePath :: FilePath -> PoseidonYamlStruct -> Maybe FilePath
poseidonJannoFilePath FilePath
baseDir PoseidonYamlStruct
yml = (FilePath
baseDir FilePath -> ShowS
</>) ShowS -> Maybe FilePath -> Maybe FilePath
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PoseidonYamlStruct -> Maybe FilePath
_posYamlJannoFile PoseidonYamlStruct
yml
poseidonSeqSourceFilePath :: FilePath -> PoseidonYamlStruct -> Maybe FilePath
poseidonSeqSourceFilePath :: FilePath -> PoseidonYamlStruct -> Maybe FilePath
poseidonSeqSourceFilePath FilePath
baseDir PoseidonYamlStruct
yml = (FilePath
baseDir FilePath -> ShowS
</>) ShowS -> Maybe FilePath -> Maybe FilePath
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PoseidonYamlStruct -> Maybe FilePath
_posYamlSeqSourceFile PoseidonYamlStruct
yml
poseidonBibFilePath :: FilePath -> PoseidonYamlStruct -> Maybe FilePath
poseidonBibFilePath :: FilePath -> PoseidonYamlStruct -> Maybe FilePath
poseidonBibFilePath FilePath
baseDir PoseidonYamlStruct
yml = (FilePath
baseDir FilePath -> ShowS
</>) ShowS -> Maybe FilePath -> Maybe FilePath
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PoseidonYamlStruct -> Maybe FilePath
_posYamlBibFile PoseidonYamlStruct
yml
poseidonReadmeFilePath :: FilePath -> PoseidonYamlStruct -> Maybe FilePath
poseidonReadmeFilePath :: FilePath -> PoseidonYamlStruct -> Maybe FilePath
poseidonReadmeFilePath FilePath
baseDir PoseidonYamlStruct
yml = (FilePath
baseDir FilePath -> ShowS
</>) ShowS -> Maybe FilePath -> Maybe FilePath
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PoseidonYamlStruct -> Maybe FilePath
_posYamlReadmeFile PoseidonYamlStruct
yml
poseidonChangelogFilePath :: FilePath -> PoseidonYamlStruct -> Maybe FilePath
poseidonChangelogFilePath :: FilePath -> PoseidonYamlStruct -> Maybe FilePath
poseidonChangelogFilePath FilePath
baseDir PoseidonYamlStruct
yml = (FilePath
baseDir FilePath -> ShowS
</>) ShowS -> Maybe FilePath -> Maybe FilePath
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PoseidonYamlStruct -> Maybe FilePath
_posYamlChangelogFile PoseidonYamlStruct
yml
instance FromJSON PoseidonYamlStruct where
parseJSON :: Value -> Parser PoseidonYamlStruct
parseJSON = FilePath
-> (Object -> Parser PoseidonYamlStruct)
-> Value
-> Parser PoseidonYamlStruct
forall a. FilePath -> (Object -> Parser a) -> Value -> Parser a
withObject FilePath
"PoseidonYamlStruct" ((Object -> Parser PoseidonYamlStruct)
-> Value -> Parser PoseidonYamlStruct)
-> (Object -> Parser PoseidonYamlStruct)
-> Value
-> Parser PoseidonYamlStruct
forall a b. (a -> b) -> a -> b
$ \Object
v -> Version
-> FilePath
-> Maybe FilePath
-> [ContributorSpec]
-> Maybe Version
-> Maybe Day
-> GenotypeDataSpec
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct
PoseidonYamlStruct
(Version
-> FilePath
-> Maybe FilePath
-> [ContributorSpec]
-> Maybe Version
-> Maybe Day
-> GenotypeDataSpec
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
-> Parser Version
-> Parser
(FilePath
-> Maybe FilePath
-> [ContributorSpec]
-> Maybe Version
-> Maybe Day
-> GenotypeDataSpec
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v Object -> Key -> Parser Version
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"poseidonVersion"
Parser
(FilePath
-> Maybe FilePath
-> [ContributorSpec]
-> Maybe Version
-> Maybe Day
-> GenotypeDataSpec
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
-> Parser FilePath
-> Parser
(Maybe FilePath
-> [ContributorSpec]
-> Maybe Version
-> Maybe Day
-> GenotypeDataSpec
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser FilePath
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"title"
Parser
(Maybe FilePath
-> [ContributorSpec]
-> Maybe Version
-> Maybe Day
-> GenotypeDataSpec
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
-> Parser (Maybe FilePath)
-> Parser
([ContributorSpec]
-> Maybe Version
-> Maybe Day
-> GenotypeDataSpec
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe FilePath)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"description"
Parser
([ContributorSpec]
-> Maybe Version
-> Maybe Day
-> GenotypeDataSpec
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
-> Parser [ContributorSpec]
-> Parser
(Maybe Version
-> Maybe Day
-> GenotypeDataSpec
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe [ContributorSpec])
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"contributor" Parser (Maybe [ContributorSpec])
-> [ContributorSpec] -> Parser [ContributorSpec]
forall a. Parser (Maybe a) -> a -> Parser a
.!= []
Parser
(Maybe Version
-> Maybe Day
-> GenotypeDataSpec
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
-> Parser (Maybe Version)
-> Parser
(Maybe Day
-> GenotypeDataSpec
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe Version)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"packageVersion"
Parser
(Maybe Day
-> GenotypeDataSpec
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
-> Parser (Maybe Day)
-> Parser
(GenotypeDataSpec
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe Day)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"lastModified"
Parser
(GenotypeDataSpec
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
-> Parser GenotypeDataSpec
-> Parser
(Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser GenotypeDataSpec
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"genotypeData"
Parser
(Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
-> Parser (Maybe FilePath)
-> Parser
(Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe FilePath)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"jannoFile"
Parser
(Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
-> Parser (Maybe FilePath)
-> Parser
(Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe FilePath)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"jannoFileChkSum"
Parser
(Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
-> Parser (Maybe FilePath)
-> Parser
(Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe FilePath)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"sequencingSourceFile"
Parser
(Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
-> Parser (Maybe FilePath)
-> Parser
(Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe FilePath)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"sequencingSourceFileChkSum"
Parser
(Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct)
-> Parser (Maybe FilePath)
-> Parser
(Maybe FilePath
-> Maybe FilePath -> Maybe FilePath -> PoseidonYamlStruct)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe FilePath)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"bibFile"
Parser
(Maybe FilePath
-> Maybe FilePath -> Maybe FilePath -> PoseidonYamlStruct)
-> Parser (Maybe FilePath)
-> Parser (Maybe FilePath -> Maybe FilePath -> PoseidonYamlStruct)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe FilePath)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"bibFileChkSum"
Parser (Maybe FilePath -> Maybe FilePath -> PoseidonYamlStruct)
-> Parser (Maybe FilePath)
-> Parser (Maybe FilePath -> PoseidonYamlStruct)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe FilePath)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"readmeFile"
Parser (Maybe FilePath -> PoseidonYamlStruct)
-> Parser (Maybe FilePath) -> Parser PoseidonYamlStruct
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe FilePath)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"changelogFile"
instance ToJSON PoseidonYamlStruct where
toJSON :: PoseidonYamlStruct -> Value
toJSON PoseidonYamlStruct
x = [Pair] -> Value
object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$ [
Key
"poseidonVersion" Key -> Version -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= PoseidonYamlStruct -> Version
_posYamlPoseidonVersion PoseidonYamlStruct
x,
Key
"title" Key -> FilePath -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= PoseidonYamlStruct -> FilePath
_posYamlTitle PoseidonYamlStruct
x,
Key
"description" Key -> Maybe FilePath -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= PoseidonYamlStruct -> Maybe FilePath
_posYamlDescription PoseidonYamlStruct
x] [Pair] -> [Pair] -> [Pair]
forall a. [a] -> [a] -> [a]
++
(if Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [ContributorSpec] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (PoseidonYamlStruct -> [ContributorSpec]
_posYamlContributor PoseidonYamlStruct
x) then [Key
"contributor" Key -> [ContributorSpec] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= PoseidonYamlStruct -> [ContributorSpec]
_posYamlContributor PoseidonYamlStruct
x] else []) [Pair] -> [Pair] -> [Pair]
forall a. [a] -> [a] -> [a]
++
[Key
"packageVersion" Key -> Maybe Version -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= PoseidonYamlStruct -> Maybe Version
_posYamlPackageVersion PoseidonYamlStruct
x,
Key
"lastModified" Key -> Maybe Day -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= PoseidonYamlStruct -> Maybe Day
_posYamlLastModified PoseidonYamlStruct
x,
Key
"genotypeData" Key -> GenotypeDataSpec -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= PoseidonYamlStruct -> GenotypeDataSpec
_posYamlGenotypeData PoseidonYamlStruct
x,
Key
"jannoFile" Key -> Maybe FilePath -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= PoseidonYamlStruct -> Maybe FilePath
_posYamlJannoFile PoseidonYamlStruct
x,
Key
"jannoFileChkSum" Key -> Maybe FilePath -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= PoseidonYamlStruct -> Maybe FilePath
_posYamlJannoFileChkSum PoseidonYamlStruct
x,
Key
"sequencingSourceFile" Key -> Maybe FilePath -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= PoseidonYamlStruct -> Maybe FilePath
_posYamlSeqSourceFile PoseidonYamlStruct
x,
Key
"sequencingSourceFileChkSum" Key -> Maybe FilePath -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= PoseidonYamlStruct -> Maybe FilePath
_posYamlSeqSourceFileChkSum PoseidonYamlStruct
x,
Key
"bibFile" Key -> Maybe FilePath -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= PoseidonYamlStruct -> Maybe FilePath
_posYamlBibFile PoseidonYamlStruct
x,
Key
"bibFileChkSum" Key -> Maybe FilePath -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= PoseidonYamlStruct -> Maybe FilePath
_posYamlBibFileChkSum PoseidonYamlStruct
x,
Key
"readmeFile" Key -> Maybe FilePath -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= PoseidonYamlStruct -> Maybe FilePath
_posYamlReadmeFile PoseidonYamlStruct
x,
Key
"changelogFile" Key -> Maybe FilePath -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
forall v. ToJSON v => Key -> v -> Pair
.= PoseidonYamlStruct -> Maybe FilePath
_posYamlChangelogFile PoseidonYamlStruct
x
]
instance HasNameAndVersion PoseidonYamlStruct where
getPacName :: PoseidonYamlStruct -> FilePath
getPacName = PoseidonYamlStruct -> FilePath
_posYamlTitle
getPacVersion :: PoseidonYamlStruct -> Maybe Version
getPacVersion = PoseidonYamlStruct -> Maybe Version
_posYamlPackageVersion
data PoseidonPackage = PoseidonPackage
{ PoseidonPackage -> FilePath
posPacBaseDir :: FilePath
, PoseidonPackage -> Version
posPacPoseidonVersion :: Version
, PoseidonPackage -> PacNameAndVersion
posPacNameAndVersion :: PacNameAndVersion
, PoseidonPackage -> Maybe FilePath
posPacDescription :: Maybe String
, PoseidonPackage -> [ContributorSpec]
posPacContributor :: [ContributorSpec]
, PoseidonPackage -> Maybe Day
posPacLastModified :: Maybe Day
, PoseidonPackage -> GenotypeDataSpec
posPacGenotypeData :: GenotypeDataSpec
, PoseidonPackage -> Maybe FilePath
posPacJannoFile :: Maybe FilePath
, PoseidonPackage -> JannoRows
posPacJanno :: JannoRows
, PoseidonPackage -> Maybe FilePath
posPacJannoFileChkSum :: Maybe String
, PoseidonPackage -> Maybe FilePath
posPacSeqSourceFile :: Maybe FilePath
, PoseidonPackage -> SeqSourceRows
posPacSeqSource :: SeqSourceRows
, PoseidonPackage -> Maybe FilePath
posPacSeqSourceFileChkSum :: Maybe String
, PoseidonPackage -> Maybe FilePath
posPacBibFile :: Maybe FilePath
, PoseidonPackage -> BibTeX
posPacBib :: BibTeX
, PoseidonPackage -> Maybe FilePath
posPacBibFileChkSum :: Maybe String
, PoseidonPackage -> Maybe FilePath
posPacReadmeFile :: Maybe FilePath
, PoseidonPackage -> Maybe FilePath
posPacChangelogFile :: Maybe FilePath
}
deriving (Int -> PoseidonPackage -> ShowS
[PoseidonPackage] -> ShowS
PoseidonPackage -> FilePath
(Int -> PoseidonPackage -> ShowS)
-> (PoseidonPackage -> FilePath)
-> ([PoseidonPackage] -> ShowS)
-> Show PoseidonPackage
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PoseidonPackage -> ShowS
showsPrec :: Int -> PoseidonPackage -> ShowS
$cshow :: PoseidonPackage -> FilePath
show :: PoseidonPackage -> FilePath
$cshowList :: [PoseidonPackage] -> ShowS
showList :: [PoseidonPackage] -> ShowS
Show, PoseidonPackage -> PoseidonPackage -> Bool
(PoseidonPackage -> PoseidonPackage -> Bool)
-> (PoseidonPackage -> PoseidonPackage -> Bool)
-> Eq PoseidonPackage
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PoseidonPackage -> PoseidonPackage -> Bool
== :: PoseidonPackage -> PoseidonPackage -> Bool
$c/= :: PoseidonPackage -> PoseidonPackage -> Bool
/= :: PoseidonPackage -> PoseidonPackage -> Bool
Eq, (forall x. PoseidonPackage -> Rep PoseidonPackage x)
-> (forall x. Rep PoseidonPackage x -> PoseidonPackage)
-> Generic PoseidonPackage
forall x. Rep PoseidonPackage x -> PoseidonPackage
forall x. PoseidonPackage -> Rep PoseidonPackage x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. PoseidonPackage -> Rep PoseidonPackage x
from :: forall x. PoseidonPackage -> Rep PoseidonPackage x
$cto :: forall x. Rep PoseidonPackage x -> PoseidonPackage
to :: forall x. Rep PoseidonPackage x -> PoseidonPackage
Generic)
instance Ord PoseidonPackage where
compare :: PoseidonPackage -> PoseidonPackage -> Ordering
compare PoseidonPackage
pacA PoseidonPackage
pacB = (FilePath, Maybe Version) -> (FilePath, Maybe Version) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (PoseidonPackage -> FilePath
forall a. HasNameAndVersion a => a -> FilePath
getPacName PoseidonPackage
pacA, PoseidonPackage -> Maybe Version
forall a. HasNameAndVersion a => a -> Maybe Version
getPacVersion PoseidonPackage
pacA) (PoseidonPackage -> FilePath
forall a. HasNameAndVersion a => a -> FilePath
getPacName PoseidonPackage
pacB, PoseidonPackage -> Maybe Version
forall a. HasNameAndVersion a => a -> Maybe Version
getPacVersion PoseidonPackage
pacB)
instance HasNameAndVersion PoseidonPackage where
getPacName :: PoseidonPackage -> FilePath
getPacName = PacNameAndVersion -> FilePath
forall a. HasNameAndVersion a => a -> FilePath
getPacName (PacNameAndVersion -> FilePath)
-> (PoseidonPackage -> PacNameAndVersion)
-> PoseidonPackage
-> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PoseidonPackage -> PacNameAndVersion
posPacNameAndVersion
getPacVersion :: PoseidonPackage -> Maybe Version
getPacVersion = PacNameAndVersion -> Maybe Version
forall a. HasNameAndVersion a => a -> Maybe Version
getPacVersion (PacNameAndVersion -> Maybe Version)
-> (PoseidonPackage -> PacNameAndVersion)
-> PoseidonPackage
-> Maybe Version
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PoseidonPackage -> PacNameAndVersion
posPacNameAndVersion
data PackageReadOptions = PackageReadOptions
{ PackageReadOptions -> Bool
_readOptIgnoreChecksums :: Bool
, PackageReadOptions -> Bool
_readOptIgnoreGeno :: Bool
, PackageReadOptions -> Bool
_readOptGenoCheck :: Bool
, PackageReadOptions -> Bool
_readOptFullGeno :: Bool
, PackageReadOptions -> Bool
_readOptIgnorePosVersion :: Bool
, PackageReadOptions -> Bool
_readOptOnlyLatest :: Bool
}
defaultPackageReadOptions :: PackageReadOptions
defaultPackageReadOptions :: PackageReadOptions
defaultPackageReadOptions = PackageReadOptions {
_readOptIgnoreChecksums :: Bool
_readOptIgnoreChecksums = Bool
False
, _readOptIgnoreGeno :: Bool
_readOptIgnoreGeno = Bool
False
, _readOptGenoCheck :: Bool
_readOptGenoCheck = Bool
True
, _readOptFullGeno :: Bool
_readOptFullGeno = Bool
False
, _readOptIgnorePosVersion :: Bool
_readOptIgnorePosVersion = Bool
False
, _readOptOnlyLatest :: Bool
_readOptOnlyLatest = Bool
False
}
readPoseidonPackageCollection :: PackageReadOptions
-> [FilePath]
-> PoseidonIO [PoseidonPackage]
readPoseidonPackageCollection :: PackageReadOptions -> [FilePath] -> PoseidonIO [PoseidonPackage]
readPoseidonPackageCollection PackageReadOptions
opts [FilePath]
baseDirs = ([PoseidonPackage], Bool) -> [PoseidonPackage]
forall a b. (a, b) -> a
fst (([PoseidonPackage], Bool) -> [PoseidonPackage])
-> ReaderT Env IO ([PoseidonPackage], Bool)
-> PoseidonIO [PoseidonPackage]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PackageReadOptions
-> [FilePath] -> ReaderT Env IO ([PoseidonPackage], Bool)
readPoseidonPackageCollectionWithSkipIndicator PackageReadOptions
opts [FilePath]
baseDirs
readPoseidonPackageCollectionWithSkipIndicator :: PackageReadOptions
-> [FilePath]
-> PoseidonIO ([PoseidonPackage], Bool)
readPoseidonPackageCollectionWithSkipIndicator :: PackageReadOptions
-> [FilePath] -> ReaderT Env IO ([PoseidonPackage], Bool)
readPoseidonPackageCollectionWithSkipIndicator PackageReadOptions
opts [FilePath]
baseDirs = do
FilePath -> PoseidonIO ()
logInfo FilePath
"Checking base directories... "
[FilePath]
goodDirs <- [Maybe FilePath] -> [FilePath]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe FilePath] -> [FilePath])
-> ReaderT Env IO [Maybe FilePath] -> ReaderT Env IO [FilePath]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (FilePath -> ReaderT Env IO (Maybe FilePath))
-> [FilePath] -> ReaderT Env IO [Maybe FilePath]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM FilePath -> ReaderT Env IO (Maybe FilePath)
checkIfBaseDirExists [FilePath]
baseDirs
FilePath -> PoseidonIO ()
logInfo FilePath
"Searching POSEIDON.yml files... "
[FilePath]
posFilesAllVersions <- IO [FilePath] -> ReaderT Env IO [FilePath]
forall a. IO a -> ReaderT Env IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [FilePath] -> ReaderT Env IO [FilePath])
-> IO [FilePath] -> ReaderT Env IO [FilePath]
forall a b. (a -> b) -> a -> b
$ [[FilePath]] -> [FilePath]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[FilePath]] -> [FilePath]) -> IO [[FilePath]] -> IO [FilePath]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (FilePath -> IO [FilePath]) -> [FilePath] -> IO [[FilePath]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM FilePath -> IO [FilePath]
findAllPoseidonYmlFiles [FilePath]
goodDirs
FilePath -> PoseidonIO ()
logInfo (FilePath -> PoseidonIO ()) -> FilePath -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ Int -> FilePath
forall a. Show a => a -> FilePath
show ([FilePath] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [FilePath]
posFilesAllVersions) FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
" found"
[FilePath]
posFiles <- if PackageReadOptions -> Bool
_readOptIgnorePosVersion PackageReadOptions
opts
then [FilePath] -> ReaderT Env IO [FilePath]
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [FilePath]
posFilesAllVersions
else do
FilePath -> PoseidonIO ()
logInfo FilePath
"Checking Poseidon versions... "
[FilePath] -> ReaderT Env IO [FilePath]
filterByPoseidonVersion [FilePath]
posFilesAllVersions
FilePath -> PoseidonIO ()
logInfo FilePath
"Initializing packages... "
[Either PoseidonException PoseidonPackage]
eitherPackages <- ((Integer, FilePath)
-> ReaderT Env IO (Either PoseidonException PoseidonPackage))
-> [(Integer, FilePath)]
-> ReaderT Env IO [Either PoseidonException PoseidonPackage]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Integer, FilePath)
-> ReaderT Env IO (Either PoseidonException PoseidonPackage)
tryDecodePoseidonPackage ([(Integer, FilePath)]
-> ReaderT Env IO [Either PoseidonException PoseidonPackage])
-> [(Integer, FilePath)]
-> ReaderT Env IO [Either PoseidonException PoseidonPackage]
forall a b. (a -> b) -> a -> b
$ [Integer] -> [FilePath] -> [(Integer, FilePath)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Integer
1..] [FilePath]
posFiles
Bool
skipIndicator <- if ([PoseidonException] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([PoseidonException] -> Bool)
-> ([Either PoseidonException PoseidonPackage]
-> [PoseidonException])
-> [Either PoseidonException PoseidonPackage]
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Either PoseidonException PoseidonPackage] -> [PoseidonException]
forall a b. [Either a b] -> [a]
lefts ([Either PoseidonException PoseidonPackage] -> Bool)
-> [Either PoseidonException PoseidonPackage] -> Bool
forall a b. (a -> b) -> a -> b
$ [Either PoseidonException PoseidonPackage]
eitherPackages) then Bool -> ReaderT Env IO Bool
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False else do
FilePath -> PoseidonIO ()
logWarning FilePath
"Some packages were skipped due to issues:"
[(FilePath, Either PoseidonException PoseidonPackage)]
-> ((FilePath, Either PoseidonException PoseidonPackage)
-> PoseidonIO ())
-> PoseidonIO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ ([FilePath]
-> [Either PoseidonException PoseidonPackage]
-> [(FilePath, Either PoseidonException PoseidonPackage)]
forall a b. [a] -> [b] -> [(a, b)]
zip [FilePath]
posFiles [Either PoseidonException PoseidonPackage]
eitherPackages) (((FilePath, Either PoseidonException PoseidonPackage)
-> PoseidonIO ())
-> PoseidonIO ())
-> ((FilePath, Either PoseidonException PoseidonPackage)
-> PoseidonIO ())
-> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ \(FilePath
posF, Either PoseidonException PoseidonPackage
epac) -> do
case Either PoseidonException PoseidonPackage
epac of
Left PoseidonException
e -> do
FilePath -> PoseidonIO ()
logWarning (FilePath -> PoseidonIO ()) -> FilePath -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ FilePath
"In the package described in " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
posF FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
":"
FilePath -> PoseidonIO ()
logWarning (FilePath -> PoseidonIO ()) -> FilePath -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ PoseidonException -> FilePath
renderPoseidonException PoseidonException
e
Either PoseidonException PoseidonPackage
_ -> () -> PoseidonIO ()
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Bool -> ReaderT Env IO Bool
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
let loadedPackages :: [PoseidonPackage]
loadedPackages = [Either PoseidonException PoseidonPackage] -> [PoseidonPackage]
forall a b. [Either a b] -> [b]
rights [Either PoseidonException PoseidonPackage]
eitherPackages
[PoseidonPackage]
filteredPackageList <-
if PackageReadOptions -> Bool
_readOptOnlyLatest PackageReadOptions
opts
then (PoseidonPackage -> ReaderT Env IO Bool)
-> [PoseidonPackage] -> PoseidonIO [PoseidonPackage]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM ([PoseidonPackage] -> PoseidonPackage -> ReaderT Env IO Bool
forall (m :: * -> *) a.
(MonadThrow m, HasNameAndVersion a) =>
[a] -> a -> m Bool
isLatestInCollection [PoseidonPackage]
loadedPackages) [PoseidonPackage]
loadedPackages
else [PoseidonPackage] -> PoseidonIO [PoseidonPackage]
forall a. a -> ReaderT Env IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([PoseidonPackage] -> PoseidonIO [PoseidonPackage])
-> [PoseidonPackage] -> PoseidonIO [PoseidonPackage]
forall a b. (a -> b) -> a -> b
$ [PoseidonPackage]
loadedPackages
let duplicateGroups :: [[PoseidonPackage]]
duplicateGroups = ([PoseidonPackage] -> Bool)
-> [[PoseidonPackage]] -> [[PoseidonPackage]]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
1) (Int -> Bool)
-> ([PoseidonPackage] -> Int) -> [PoseidonPackage] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [PoseidonPackage] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length)
([[PoseidonPackage]] -> [[PoseidonPackage]])
-> ([PoseidonPackage] -> [[PoseidonPackage]])
-> [PoseidonPackage]
-> [[PoseidonPackage]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PoseidonPackage -> PoseidonPackage -> Bool)
-> [PoseidonPackage] -> [[PoseidonPackage]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy (\PoseidonPackage
a PoseidonPackage
b -> PoseidonPackage -> PacNameAndVersion
forall a. HasNameAndVersion a => a -> PacNameAndVersion
makePacNameAndVersion PoseidonPackage
a PacNameAndVersion -> PacNameAndVersion -> Bool
forall a. Eq a => a -> a -> Bool
== PoseidonPackage -> PacNameAndVersion
forall a. HasNameAndVersion a => a -> PacNameAndVersion
makePacNameAndVersion PoseidonPackage
b)
([PoseidonPackage] -> [[PoseidonPackage]])
-> ([PoseidonPackage] -> [PoseidonPackage])
-> [PoseidonPackage]
-> [[PoseidonPackage]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PoseidonPackage -> PacNameAndVersion)
-> [PoseidonPackage] -> [PoseidonPackage]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn PoseidonPackage -> PacNameAndVersion
forall a. HasNameAndVersion a => a -> PacNameAndVersion
makePacNameAndVersion ([PoseidonPackage] -> [[PoseidonPackage]])
-> [PoseidonPackage] -> [[PoseidonPackage]]
forall a b. (a -> b) -> a -> b
$ [PoseidonPackage]
filteredPackageList
Bool -> PoseidonIO () -> PoseidonIO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([[PoseidonPackage]] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[PoseidonPackage]]
duplicateGroups) (PoseidonIO () -> PoseidonIO ()) -> PoseidonIO () -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ do
FilePath -> PoseidonIO ()
logError FilePath
"There are duplicated packages in this package collection:"
[[PoseidonPackage]]
-> ([PoseidonPackage] -> ReaderT Env IO Any) -> PoseidonIO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [[PoseidonPackage]]
duplicateGroups (([PoseidonPackage] -> ReaderT Env IO Any) -> PoseidonIO ())
-> ([PoseidonPackage] -> ReaderT Env IO Any) -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ \[PoseidonPackage]
xs -> do
FilePath -> PoseidonIO ()
logError (FilePath -> PoseidonIO ()) -> FilePath -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ FilePath
"Duplicate package " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ PacNameAndVersion -> FilePath
forall a. Show a => a -> FilePath
show (PoseidonPackage -> PacNameAndVersion
posPacNameAndVersion (PoseidonPackage -> PacNameAndVersion)
-> PoseidonPackage -> PacNameAndVersion
forall a b. (a -> b) -> a -> b
$ [PoseidonPackage] -> PoseidonPackage
forall a. HasCallStack => [a] -> a
head [PoseidonPackage]
xs) FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
" found at"
[PoseidonPackage]
-> (PoseidonPackage -> PoseidonIO ()) -> PoseidonIO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [PoseidonPackage]
xs ((PoseidonPackage -> PoseidonIO ()) -> PoseidonIO ())
-> (PoseidonPackage -> PoseidonIO ()) -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ \PoseidonPackage
x -> do
FilePath -> PoseidonIO ()
logError (FilePath -> PoseidonIO ()) -> FilePath -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ FilePath
" " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ PoseidonPackage -> FilePath
posPacBaseDir PoseidonPackage
x
PoseidonException -> ReaderT Env IO Any
forall e a. Exception e => e -> ReaderT Env IO a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (PoseidonException -> ReaderT Env IO Any)
-> (FilePath -> PoseidonException)
-> FilePath
-> ReaderT Env IO Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> PoseidonException
PoseidonCollectionException (FilePath -> ReaderT Env IO Any) -> FilePath -> ReaderT Env IO Any
forall a b. (a -> b) -> a -> b
$ FilePath
"Detected duplicate packages."
let finalPackageList :: [PoseidonPackage]
finalPackageList = [PoseidonPackage] -> [PoseidonPackage]
forall a. Ord a => [a] -> [a]
sort [PoseidonPackage]
filteredPackageList
FilePath -> PoseidonIO ()
logInfo (FilePath -> PoseidonIO ()) -> FilePath -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ FilePath
"Packages loaded: " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ (Int -> FilePath
forall a. Show a => a -> FilePath
show (Int -> FilePath)
-> ([PoseidonPackage] -> Int) -> [PoseidonPackage] -> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [PoseidonPackage] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([PoseidonPackage] -> FilePath) -> [PoseidonPackage] -> FilePath
forall a b. (a -> b) -> a -> b
$ [PoseidonPackage]
finalPackageList)
([PoseidonPackage], Bool)
-> ReaderT Env IO ([PoseidonPackage], Bool)
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([PoseidonPackage]
finalPackageList, Bool
skipIndicator)
where
checkIfBaseDirExists :: FilePath -> PoseidonIO (Maybe FilePath)
checkIfBaseDirExists :: FilePath -> ReaderT Env IO (Maybe FilePath)
checkIfBaseDirExists FilePath
p = do
Bool
exists <- IO Bool -> ReaderT Env IO Bool
forall a. IO a -> ReaderT Env IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> ReaderT Env IO Bool) -> IO Bool -> ReaderT Env IO Bool
forall a b. (a -> b) -> a -> b
$ FilePath -> IO Bool
doesDirectoryExist FilePath
p
if Bool
exists
then Maybe FilePath -> ReaderT Env IO (Maybe FilePath)
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (FilePath -> Maybe FilePath
forall a. a -> Maybe a
Just FilePath
p)
else do
FilePath -> PoseidonIO ()
logWarning (FilePath -> PoseidonIO ()) -> FilePath -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ FilePath
"Base directory (-d) " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> FilePath
show FilePath
p FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
" does not exist"
Maybe FilePath -> ReaderT Env IO (Maybe FilePath)
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe FilePath
forall a. Maybe a
Nothing
filterByPoseidonVersion :: [FilePath] -> PoseidonIO [FilePath]
filterByPoseidonVersion :: [FilePath] -> ReaderT Env IO [FilePath]
filterByPoseidonVersion [FilePath]
posFiles = do
[Either PoseidonException FilePath]
eitherPaths <- IO [Either PoseidonException FilePath]
-> ReaderT Env IO [Either PoseidonException FilePath]
forall a. IO a -> ReaderT Env IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [Either PoseidonException FilePath]
-> ReaderT Env IO [Either PoseidonException FilePath])
-> IO [Either PoseidonException FilePath]
-> ReaderT Env IO [Either PoseidonException FilePath]
forall a b. (a -> b) -> a -> b
$ (FilePath -> IO (Either PoseidonException FilePath))
-> [FilePath] -> IO [Either PoseidonException FilePath]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM FilePath -> IO (Either PoseidonException FilePath)
isInVersionRange [FilePath]
posFiles
(PoseidonException -> PoseidonIO ())
-> [PoseidonException] -> PoseidonIO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (FilePath -> PoseidonIO ()
logWarning (FilePath -> PoseidonIO ())
-> (PoseidonException -> FilePath)
-> PoseidonException
-> PoseidonIO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PoseidonException -> FilePath
renderPoseidonException) ([PoseidonException] -> PoseidonIO ())
-> [PoseidonException] -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ [Either PoseidonException FilePath] -> [PoseidonException]
forall a b. [Either a b] -> [a]
lefts [Either PoseidonException FilePath]
eitherPaths
[FilePath] -> ReaderT Env IO [FilePath]
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([FilePath] -> ReaderT Env IO [FilePath])
-> [FilePath] -> ReaderT Env IO [FilePath]
forall a b. (a -> b) -> a -> b
$ [Either PoseidonException FilePath] -> [FilePath]
forall a b. [Either a b] -> [b]
rights [Either PoseidonException FilePath]
eitherPaths
where
isInVersionRange :: FilePath -> IO (Either PoseidonException FilePath)
isInVersionRange :: FilePath -> IO (Either PoseidonException FilePath)
isInVersionRange FilePath
posFile = do
FilePath
content <- FilePath -> IO FilePath
readFile' FilePath
posFile
let posLines :: [FilePath]
posLines = FilePath -> [FilePath]
lines FilePath
content
case FilePath -> [FilePath] -> Maybe Int
forall a. Eq a => a -> [a] -> Maybe Int
elemIndex FilePath
"poseidonVersion:" (ShowS -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> ShowS
forall a. Int -> [a] -> [a]
take Int
16) [FilePath]
posLines) of
Maybe Int
Nothing -> Either PoseidonException FilePath
-> IO (Either PoseidonException FilePath)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either PoseidonException FilePath
-> IO (Either PoseidonException FilePath))
-> Either PoseidonException FilePath
-> IO (Either PoseidonException FilePath)
forall a b. (a -> b) -> a -> b
$ PoseidonException -> Either PoseidonException FilePath
forall a b. a -> Either a b
Left (PoseidonException -> Either PoseidonException FilePath)
-> PoseidonException -> Either PoseidonException FilePath
forall a b. (a -> b) -> a -> b
$ FilePath -> PoseidonException
PoseidonPackageMissingVersionException FilePath
posFile
Just Int
n -> do
let versionLine :: FilePath
versionLine = [FilePath]
posLines [FilePath] -> Int -> FilePath
forall a. HasCallStack => [a] -> Int -> a
!! Int
n
versionString :: FilePath
versionString = (Char -> Bool) -> ShowS
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isSpace) ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
16 FilePath
versionLine
if FilePath
versionString FilePath -> [FilePath] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (PoseidonVersion -> FilePath) -> [PoseidonVersion] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map PoseidonVersion -> FilePath
showPoseidonVersion [PoseidonVersion]
validPoseidonVersions
then Either PoseidonException FilePath
-> IO (Either PoseidonException FilePath)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either PoseidonException FilePath
-> IO (Either PoseidonException FilePath))
-> Either PoseidonException FilePath
-> IO (Either PoseidonException FilePath)
forall a b. (a -> b) -> a -> b
$ FilePath -> Either PoseidonException FilePath
forall a b. b -> Either a b
Right FilePath
posFile
else Either PoseidonException FilePath
-> IO (Either PoseidonException FilePath)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either PoseidonException FilePath
-> IO (Either PoseidonException FilePath))
-> Either PoseidonException FilePath
-> IO (Either PoseidonException FilePath)
forall a b. (a -> b) -> a -> b
$ PoseidonException -> Either PoseidonException FilePath
forall a b. a -> Either a b
Left (PoseidonException -> Either PoseidonException FilePath)
-> PoseidonException -> Either PoseidonException FilePath
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath -> PoseidonException
PoseidonPackageVersionException FilePath
posFile FilePath
versionString
readFile' :: FilePath -> IO String
readFile' :: FilePath -> IO FilePath
readFile' FilePath
filename = FilePath -> IOMode -> (Handle -> IO FilePath) -> IO FilePath
forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
withFile FilePath
filename IOMode
ReadMode ((Handle -> IO FilePath) -> IO FilePath)
-> (Handle -> IO FilePath) -> IO FilePath
forall a b. (a -> b) -> a -> b
$ \Handle
handle -> do
FilePath
theContent <- Handle -> IO FilePath
hGetContents Handle
handle
(Char -> IO Char) -> FilePath -> IO FilePath
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Char -> IO Char
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return FilePath
theContent
tryDecodePoseidonPackage :: (Integer, FilePath) -> PoseidonIO (Either PoseidonException PoseidonPackage)
tryDecodePoseidonPackage :: (Integer, FilePath)
-> ReaderT Env IO (Either PoseidonException PoseidonPackage)
tryDecodePoseidonPackage (Integer
numberPackage, FilePath
path) = do
FilePath -> PoseidonIO ()
logDebug (FilePath -> PoseidonIO ()) -> FilePath -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ FilePath
"Package " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ Integer -> FilePath
forall a. Show a => a -> FilePath
show Integer
numberPackage FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
": " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
path
ReaderT Env IO PoseidonPackage
-> ReaderT Env IO (Either PoseidonException PoseidonPackage)
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> m (Either e a)
try (ReaderT Env IO PoseidonPackage
-> ReaderT Env IO (Either PoseidonException PoseidonPackage))
-> (FilePath -> ReaderT Env IO PoseidonPackage)
-> FilePath
-> ReaderT Env IO (Either PoseidonException PoseidonPackage)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageReadOptions -> FilePath -> ReaderT Env IO PoseidonPackage
readPoseidonPackage PackageReadOptions
opts (FilePath
-> ReaderT Env IO (Either PoseidonException PoseidonPackage))
-> FilePath
-> ReaderT Env IO (Either PoseidonException PoseidonPackage)
forall a b. (a -> b) -> a -> b
$ FilePath
path
readPoseidonPackage :: PackageReadOptions
-> FilePath
-> PoseidonIO PoseidonPackage
readPoseidonPackage :: PackageReadOptions -> FilePath -> ReaderT Env IO PoseidonPackage
readPoseidonPackage PackageReadOptions
opts FilePath
ymlPath = do
let baseDir :: FilePath
baseDir = ShowS
takeDirectory FilePath
ymlPath
ByteString
bs <- IO ByteString -> ReaderT Env IO ByteString
forall a. IO a -> ReaderT Env IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ByteString -> ReaderT Env IO ByteString)
-> IO ByteString -> ReaderT Env IO ByteString
forall a b. (a -> b) -> a -> b
$ FilePath -> IO ByteString
B.readFile FilePath
ymlPath
yml :: PoseidonYamlStruct
yml@(PoseidonYamlStruct Version
ver FilePath
tit Maybe FilePath
des [ContributorSpec]
con Maybe Version
pacVer Maybe Day
mod_ GenotypeDataSpec
geno Maybe FilePath
jannoF Maybe FilePath
jannoC Maybe FilePath
seqSourceF Maybe FilePath
seqSourceC Maybe FilePath
bibF Maybe FilePath
bibC Maybe FilePath
readF Maybe FilePath
changeF) <- case ByteString -> Either ParseException PoseidonYamlStruct
forall a. FromJSON a => ByteString -> Either ParseException a
decodeEither' ByteString
bs of
Left ParseException
err -> PoseidonException -> ReaderT Env IO PoseidonYamlStruct
forall e a. Exception e => e -> ReaderT Env IO a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (PoseidonException -> ReaderT Env IO PoseidonYamlStruct)
-> PoseidonException -> ReaderT Env IO PoseidonYamlStruct
forall a b. (a -> b) -> a -> b
$ FilePath -> ParseException -> PoseidonException
PoseidonYamlParseException FilePath
ymlPath ParseException
err
Right PoseidonYamlStruct
pac -> PoseidonYamlStruct -> ReaderT Env IO PoseidonYamlStruct
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return PoseidonYamlStruct
pac
PoseidonYamlStruct -> PoseidonIO ()
checkYML PoseidonYamlStruct
yml
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
$ FilePath -> Bool -> Bool -> PoseidonYamlStruct -> IO ()
checkFiles FilePath
baseDir (PackageReadOptions -> Bool
_readOptIgnoreChecksums PackageReadOptions
opts) (PackageReadOptions -> Bool
_readOptIgnoreGeno PackageReadOptions
opts) PoseidonYamlStruct
yml
[EigenstratIndEntry]
indEntries <- FilePath -> GenotypeDataSpec -> PoseidonIO [EigenstratIndEntry]
loadIndividuals FilePath
baseDir GenotypeDataSpec
geno
JannoRows
janno <- case FilePath -> PoseidonYamlStruct -> Maybe FilePath
poseidonJannoFilePath FilePath
baseDir PoseidonYamlStruct
yml of
Maybe FilePath
Nothing -> do
JannoRows -> ReaderT Env IO JannoRows
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (JannoRows -> ReaderT Env IO JannoRows)
-> JannoRows -> ReaderT Env IO JannoRows
forall a b. (a -> b) -> a -> b
$ [EigenstratIndEntry] -> JannoRows
createMinimalJanno [EigenstratIndEntry]
indEntries
Just FilePath
p -> do
JannoRows
loadedJanno <- FilePath -> ReaderT Env IO JannoRows
readJannoFile FilePath
p
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
$ FilePath -> JannoRows -> [EigenstratIndEntry] -> IO ()
checkJannoIndConsistency FilePath
tit JannoRows
loadedJanno [EigenstratIndEntry]
indEntries
JannoRows -> ReaderT Env IO JannoRows
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return JannoRows
loadedJanno
SeqSourceRows
seqSource <- case FilePath -> PoseidonYamlStruct -> Maybe FilePath
poseidonSeqSourceFilePath FilePath
baseDir PoseidonYamlStruct
yml of
Maybe FilePath
Nothing -> SeqSourceRows -> ReaderT Env IO SeqSourceRows
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return SeqSourceRows
forall a. Monoid a => a
mempty
Just FilePath
p -> FilePath -> ReaderT Env IO SeqSourceRows
readSeqSourceFile FilePath
p
FilePath -> SeqSourceRows -> JannoRows -> PoseidonIO ()
checkSeqSourceJannoConsistency FilePath
tit SeqSourceRows
seqSource JannoRows
janno
BibTeX
bib <- case FilePath -> PoseidonYamlStruct -> Maybe FilePath
poseidonBibFilePath FilePath
baseDir PoseidonYamlStruct
yml of
Maybe FilePath
Nothing -> BibTeX -> ReaderT Env IO BibTeX
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([] :: BibTeX)
Just FilePath
p -> IO BibTeX -> ReaderT Env IO BibTeX
forall a. IO a -> ReaderT Env IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO BibTeX -> ReaderT Env IO BibTeX)
-> IO BibTeX -> ReaderT Env IO BibTeX
forall a b. (a -> b) -> a -> b
$ FilePath -> IO BibTeX
readBibTeXFile FilePath
p
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
$ FilePath -> JannoRows -> BibTeX -> IO ()
checkJannoBibConsistency FilePath
tit JannoRows
janno BibTeX
bib
Bool -> PoseidonIO () -> PoseidonIO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (PackageReadOptions -> Bool
_readOptFullGeno PackageReadOptions
opts) (PoseidonIO () -> PoseidonIO ()) -> PoseidonIO () -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ do
FilePath -> PoseidonIO ()
logInfo (FilePath -> PoseidonIO ()) -> FilePath -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ FilePath
"Trying to parse genotype data for package: " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
tit
let pac :: PoseidonPackage
pac = FilePath
-> Version
-> PacNameAndVersion
-> Maybe FilePath
-> [ContributorSpec]
-> Maybe Day
-> GenotypeDataSpec
-> Maybe FilePath
-> JannoRows
-> Maybe FilePath
-> Maybe FilePath
-> SeqSourceRows
-> Maybe FilePath
-> Maybe FilePath
-> BibTeX
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonPackage
PoseidonPackage FilePath
baseDir Version
ver (FilePath -> Maybe Version -> PacNameAndVersion
PacNameAndVersion FilePath
tit Maybe Version
pacVer) Maybe FilePath
des [ContributorSpec]
con Maybe Day
mod_ GenotypeDataSpec
geno Maybe FilePath
jannoF JannoRows
janno Maybe FilePath
jannoC Maybe FilePath
seqSourceF SeqSourceRows
seqSource Maybe FilePath
seqSourceC Maybe FilePath
bibF BibTeX
bib Maybe FilePath
bibC Maybe FilePath
readF Maybe FilePath
changeF
Bool -> PoseidonIO () -> PoseidonIO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not (PackageReadOptions -> Bool
_readOptIgnoreGeno PackageReadOptions
opts) Bool -> Bool -> Bool
&& PackageReadOptions -> Bool
_readOptGenoCheck PackageReadOptions
opts) (PoseidonIO () -> PoseidonIO ()) -> PoseidonIO () -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$
PoseidonPackage -> Bool -> PoseidonIO ()
validateGeno PoseidonPackage
pac (PackageReadOptions -> Bool
_readOptFullGeno PackageReadOptions
opts)
PoseidonPackage -> ReaderT Env IO PoseidonPackage
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return PoseidonPackage
pac
checkYML :: PoseidonYamlStruct -> PoseidonIO ()
checkYML :: PoseidonYamlStruct -> PoseidonIO ()
checkYML PoseidonYamlStruct
yml = do
let contributors :: [ContributorSpec]
contributors = PoseidonYamlStruct -> [ContributorSpec]
_posYamlContributor PoseidonYamlStruct
yml
Bool -> PoseidonIO () -> PoseidonIO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([ContributorSpec] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ContributorSpec]
contributors) (PoseidonIO () -> PoseidonIO ()) -> PoseidonIO () -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ do
FilePath -> PoseidonIO ()
logWarning (FilePath -> PoseidonIO ()) -> FilePath -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ FilePath
"Contributor missing in POSEIDON.yml file of package " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ PoseidonYamlStruct -> FilePath
forall a. HasNameAndVersion a => a -> FilePath
renderNameWithVersion PoseidonYamlStruct
yml
validateGeno :: PoseidonPackage -> Bool -> PoseidonIO ()
validateGeno :: PoseidonPackage -> Bool -> PoseidonIO ()
validateGeno PoseidonPackage
pac Bool
checkFullGeno = do
LogA
logA <- PoseidonIO LogA
envLogAction
PlinkPopNameMode
plinkMode <- PoseidonIO PlinkPopNameMode
envInputPlinkMode
ErrorLength
errLength <- PoseidonIO ErrorLength
envErrorLength
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
$ IO () -> (SomeException -> IO ()) -> IO ()
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
catch (
SafeT IO () -> IO ()
forall (m :: * -> *) r.
(MonadMask m, MonadIO m) =>
SafeT m r -> m r
runSafeT (SafeT IO () -> IO ()) -> SafeT IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
([EigenstratIndEntry]
_, Producer (EigenstratSnpEntry, GenoLine) (SafeT IO) ()
eigenstratProd) <- LogA
-> Bool
-> PlinkPopNameMode
-> [PoseidonPackage]
-> Maybe FilePath
-> SafeT
IO
([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) (SafeT IO) ())
forall (m :: * -> *).
MonadSafe m =>
LogA
-> Bool
-> PlinkPopNameMode
-> [PoseidonPackage]
-> Maybe FilePath
-> m ([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())
getJointGenotypeData LogA
logA Bool
False PlinkPopNameMode
plinkMode [PoseidonPackage
pac] Maybe FilePath
forall a. Maybe a
Nothing
if Bool
checkFullGeno
then do
UTCTime
currentTime <- IO UTCTime -> SafeT IO UTCTime
forall a. IO a -> SafeT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO UTCTime
getCurrentTime
Effect (SafeT IO) () -> SafeT IO ()
forall (m :: * -> *) r. Monad m => Effect m r -> m r
runEffect (Effect (SafeT IO) () -> SafeT IO ())
-> Effect (SafeT IO) () -> SafeT IO ()
forall a b. (a -> b) -> a -> b
$ Producer (EigenstratSnpEntry, GenoLine) (SafeT IO) ()
eigenstratProd Producer (EigenstratSnpEntry, GenoLine) (SafeT IO) ()
-> Proxy
()
(EigenstratSnpEntry, GenoLine)
()
(EigenstratSnpEntry, GenoLine)
(SafeT IO)
()
-> Producer (EigenstratSnpEntry, GenoLine) (SafeT IO) ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> LogA
-> UTCTime
-> Proxy
()
(EigenstratSnpEntry, GenoLine)
()
(EigenstratSnpEntry, GenoLine)
(SafeT IO)
()
forall (m :: * -> *) a.
MonadIO m =>
LogA -> UTCTime -> Pipe a a m ()
printSNPCopyProgress LogA
logA UTCTime
currentTime Producer (EigenstratSnpEntry, GenoLine) (SafeT IO) ()
-> Proxy () (EigenstratSnpEntry, GenoLine) () X (SafeT IO) ()
-> Effect (SafeT IO) ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> Proxy () (EigenstratSnpEntry, GenoLine) () X (SafeT IO) ()
Consumer' (EigenstratSnpEntry, GenoLine) (SafeT IO) ()
forall (m :: * -> *) a r. Functor m => Consumer' a m r
P.drain
else
Effect (SafeT IO) () -> SafeT IO ()
forall (m :: * -> *) r. Monad m => Effect m r -> m r
runEffect (Effect (SafeT IO) () -> SafeT IO ())
-> Effect (SafeT IO) () -> SafeT IO ()
forall a b. (a -> b) -> a -> b
$ Producer (EigenstratSnpEntry, GenoLine) (SafeT IO) ()
eigenstratProd Producer (EigenstratSnpEntry, GenoLine) (SafeT IO) ()
-> Proxy
()
(EigenstratSnpEntry, GenoLine)
()
(EigenstratSnpEntry, GenoLine)
(SafeT IO)
()
-> Producer (EigenstratSnpEntry, GenoLine) (SafeT IO) ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> Int
-> Proxy
()
(EigenstratSnpEntry, GenoLine)
()
(EigenstratSnpEntry, GenoLine)
(SafeT IO)
()
forall (m :: * -> *) a. Functor m => Int -> Pipe a a m ()
P.take Int
100 Producer (EigenstratSnpEntry, GenoLine) (SafeT IO) ()
-> Proxy () (EigenstratSnpEntry, GenoLine) () X (SafeT IO) ()
-> Effect (SafeT IO) ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> Proxy () (EigenstratSnpEntry, GenoLine) () X (SafeT IO) ()
Consumer' (EigenstratSnpEntry, GenoLine) (SafeT IO) ()
forall (m :: * -> *) a r. Functor m => Consumer' a m r
P.drain
) (PoseidonException -> IO ()
forall e a. Exception e => e -> IO a
throwIO (PoseidonException -> IO ())
-> (SomeException -> PoseidonException) -> SomeException -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ErrorLength -> SomeException -> PoseidonException
PoseidonGenotypeExceptionForward ErrorLength
errLength)
checkFiles :: FilePath -> Bool -> Bool -> PoseidonYamlStruct -> IO ()
checkFiles :: FilePath -> Bool -> Bool -> PoseidonYamlStruct -> IO ()
checkFiles FilePath
baseDir Bool
ignoreChecksums Bool
ignoreGenotypeFilesMissing PoseidonYamlStruct
yml = do
case FilePath -> PoseidonYamlStruct -> Maybe FilePath
poseidonReadmeFilePath FilePath
baseDir PoseidonYamlStruct
yml of
Maybe FilePath
Nothing -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just FilePath
fn -> FilePath -> Maybe FilePath -> IO ()
checkFile FilePath
fn Maybe FilePath
forall a. Maybe a
Nothing
case FilePath -> PoseidonYamlStruct -> Maybe FilePath
poseidonChangelogFilePath FilePath
baseDir PoseidonYamlStruct
yml of
Maybe FilePath
Nothing -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just FilePath
fn -> FilePath -> Maybe FilePath -> IO ()
checkFile FilePath
fn Maybe FilePath
forall a. Maybe a
Nothing
case FilePath -> PoseidonYamlStruct -> Maybe FilePath
poseidonBibFilePath FilePath
baseDir PoseidonYamlStruct
yml of
Maybe FilePath
Nothing -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just FilePath
fn -> if Bool
ignoreChecksums
then FilePath -> Maybe FilePath -> IO ()
checkFile FilePath
fn Maybe FilePath
forall a. Maybe a
Nothing
else FilePath -> Maybe FilePath -> IO ()
checkFile FilePath
fn (Maybe FilePath -> IO ()) -> Maybe FilePath -> IO ()
forall a b. (a -> b) -> a -> b
$ PoseidonYamlStruct -> Maybe FilePath
_posYamlBibFileChkSum PoseidonYamlStruct
yml
case FilePath -> PoseidonYamlStruct -> Maybe FilePath
poseidonJannoFilePath FilePath
baseDir PoseidonYamlStruct
yml of
Maybe FilePath
Nothing -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just FilePath
fn -> if Bool
ignoreChecksums
then FilePath -> Maybe FilePath -> IO ()
checkFile FilePath
fn Maybe FilePath
forall a. Maybe a
Nothing
else FilePath -> Maybe FilePath -> IO ()
checkFile FilePath
fn (Maybe FilePath -> IO ()) -> Maybe FilePath -> IO ()
forall a b. (a -> b) -> a -> b
$ PoseidonYamlStruct -> Maybe FilePath
_posYamlJannoFileChkSum PoseidonYamlStruct
yml
case FilePath -> PoseidonYamlStruct -> Maybe FilePath
poseidonSeqSourceFilePath FilePath
baseDir PoseidonYamlStruct
yml of
Maybe FilePath
Nothing -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just FilePath
fn -> if Bool
ignoreChecksums
then FilePath -> Maybe FilePath -> IO ()
checkFile FilePath
fn Maybe FilePath
forall a. Maybe a
Nothing
else FilePath -> Maybe FilePath -> IO ()
checkFile FilePath
fn (Maybe FilePath -> IO ()) -> Maybe FilePath -> IO ()
forall a b. (a -> b) -> a -> b
$ PoseidonYamlStruct -> Maybe FilePath
_posYamlSeqSourceFileChkSum PoseidonYamlStruct
yml
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
ignoreGenotypeFilesMissing (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
let gd :: GenotypeDataSpec
gd = PoseidonYamlStruct -> GenotypeDataSpec
_posYamlGenotypeData PoseidonYamlStruct
yml
d :: FilePath
d = FilePath
baseDir
if Bool
ignoreChecksums
then do
FilePath -> Maybe FilePath -> IO ()
checkFile (FilePath
d FilePath -> ShowS
</> GenotypeDataSpec -> FilePath
genoFile GenotypeDataSpec
gd) Maybe FilePath
forall a. Maybe a
Nothing
FilePath -> Maybe FilePath -> IO ()
checkFile (FilePath
d FilePath -> ShowS
</> GenotypeDataSpec -> FilePath
snpFile GenotypeDataSpec
gd) Maybe FilePath
forall a. Maybe a
Nothing
FilePath -> Maybe FilePath -> IO ()
checkFile (FilePath
d FilePath -> ShowS
</> GenotypeDataSpec -> FilePath
indFile GenotypeDataSpec
gd) Maybe FilePath
forall a. Maybe a
Nothing
else do
FilePath -> Maybe FilePath -> IO ()
checkFile (FilePath
d FilePath -> ShowS
</> GenotypeDataSpec -> FilePath
genoFile GenotypeDataSpec
gd) (Maybe FilePath -> IO ()) -> Maybe FilePath -> IO ()
forall a b. (a -> b) -> a -> b
$ GenotypeDataSpec -> Maybe FilePath
genoFileChkSum GenotypeDataSpec
gd
FilePath -> Maybe FilePath -> IO ()
checkFile (FilePath
d FilePath -> ShowS
</> GenotypeDataSpec -> FilePath
snpFile GenotypeDataSpec
gd) (Maybe FilePath -> IO ()) -> Maybe FilePath -> IO ()
forall a b. (a -> b) -> a -> b
$ GenotypeDataSpec -> Maybe FilePath
snpFileChkSum GenotypeDataSpec
gd
FilePath -> Maybe FilePath -> IO ()
checkFile (FilePath
d FilePath -> ShowS
</> GenotypeDataSpec -> FilePath
indFile GenotypeDataSpec
gd) (Maybe FilePath -> IO ()) -> Maybe FilePath -> IO ()
forall a b. (a -> b) -> a -> b
$ GenotypeDataSpec -> Maybe FilePath
indFileChkSum GenotypeDataSpec
gd
checkJannoIndConsistency :: String -> JannoRows -> [EigenstratIndEntry] -> IO ()
checkJannoIndConsistency :: FilePath -> JannoRows -> [EigenstratIndEntry] -> IO ()
checkJannoIndConsistency FilePath
pacName (JannoRows [JannoRow]
rows) [EigenstratIndEntry]
indEntries = do
let genoIDs :: [FilePath]
genoIDs = [ FilePath
x | EigenstratIndEntry FilePath
x Sex
_ FilePath
_ <- [EigenstratIndEntry]
indEntries]
genoSexs :: [Sex]
genoSexs = [ Sex
x | EigenstratIndEntry FilePath
_ Sex
x FilePath
_ <- [EigenstratIndEntry]
indEntries]
genoGroups :: [FilePath]
genoGroups = [ FilePath
x | EigenstratIndEntry FilePath
_ Sex
_ FilePath
x <- [EigenstratIndEntry]
indEntries]
let jannoIDs :: [FilePath]
jannoIDs = (JannoRow -> FilePath) -> [JannoRow] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map JannoRow -> FilePath
jPoseidonID [JannoRow]
rows
jannoSexs :: [Sex]
jannoSexs = (JannoRow -> Sex) -> [JannoRow] -> [Sex]
forall a b. (a -> b) -> [a] -> [b]
map (JannoSex -> Sex
sfSex (JannoSex -> Sex) -> (JannoRow -> JannoSex) -> JannoRow -> Sex
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JannoRow -> JannoSex
jGeneticSex) [JannoRow]
rows
jannoGroups :: [FilePath]
jannoGroups = (JannoRow -> FilePath) -> [JannoRow] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map ([FilePath] -> FilePath
forall a. HasCallStack => [a] -> a
head ([FilePath] -> FilePath)
-> (JannoRow -> [FilePath]) -> JannoRow -> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JannoList FilePath -> [FilePath]
forall a. JannoList a -> [a]
getJannoList (JannoList FilePath -> [FilePath])
-> (JannoRow -> JannoList FilePath) -> JannoRow -> [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JannoRow -> JannoList FilePath
jGroupName) [JannoRow]
rows
let idMis :: Bool
idMis = [FilePath]
genoIDs [FilePath] -> [FilePath] -> Bool
forall a. Eq a => a -> a -> Bool
/= [FilePath]
jannoIDs
sexMis :: Bool
sexMis = [Sex]
genoSexs [Sex] -> [Sex] -> Bool
forall a. Eq a => a -> a -> Bool
/= [Sex]
jannoSexs
groupMis :: Bool
groupMis = [FilePath]
genoGroups [FilePath] -> [FilePath] -> Bool
forall a. Eq a => a -> a -> Bool
/= [FilePath]
jannoGroups
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
idMis (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ PoseidonException -> IO ()
forall e a. Exception e => e -> IO a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (PoseidonException -> IO ()) -> PoseidonException -> IO ()
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath -> PoseidonException
PoseidonCrossFileConsistencyException FilePath
pacName (FilePath -> PoseidonException) -> FilePath -> PoseidonException
forall a b. (a -> b) -> a -> b
$
FilePath
"Individual ID mismatch between genotype data (left) and .janno files (right): " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++
[FilePath] -> [FilePath] -> FilePath
renderMismatch [FilePath]
genoIDs [FilePath]
jannoIDs
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
sexMis (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ PoseidonException -> IO ()
forall e a. Exception e => e -> IO a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (PoseidonException -> IO ()) -> PoseidonException -> IO ()
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath -> PoseidonException
PoseidonCrossFileConsistencyException FilePath
pacName (FilePath -> PoseidonException) -> FilePath -> PoseidonException
forall a b. (a -> b) -> a -> b
$
FilePath
"Individual Sex mismatch between genotype data (left) and .janno files (right): " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++
[FilePath] -> [FilePath] -> FilePath
renderMismatch ((Sex -> FilePath) -> [Sex] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map Sex -> FilePath
forall a. Show a => a -> FilePath
show [Sex]
genoSexs) ((Sex -> FilePath) -> [Sex] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map Sex -> FilePath
forall a. Show a => a -> FilePath
show [Sex]
jannoSexs)
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
groupMis (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ PoseidonException -> IO ()
forall e a. Exception e => e -> IO a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (PoseidonException -> IO ()) -> PoseidonException -> IO ()
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath -> PoseidonException
PoseidonCrossFileConsistencyException FilePath
pacName (FilePath -> PoseidonException) -> FilePath -> PoseidonException
forall a b. (a -> b) -> a -> b
$
FilePath
"Individual GroupID mismatch between genotype data (left) and .janno files (right). Note \
\that this could be due to a wrong Plink file population-name encoding \
\(see the --inPlinkPopName option). " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++
[FilePath] -> [FilePath] -> FilePath
renderMismatch [FilePath]
genoGroups [FilePath]
jannoGroups
renderMismatch :: [String] -> [String] -> String
renderMismatch :: [FilePath] -> [FilePath] -> FilePath
renderMismatch [FilePath]
a [FilePath]
b =
let misMatchList :: [FilePath]
misMatchList = ((FilePath, FilePath) -> FilePath)
-> [(FilePath, FilePath)] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map (\ (FilePath
x, FilePath
y) -> FilePath
"(" FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
x FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
" = " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
y FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
")")
(((FilePath, FilePath) -> Bool)
-> [(FilePath, FilePath)] -> [(FilePath, FilePath)]
forall a. (a -> Bool) -> [a] -> [a]
filter ((FilePath -> FilePath -> Bool) -> (FilePath, FilePath) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry FilePath -> FilePath -> Bool
forall a. Eq a => a -> a -> Bool
(/=)) ([(FilePath, FilePath)] -> [(FilePath, FilePath)])
-> [(FilePath, FilePath)] -> [(FilePath, FilePath)]
forall a b. (a -> b) -> a -> b
$ FilePath
-> FilePath -> [FilePath] -> [FilePath] -> [(FilePath, FilePath)]
forall a b. a -> b -> [a] -> [b] -> [(a, b)]
zipWithPadding FilePath
"?" FilePath
"?" [FilePath]
a [FilePath]
b)
in if [FilePath] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [FilePath]
misMatchList Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
5
then FilePath -> [FilePath] -> FilePath
forall a. [a] -> [[a]] -> [a]
intercalate FilePath
", " (Int -> [FilePath] -> [FilePath]
forall a. Int -> [a] -> [a]
take Int
5 [FilePath]
misMatchList) FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
", ..."
else FilePath -> [FilePath] -> FilePath
forall a. [a] -> [[a]] -> [a]
intercalate FilePath
", " [FilePath]
misMatchList
zipWithPadding :: a -> b -> [a] -> [b] -> [(a,b)]
zipWithPadding :: forall a b. a -> b -> [a] -> [b] -> [(a, b)]
zipWithPadding a
a b
b (a
x:[a]
xs) (b
y:[b]
ys) = (a
x,b
y) (a, b) -> [(a, b)] -> [(a, b)]
forall a. a -> [a] -> [a]
: a -> b -> [a] -> [b] -> [(a, b)]
forall a b. a -> b -> [a] -> [b] -> [(a, b)]
zipWithPadding a
a b
b [a]
xs [b]
ys
zipWithPadding a
a b
_ [] [b]
ys = [a] -> [b] -> [(a, b)]
forall a b. [a] -> [b] -> [(a, b)]
zip (a -> [a]
forall a. a -> [a]
repeat a
a) [b]
ys
zipWithPadding a
_ b
b [a]
xs [] = [a] -> [b] -> [(a, b)]
forall a b. [a] -> [b] -> [(a, b)]
zip [a]
xs (b -> [b]
forall a. a -> [a]
repeat b
b)
checkSeqSourceJannoConsistency :: String -> SeqSourceRows -> JannoRows -> PoseidonIO ()
checkSeqSourceJannoConsistency :: FilePath -> SeqSourceRows -> JannoRows -> PoseidonIO ()
checkSeqSourceJannoConsistency FilePath
pacName (SeqSourceRows [SeqSourceRow]
sRows) (JannoRows [JannoRow]
jRows) = do
PoseidonIO ()
checkPoseidonIDOverlap
PoseidonIO ()
checkUDGandLibraryBuiltOverlap
where
js :: [(FilePath, Maybe JannoUDG, Maybe JannoLibraryBuilt)]
js = (JannoRow -> (FilePath, Maybe JannoUDG, Maybe JannoLibraryBuilt))
-> [JannoRow]
-> [(FilePath, Maybe JannoUDG, Maybe JannoLibraryBuilt)]
forall a b. (a -> b) -> [a] -> [b]
map (\JannoRow
r -> (JannoRow -> FilePath
jPoseidonID JannoRow
r, JannoRow -> Maybe JannoUDG
jUDG JannoRow
r, JannoRow -> Maybe JannoLibraryBuilt
jLibraryBuilt JannoRow
r)) [JannoRow]
jRows
ss :: [([FilePath], Maybe SSFUDG, Maybe SSFLibraryBuilt)]
ss = (SeqSourceRow -> ([FilePath], Maybe SSFUDG, Maybe SSFLibraryBuilt))
-> [SeqSourceRow]
-> [([FilePath], Maybe SSFUDG, Maybe SSFLibraryBuilt)]
forall a b. (a -> b) -> [a] -> [b]
map (\SeqSourceRow
r -> (Maybe (JannoList FilePath) -> [FilePath]
forall a. Maybe (JannoList a) -> [a]
getMaybeJannoList (Maybe (JannoList FilePath) -> [FilePath])
-> Maybe (JannoList FilePath) -> [FilePath]
forall a b. (a -> b) -> a -> b
$ SeqSourceRow -> Maybe (JannoList FilePath)
sPoseidonID SeqSourceRow
r, SeqSourceRow -> Maybe SSFUDG
sUDG SeqSourceRow
r, SeqSourceRow -> Maybe SSFLibraryBuilt
sLibraryBuilt SeqSourceRow
r)) [SeqSourceRow]
sRows
checkPoseidonIDOverlap :: PoseidonIO ()
checkPoseidonIDOverlap :: PoseidonIO ()
checkPoseidonIDOverlap = do
let flatSeqSourceIDs :: [FilePath]
flatSeqSourceIDs = [FilePath] -> [FilePath]
forall a. Eq a => [a] -> [a]
nub ([FilePath] -> [FilePath]) -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> a -> b
$ [[FilePath]] -> [FilePath]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[FilePath]] -> [FilePath]) -> [[FilePath]] -> [FilePath]
forall a b. (a -> b) -> a -> b
$ [[FilePath]
a | ([FilePath]
a,Maybe SSFUDG
_,Maybe SSFLibraryBuilt
_) <- [([FilePath], Maybe SSFUDG, Maybe SSFLibraryBuilt)]
ss]
misMatch :: [FilePath]
misMatch = [FilePath]
flatSeqSourceIDs [FilePath] -> [FilePath] -> [FilePath]
forall a. Eq a => [a] -> [a] -> [a]
\\ [FilePath
a | (FilePath
a,Maybe JannoUDG
_,Maybe JannoLibraryBuilt
_) <- [(FilePath, Maybe JannoUDG, Maybe JannoLibraryBuilt)]
js]
Bool -> PoseidonIO () -> PoseidonIO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([FilePath] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [FilePath]
misMatch) (PoseidonIO () -> PoseidonIO ()) -> PoseidonIO () -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ do
FilePath -> PoseidonIO ()
logWarning (FilePath -> PoseidonIO ()) -> FilePath -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ FilePath
"The .ssf file in the package " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
pacName FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++
FilePath
" features Poseidon_IDs that are not in the package: " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath -> [FilePath] -> FilePath
forall a. [a] -> [[a]] -> [a]
intercalate FilePath
", " [FilePath]
misMatch
checkUDGandLibraryBuiltOverlap :: PoseidonIO ()
checkUDGandLibraryBuiltOverlap :: PoseidonIO ()
checkUDGandLibraryBuiltOverlap = do
((FilePath, Maybe JannoUDG, Maybe JannoLibraryBuilt)
-> PoseidonIO ())
-> [(FilePath, Maybe JannoUDG, Maybe JannoLibraryBuilt)]
-> PoseidonIO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (FilePath, Maybe JannoUDG, Maybe JannoLibraryBuilt)
-> PoseidonIO ()
checkOneIndividual [(FilePath, Maybe JannoUDG, Maybe JannoLibraryBuilt)]
js
where
checkOneIndividual :: (String, Maybe JannoUDG, Maybe JannoLibraryBuilt) -> PoseidonIO ()
checkOneIndividual :: (FilePath, Maybe JannoUDG, Maybe JannoLibraryBuilt)
-> PoseidonIO ()
checkOneIndividual (FilePath
jannoPoseidonID, Maybe JannoUDG
jannoUDG, Maybe JannoLibraryBuilt
jannoLibraryBuilt) = do
let relevantSeqSourceRows :: [([FilePath], Maybe SSFUDG, Maybe SSFLibraryBuilt)]
relevantSeqSourceRows = (([FilePath], Maybe SSFUDG, Maybe SSFLibraryBuilt) -> Bool)
-> [([FilePath], Maybe SSFUDG, Maybe SSFLibraryBuilt)]
-> [([FilePath], Maybe SSFUDG, Maybe SSFLibraryBuilt)]
forall a. (a -> Bool) -> [a] -> [a]
filter (\([FilePath]
seqSourcePoseidonID,Maybe SSFUDG
_,Maybe SSFLibraryBuilt
_) -> FilePath
jannoPoseidonID FilePath -> [FilePath] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [FilePath]
seqSourcePoseidonID) [([FilePath], Maybe SSFUDG, Maybe SSFLibraryBuilt)]
ss
allSeqSourceUDGs :: [SSFUDG]
allSeqSourceUDGs = [Maybe SSFUDG] -> [SSFUDG]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe SSFUDG] -> [SSFUDG]) -> [Maybe SSFUDG] -> [SSFUDG]
forall a b. (a -> b) -> a -> b
$ [Maybe SSFUDG
b | ([FilePath]
_,Maybe SSFUDG
b,Maybe SSFLibraryBuilt
_) <- [([FilePath], Maybe SSFUDG, Maybe SSFLibraryBuilt)]
relevantSeqSourceRows]
allSeqSourceLibraryBuilts :: [SSFLibraryBuilt]
allSeqSourceLibraryBuilts = [Maybe SSFLibraryBuilt] -> [SSFLibraryBuilt]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe SSFLibraryBuilt] -> [SSFLibraryBuilt])
-> [Maybe SSFLibraryBuilt] -> [SSFLibraryBuilt]
forall a b. (a -> b) -> a -> b
$ [Maybe SSFLibraryBuilt
c | ([FilePath]
_,Maybe SSFUDG
_,Maybe SSFLibraryBuilt
c) <- [([FilePath], Maybe SSFUDG, Maybe SSFLibraryBuilt)]
relevantSeqSourceRows]
case Maybe JannoUDG
jannoUDG of
Maybe JannoUDG
Nothing -> () -> PoseidonIO ()
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just JannoUDG
j -> Bool -> PoseidonIO () -> PoseidonIO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ((SSFUDG -> Bool) -> [SSFUDG] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (JannoUDG -> SSFUDG -> Bool
compareU JannoUDG
j) [SSFUDG]
allSeqSourceUDGs) (PoseidonIO () -> PoseidonIO ()) -> PoseidonIO () -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$
PoseidonException -> PoseidonIO ()
forall e a. Exception e => e -> ReaderT Env IO a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (PoseidonException -> PoseidonIO ())
-> PoseidonException -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath -> PoseidonException
PoseidonCrossFileConsistencyException FilePath
pacName (FilePath -> PoseidonException) -> FilePath -> PoseidonException
forall a b. (a -> b) -> a -> b
$
FilePath
"The information on UDG treatment in .janno and .ssf do not match" FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++
FilePath
" for the individual: " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
jannoPoseidonID FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
" (" FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ JannoUDG -> FilePath
forall a. Show a => a -> FilePath
show JannoUDG
j FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
" <> " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ [SSFUDG] -> FilePath
forall a. Show a => a -> FilePath
show [SSFUDG]
allSeqSourceUDGs FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
")"
case Maybe JannoLibraryBuilt
jannoLibraryBuilt of
Maybe JannoLibraryBuilt
Nothing -> () -> PoseidonIO ()
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just JannoLibraryBuilt
j -> Bool -> PoseidonIO () -> PoseidonIO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ((SSFLibraryBuilt -> Bool) -> [SSFLibraryBuilt] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (JannoLibraryBuilt -> SSFLibraryBuilt -> Bool
compareL JannoLibraryBuilt
j) [SSFLibraryBuilt]
allSeqSourceLibraryBuilts) (PoseidonIO () -> PoseidonIO ()) -> PoseidonIO () -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$
PoseidonException -> PoseidonIO ()
forall e a. Exception e => e -> ReaderT Env IO a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (PoseidonException -> PoseidonIO ())
-> PoseidonException -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath -> PoseidonException
PoseidonCrossFileConsistencyException FilePath
pacName (FilePath -> PoseidonException) -> FilePath -> PoseidonException
forall a b. (a -> b) -> a -> b
$
FilePath
"The information on library strandedness in .janno and .ssf do not match" FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++
FilePath
" for the individual: " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
jannoPoseidonID FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
" (" FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ JannoLibraryBuilt -> FilePath
forall a. Show a => a -> FilePath
show JannoLibraryBuilt
j FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
" <> " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ [SSFLibraryBuilt] -> FilePath
forall a. Show a => a -> FilePath
show [SSFLibraryBuilt]
allSeqSourceLibraryBuilts FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
")"
compareU :: JannoUDG -> SSFUDG -> Bool
compareU :: JannoUDG -> SSFUDG -> Bool
compareU JannoUDG
Mixed SSFUDG
_ = Bool
True
compareU JannoUDG
Minus SSFUDG
SSFMinus = Bool
True
compareU JannoUDG
Half SSFUDG
SSFHalf = Bool
True
compareU JannoUDG
Plus SSFUDG
SSFPlus = Bool
True
compareU JannoUDG
_ SSFUDG
_ = Bool
False
compareL :: JannoLibraryBuilt -> SSFLibraryBuilt -> Bool
compareL :: JannoLibraryBuilt -> SSFLibraryBuilt -> Bool
compareL JannoLibraryBuilt
MixedSSDS SSFLibraryBuilt
_ = Bool
True
compareL JannoLibraryBuilt
DS SSFLibraryBuilt
SSFDS = Bool
True
compareL JannoLibraryBuilt
SS SSFLibraryBuilt
SSFSS = Bool
True
compareL JannoLibraryBuilt
_ SSFLibraryBuilt
_ = Bool
False
checkJannoBibConsistency :: String -> JannoRows -> BibTeX -> IO ()
checkJannoBibConsistency :: FilePath -> JannoRows -> BibTeX -> IO ()
checkJannoBibConsistency FilePath
pacName (JannoRows [JannoRow]
rows) BibTeX
bibtex = do
let literatureInJanno :: [FilePath]
literatureInJanno = [FilePath] -> [FilePath]
forall a. Eq a => [a] -> [a]
nub ([FilePath] -> [FilePath])
-> ([JannoRow] -> [FilePath]) -> [JannoRow] -> [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoList FilePath -> [FilePath])
-> [JannoList FilePath] -> [FilePath]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap JannoList FilePath -> [FilePath]
forall a. JannoList a -> [a]
getJannoList ([JannoList FilePath] -> [FilePath])
-> ([JannoRow] -> [JannoList FilePath]) -> [JannoRow] -> [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JannoRow -> Maybe (JannoList FilePath))
-> [JannoRow] -> [JannoList FilePath]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe JannoRow -> Maybe (JannoList FilePath)
jPublication ([JannoRow] -> [FilePath]) -> [JannoRow] -> [FilePath]
forall a b. (a -> b) -> a -> b
$ [JannoRow]
rows
literatureInBib :: [FilePath]
literatureInBib = [FilePath] -> [FilePath]
forall a. Eq a => [a] -> [a]
nub ([FilePath] -> [FilePath]) -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> a -> b
$ (BibEntry -> FilePath) -> BibTeX -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map BibEntry -> FilePath
bibEntryId BibTeX
bibtex
literatureNotInBibButInJanno :: [FilePath]
literatureNotInBibButInJanno = [FilePath]
literatureInJanno [FilePath] -> [FilePath] -> [FilePath]
forall a. Eq a => [a] -> [a] -> [a]
\\ [FilePath]
literatureInBib
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([FilePath] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [FilePath]
literatureNotInBibButInJanno) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ PoseidonException -> IO ()
forall e a. Exception e => e -> IO a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (PoseidonException -> IO ()) -> PoseidonException -> IO ()
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath -> PoseidonException
PoseidonCrossFileConsistencyException FilePath
pacName (FilePath -> PoseidonException) -> FilePath -> PoseidonException
forall a b. (a -> b) -> a -> b
$
FilePath
"The following papers lack BibTeX entries: " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++
FilePath -> [FilePath] -> FilePath
forall a. [a] -> [[a]] -> [a]
intercalate FilePath
", " [FilePath]
literatureNotInBibButInJanno
findAllPoseidonYmlFiles :: FilePath -> IO [FilePath]
findAllPoseidonYmlFiles :: FilePath -> IO [FilePath]
findAllPoseidonYmlFiles FilePath
baseDir = do
[FilePath]
entries <- FilePath -> IO [FilePath]
listDirectory FilePath
baseDir
let posFiles :: [FilePath]
posFiles = ShowS -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath
baseDir FilePath -> ShowS
</>) ([FilePath] -> [FilePath]) -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> a -> b
$ (FilePath -> Bool) -> [FilePath] -> [FilePath]
forall a. (a -> Bool) -> [a] -> [a]
filter (FilePath -> FilePath -> Bool
forall a. Eq a => a -> a -> Bool
==FilePath
"POSEIDON.yml") ([FilePath] -> [FilePath]) -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> a -> b
$ ShowS -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map ShowS
takeFileName [FilePath]
entries
[FilePath]
subDirs <- (FilePath -> IO Bool) -> [FilePath] -> IO [FilePath]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM FilePath -> IO Bool
doesDirectoryExist ([FilePath] -> IO [FilePath])
-> ([FilePath] -> [FilePath]) -> [FilePath] -> IO [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath
baseDir FilePath -> ShowS
</>) ([FilePath] -> IO [FilePath]) -> [FilePath] -> IO [FilePath]
forall a b. (a -> b) -> a -> b
$ [FilePath]
entries
[FilePath]
morePosFiles <- ([[FilePath]] -> [FilePath]) -> IO [[FilePath]] -> IO [FilePath]
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [[FilePath]] -> [FilePath]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (IO [[FilePath]] -> IO [FilePath])
-> ([FilePath] -> IO [[FilePath]]) -> [FilePath] -> IO [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FilePath -> IO [FilePath]) -> [FilePath] -> IO [[FilePath]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM FilePath -> IO [FilePath]
findAllPoseidonYmlFiles ([FilePath] -> IO [FilePath]) -> [FilePath] -> IO [FilePath]
forall a b. (a -> b) -> a -> b
$ [FilePath]
subDirs
[FilePath] -> IO [FilePath]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([FilePath] -> IO [FilePath]) -> [FilePath] -> IO [FilePath]
forall a b. (a -> b) -> a -> b
$ [FilePath]
posFiles [FilePath] -> [FilePath] -> [FilePath]
forall a. [a] -> [a] -> [a]
++ [FilePath]
morePosFiles
getJointGenotypeData :: MonadSafe m =>
LogA
-> Bool
-> PlinkPopNameMode
-> [PoseidonPackage]
-> Maybe FilePath
-> m ([EigenstratIndEntry], Producer (EigenstratSnpEntry, GenoLine) m ())
getJointGenotypeData :: forall (m :: * -> *).
MonadSafe m =>
LogA
-> Bool
-> PlinkPopNameMode
-> [PoseidonPackage]
-> Maybe FilePath
-> m ([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())
getJointGenotypeData LogA
logA Bool
intersect PlinkPopNameMode
popMode [PoseidonPackage]
pacs Maybe FilePath
maybeSnpFile = do
[([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())]
genotypeTuples <- [m ([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())]
-> m [([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence [FilePath
-> GenotypeDataSpec
-> PlinkPopNameMode
-> m ([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())
forall (m :: * -> *).
MonadSafe m =>
FilePath
-> GenotypeDataSpec
-> PlinkPopNameMode
-> m ([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())
loadGenotypeData (PoseidonPackage -> FilePath
posPacBaseDir PoseidonPackage
pac) (PoseidonPackage -> GenotypeDataSpec
posPacGenotypeData PoseidonPackage
pac) PlinkPopNameMode
popMode | PoseidonPackage
pac <- [PoseidonPackage]
pacs]
let indEntries :: [[EigenstratIndEntry]]
indEntries = (([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())
-> [EigenstratIndEntry])
-> [([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())]
-> [[EigenstratIndEntry]]
forall a b. (a -> b) -> [a] -> [b]
map ([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())
-> [EigenstratIndEntry]
forall a b. (a, b) -> a
fst [([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())]
genotypeTuples
jointIndEntries :: [EigenstratIndEntry]
jointIndEntries = [[EigenstratIndEntry]] -> [EigenstratIndEntry]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[EigenstratIndEntry]]
indEntries
nrInds :: [Int]
nrInds = ([EigenstratIndEntry] -> Int) -> [[EigenstratIndEntry]] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map [EigenstratIndEntry] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [[EigenstratIndEntry]]
indEntries
pacNames :: [FilePath]
pacNames = (PoseidonPackage -> FilePath) -> [PoseidonPackage] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map PoseidonPackage -> FilePath
forall a. HasNameAndVersion a => a -> FilePath
getPacName [PoseidonPackage]
pacs
prod :: Proxy X () () (EigenstratSnpEntry, GenoLine) m [()]
prod = (((EigenstratSnpEntry, GenoLine)
-> (EigenstratSnpEntry, GenoLine) -> Ordering)
-> [Producer (EigenstratSnpEntry, GenoLine) m ()]
-> Producer [Maybe (EigenstratSnpEntry, GenoLine)] m [()]
forall (m :: * -> *) a r.
Monad m =>
(a -> a -> Ordering)
-> [Producer a m r] -> Producer [Maybe a] m [r]
orderedZipAll (EigenstratSnpEntry, GenoLine)
-> (EigenstratSnpEntry, GenoLine) -> Ordering
compFunc ([Producer (EigenstratSnpEntry, GenoLine) m ()]
-> Producer [Maybe (EigenstratSnpEntry, GenoLine)] m [()])
-> ([([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())]
-> [Producer (EigenstratSnpEntry, GenoLine) m ()])
-> [([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())]
-> Producer [Maybe (EigenstratSnpEntry, GenoLine)] m [()]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())
-> Producer (EigenstratSnpEntry, GenoLine) m ())
-> [([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())]
-> [Producer (EigenstratSnpEntry, GenoLine) m ()]
forall a b. (a -> b) -> [a] -> [b]
map ([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())
-> Producer (EigenstratSnpEntry, GenoLine) m ()
forall a b. (a, b) -> b
snd) [([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())]
genotypeTuples Producer [Maybe (EigenstratSnpEntry, GenoLine)] m [()]
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
[Maybe (EigenstratSnpEntry, GenoLine)]
m
[()]
-> Producer [Maybe (EigenstratSnpEntry, GenoLine)] m [()]
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>->
([Maybe (EigenstratSnpEntry, GenoLine)] -> Bool)
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
[Maybe (EigenstratSnpEntry, GenoLine)]
m
[()]
forall (m :: * -> *) a r. Functor m => (a -> Bool) -> Pipe a a m r
P.filter [Maybe (EigenstratSnpEntry, GenoLine)] -> Bool
filterUnionOrIntersection Producer [Maybe (EigenstratSnpEntry, GenoLine)] m [()]
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
[()]
-> Proxy X () () (EigenstratSnpEntry, GenoLine) m [()]
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> LogA
-> [Int]
-> [FilePath]
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
[()]
forall (m :: * -> *) r.
MonadIO m =>
LogA
-> [Int]
-> [FilePath]
-> Pipe
[Maybe (EigenstratSnpEntry, GenoLine)]
(EigenstratSnpEntry, GenoLine)
m
r
joinEntryPipe LogA
logA [Int]
nrInds [FilePath]
pacNames
Proxy X () () (EigenstratSnpEntry, GenoLine) m [()]
jointProducer <- case Maybe FilePath
maybeSnpFile of
Maybe FilePath
Nothing -> do
Proxy X () () (EigenstratSnpEntry, GenoLine) m [()]
-> m (Proxy X () () (EigenstratSnpEntry, GenoLine) m [()])
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Proxy X () () (EigenstratSnpEntry, GenoLine) m [()]
prod
Just FilePath
fn -> do
let snpProd :: Proxy X () () EigenstratSnpEntry m ()
snpProd = FilePath -> Proxy X () () EigenstratSnpEntry m ()
forall (m :: * -> *).
MonadSafe m =>
FilePath -> Producer EigenstratSnpEntry m ()
loadBimOrSnpFile FilePath
fn Proxy X () () EigenstratSnpEntry m ()
-> Proxy () EigenstratSnpEntry () EigenstratSnpEntry m ()
-> Proxy X () () EigenstratSnpEntry m ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> (EigenstratSnpEntry -> EigenstratSnpEntry -> Ordering)
-> Proxy () EigenstratSnpEntry () EigenstratSnpEntry m ()
forall (m :: * -> *) a r.
(MonadIO m, MonadSafe m, Show a) =>
(a -> a -> Ordering) -> Pipe a a m r
orderCheckPipe EigenstratSnpEntry -> EigenstratSnpEntry -> Ordering
compFunc3
Proxy X () () (EigenstratSnpEntry, GenoLine) m [()]
-> m (Proxy X () () (EigenstratSnpEntry, GenoLine) m [()])
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Proxy X () () (EigenstratSnpEntry, GenoLine) m [()]
-> m (Proxy X () () (EigenstratSnpEntry, GenoLine) m [()]))
-> Proxy X () () (EigenstratSnpEntry, GenoLine) m [()]
-> m (Proxy X () () (EigenstratSnpEntry, GenoLine) m [()])
forall a b. (a -> b) -> a -> b
$ ((EigenstratSnpEntry -> (EigenstratSnpEntry, GenoLine) -> Ordering)
-> Proxy X () () EigenstratSnpEntry m ()
-> Proxy X () () (EigenstratSnpEntry, GenoLine) m [()]
-> Producer
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
m
((), [()])
forall (m :: * -> *) a b r1 r2.
Monad m =>
(a -> b -> Ordering)
-> Producer a m r1
-> Producer b m r2
-> Producer (Maybe a, Maybe b) m (r1, r2)
orderedZip EigenstratSnpEntry -> (EigenstratSnpEntry, GenoLine) -> Ordering
compFunc2 Proxy X () () EigenstratSnpEntry m ()
snpProd Proxy X () () (EigenstratSnpEntry, GenoLine) m [()]
prod Producer
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
m
((), [()])
-> Proxy
X
()
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
m
[()]
-> Proxy
X
()
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
m
[()]
forall a b.
Proxy
X
()
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
m
a
-> Proxy
X
()
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
m
b
-> Proxy
X
()
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
m
b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [()]
-> Proxy
X
()
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
m
[()]
forall a.
a
-> Proxy
X
()
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
m
a
forall (m :: * -> *) a. Monad m => a -> m a
return [()]) Proxy
X
()
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
m
[()]
-> Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(EigenstratSnpEntry, GenoLine)
m
[()]
-> Proxy X () () (EigenstratSnpEntry, GenoLine) m [()]
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> Int
-> Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(EigenstratSnpEntry, GenoLine)
m
[()]
forall (m :: * -> *) r.
Monad m =>
Int
-> Pipe
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
(EigenstratSnpEntry, GenoLine)
m
r
selectSnps ([Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Int]
nrInds)
([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())
-> m ([EigenstratIndEntry],
Producer (EigenstratSnpEntry, GenoLine) m ())
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([EigenstratIndEntry]
jointIndEntries, Proxy X () () (EigenstratSnpEntry, GenoLine) m [()]
-> Producer (EigenstratSnpEntry, GenoLine) m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void Proxy X () () (EigenstratSnpEntry, GenoLine) m [()]
jointProducer)
where
compFunc :: (EigenstratSnpEntry, GenoLine) -> (EigenstratSnpEntry, GenoLine) -> Ordering
compFunc :: (EigenstratSnpEntry, GenoLine)
-> (EigenstratSnpEntry, GenoLine) -> Ordering
compFunc (EigenstratSnpEntry Chrom
c1 Int
p1 Double
_ ByteString
_ Char
_ Char
_, GenoLine
_) (EigenstratSnpEntry Chrom
c2 Int
p2 Double
_ ByteString
_ Char
_ Char
_, GenoLine
_) = (Chrom, Int) -> (Chrom, Int) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Chrom
c1, Int
p1) (Chrom
c2, Int
p2)
compFunc2 :: EigenstratSnpEntry -> (EigenstratSnpEntry, GenoLine) -> Ordering
compFunc2 :: EigenstratSnpEntry -> (EigenstratSnpEntry, GenoLine) -> Ordering
compFunc2 (EigenstratSnpEntry Chrom
c1 Int
p1 Double
_ ByteString
_ Char
_ Char
_) (EigenstratSnpEntry Chrom
c2 Int
p2 Double
_ ByteString
_ Char
_ Char
_, GenoLine
_) = (Chrom, Int) -> (Chrom, Int) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Chrom
c1, Int
p1) (Chrom
c2, Int
p2)
compFunc3 :: EigenstratSnpEntry -> EigenstratSnpEntry -> Ordering
compFunc3 :: EigenstratSnpEntry -> EigenstratSnpEntry -> Ordering
compFunc3 (EigenstratSnpEntry Chrom
c1 Int
p1 Double
_ ByteString
_ Char
_ Char
_) (EigenstratSnpEntry Chrom
c2 Int
p2 Double
_ ByteString
_ Char
_ Char
_) = (Chrom, Int) -> (Chrom, Int) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Chrom
c1, Int
p1) (Chrom
c2, Int
p2)
filterUnionOrIntersection :: [Maybe (EigenstratSnpEntry, GenoLine)] -> Bool
filterUnionOrIntersection :: [Maybe (EigenstratSnpEntry, GenoLine)] -> Bool
filterUnionOrIntersection [Maybe (EigenstratSnpEntry, GenoLine)]
maybeTuples = Bool -> Bool
not Bool
intersect Bool -> Bool -> Bool
|| Bool -> Bool
not ((Maybe (EigenstratSnpEntry, GenoLine) -> Bool)
-> [Maybe (EigenstratSnpEntry, GenoLine)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Maybe (EigenstratSnpEntry, GenoLine) -> Bool
forall a. Maybe a -> Bool
isNothing [Maybe (EigenstratSnpEntry, GenoLine)]
maybeTuples)
selectSnps :: (Monad m) => Int -> Pipe (Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine)) (EigenstratSnpEntry, GenoLine) m r
selectSnps :: forall (m :: * -> *) r.
Monad m =>
Int
-> Pipe
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
(EigenstratSnpEntry, GenoLine)
m
r
selectSnps Int
n = Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
m
r
-> ((Maybe EigenstratSnpEntry,
Maybe (EigenstratSnpEntry, GenoLine))
-> Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(EigenstratSnpEntry, GenoLine)
m
())
-> Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(EigenstratSnpEntry, GenoLine)
m
r
forall (m :: * -> *) x' x b' b a' c' c.
Functor m =>
Proxy x' x b' b m a'
-> (b -> Proxy x' x c' c m b') -> Proxy x' x c' c m a'
for Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
m
r
forall (m :: * -> *) a r. Functor m => Pipe a a m r
cat (((Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
-> Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(EigenstratSnpEntry, GenoLine)
m
())
-> Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(EigenstratSnpEntry, GenoLine)
m
r)
-> ((Maybe EigenstratSnpEntry,
Maybe (EigenstratSnpEntry, GenoLine))
-> Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(EigenstratSnpEntry, GenoLine)
m
())
-> Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(EigenstratSnpEntry, GenoLine)
m
r
forall a b. (a -> b) -> a -> b
$ \case
(Just EigenstratSnpEntry
_, Just (EigenstratSnpEntry
es, GenoLine
gl)) -> (EigenstratSnpEntry, GenoLine)
-> Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(EigenstratSnpEntry, GenoLine)
m
()
forall (m :: * -> *) a x' x. Functor m => a -> Proxy x' x () a m ()
yield (EigenstratSnpEntry
es, GenoLine
gl)
(Just EigenstratSnpEntry
snp, Maybe (EigenstratSnpEntry, GenoLine)
Nothing) -> Bool
-> Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(EigenstratSnpEntry, GenoLine)
m
()
-> Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(EigenstratSnpEntry, GenoLine)
m
()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
intersect (Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(EigenstratSnpEntry, GenoLine)
m
()
-> Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(EigenstratSnpEntry, GenoLine)
m
())
-> Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(EigenstratSnpEntry, GenoLine)
m
()
-> Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(EigenstratSnpEntry, GenoLine)
m
()
forall a b. (a -> b) -> a -> b
$ (EigenstratSnpEntry, GenoLine)
-> Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(EigenstratSnpEntry, GenoLine)
m
()
forall (m :: * -> *) a x' x. Functor m => a -> Proxy x' x () a m ()
yield (EigenstratSnpEntry
snp, Int -> GenoEntry -> GenoLine
forall a. Int -> a -> Vector a
V.replicate Int
n GenoEntry
Missing)
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
_ -> ()
-> Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(EigenstratSnpEntry, GenoLine)
m
()
forall a.
a
-> Proxy
()
(Maybe EigenstratSnpEntry, Maybe (EigenstratSnpEntry, GenoLine))
()
(EigenstratSnpEntry, GenoLine)
m
a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
getJointJanno :: [PoseidonPackage] -> JannoRows
getJointJanno :: [PoseidonPackage] -> JannoRows
getJointJanno [PoseidonPackage]
pacs = [JannoRows] -> JannoRows
forall a. Monoid a => [a] -> a
mconcat ([JannoRows] -> JannoRows) -> [JannoRows] -> JannoRows
forall a b. (a -> b) -> a -> b
$ (PoseidonPackage -> JannoRows) -> [PoseidonPackage] -> [JannoRows]
forall a b. (a -> b) -> [a] -> [b]
map PoseidonPackage -> JannoRows
posPacJanno [PoseidonPackage]
pacs
getJannoRowsFromPac :: PoseidonPackage -> [JannoRow]
getJannoRowsFromPac :: PoseidonPackage -> [JannoRow]
getJannoRowsFromPac PoseidonPackage
pac = let (JannoRows [JannoRow]
rows) = PoseidonPackage -> JannoRows
posPacJanno PoseidonPackage
pac in [JannoRow]
rows
joinEntryPipe :: (MonadIO m) => LogA -> [Int] -> [String] -> Pipe [Maybe (EigenstratSnpEntry, GenoLine)] (EigenstratSnpEntry, GenoLine) m r
joinEntryPipe :: forall (m :: * -> *) r.
MonadIO m =>
LogA
-> [Int]
-> [FilePath]
-> Pipe
[Maybe (EigenstratSnpEntry, GenoLine)]
(EigenstratSnpEntry, GenoLine)
m
r
joinEntryPipe LogA
logA [Int]
nrInds [FilePath]
pacNames = Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
[Maybe (EigenstratSnpEntry, GenoLine)]
m
r
-> ([Maybe (EigenstratSnpEntry, GenoLine)]
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
())
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
r
forall (m :: * -> *) x' x b' b a' c' c.
Functor m =>
Proxy x' x b' b m a'
-> (b -> Proxy x' x c' c m b') -> Proxy x' x c' c m a'
for Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
[Maybe (EigenstratSnpEntry, GenoLine)]
m
r
forall (m :: * -> *) a r. Functor m => Pipe a a m r
cat (([Maybe (EigenstratSnpEntry, GenoLine)]
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
())
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
r)
-> ([Maybe (EigenstratSnpEntry, GenoLine)]
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
())
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
r
forall a b. (a -> b) -> a -> b
$ \[Maybe (EigenstratSnpEntry, GenoLine)]
maybeEntries -> do
Either PoseidonException (EigenstratSnpEntry, GenoLine)
eitherJE <- IO (Either PoseidonException (EigenstratSnpEntry, GenoLine))
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
(Either PoseidonException (EigenstratSnpEntry, GenoLine))
forall a.
IO a
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Either PoseidonException (EigenstratSnpEntry, GenoLine))
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
(Either PoseidonException (EigenstratSnpEntry, GenoLine)))
-> (IO (EigenstratSnpEntry, GenoLine)
-> IO (Either PoseidonException (EigenstratSnpEntry, GenoLine)))
-> IO (EigenstratSnpEntry, GenoLine)
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
(Either PoseidonException (EigenstratSnpEntry, GenoLine))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (EigenstratSnpEntry, GenoLine)
-> IO (Either PoseidonException (EigenstratSnpEntry, GenoLine))
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> m (Either e a)
try (IO (EigenstratSnpEntry, GenoLine)
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
(Either PoseidonException (EigenstratSnpEntry, GenoLine)))
-> IO (EigenstratSnpEntry, GenoLine)
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
(Either PoseidonException (EigenstratSnpEntry, GenoLine))
forall a b. (a -> b) -> a -> b
$ LogA
-> [Int]
-> [FilePath]
-> [Maybe (EigenstratSnpEntry, GenoLine)]
-> IO (EigenstratSnpEntry, GenoLine)
forall (m :: * -> *).
MonadIO m =>
LogA
-> [Int]
-> [FilePath]
-> [Maybe (EigenstratSnpEntry, GenoLine)]
-> m (EigenstratSnpEntry, GenoLine)
joinEntries LogA
logA [Int]
nrInds [FilePath]
pacNames [Maybe (EigenstratSnpEntry, GenoLine)]
maybeEntries
case Either PoseidonException (EigenstratSnpEntry, GenoLine)
eitherJE of
Left (PoseidonGenotypeException FilePath
err) ->
LogA
-> PoseidonIO ()
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
()
forall (m :: * -> *). MonadIO m => LogA -> PoseidonIO () -> m ()
logWithEnv LogA
logA (PoseidonIO ()
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
())
-> (FilePath -> PoseidonIO ())
-> FilePath
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> PoseidonIO ()
logDebug (FilePath
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
())
-> FilePath
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
()
forall a b. (a -> b) -> a -> b
$ FilePath
"Skipping SNP due to " FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
err
Left PoseidonException
e -> IO ()
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
()
forall a.
IO a
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ()
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
())
-> (PoseidonException -> IO ())
-> PoseidonException
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PoseidonException -> IO ()
forall e a. Exception e => e -> IO a
throwIO (PoseidonException
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
())
-> PoseidonException
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
()
forall a b. (a -> b) -> a -> b
$ PoseidonException
e
Right (EigenstratSnpEntry
eigenstratSnpEntry, GenoLine
genoLine) -> (EigenstratSnpEntry, GenoLine)
-> Proxy
()
[Maybe (EigenstratSnpEntry, GenoLine)]
()
(EigenstratSnpEntry, GenoLine)
m
()
forall (m :: * -> *) a x' x. Functor m => a -> Proxy x' x () a m ()
yield (EigenstratSnpEntry
eigenstratSnpEntry, GenoLine
genoLine)
loadBimOrSnpFile :: (MonadSafe m) => FilePath -> Producer EigenstratSnpEntry m ()
loadBimOrSnpFile :: forall (m :: * -> *).
MonadSafe m =>
FilePath -> Producer EigenstratSnpEntry m ()
loadBimOrSnpFile FilePath
fn
| ShowS
takeExtension FilePath
fn FilePath -> [FilePath] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [FilePath
".snp", FilePath
".snp.gz"] = FilePath -> Producer EigenstratSnpEntry m ()
forall (m :: * -> *).
MonadSafe m =>
FilePath -> Producer EigenstratSnpEntry m ()
readEigenstratSnpFile FilePath
fn
| ShowS
takeExtension FilePath
fn FilePath -> [FilePath] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [FilePath
".bim", FilePath
".bim.gz"] = FilePath -> Producer EigenstratSnpEntry m ()
forall (m :: * -> *).
MonadSafe m =>
FilePath -> Producer EigenstratSnpEntry m ()
readBimFile FilePath
fn
| Bool
otherwise = PoseidonException -> Producer EigenstratSnpEntry m ()
forall e a.
Exception e =>
e -> Proxy X () () EigenstratSnpEntry m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (FilePath -> PoseidonException
PoseidonGenotypeException FilePath
"option snpFile requires file endings to be *.snp or *.bim or *.snp.gz or *.bim.gz")
newMinimalPackageTemplate :: FilePath -> String -> GenotypeDataSpec -> PoseidonPackage
newMinimalPackageTemplate :: FilePath -> FilePath -> GenotypeDataSpec -> PoseidonPackage
newMinimalPackageTemplate FilePath
baseDir FilePath
name (GenotypeDataSpec GenotypeFormatSpec
format_ FilePath
geno Maybe FilePath
_ FilePath
snp Maybe FilePath
_ FilePath
ind Maybe FilePath
_ Maybe SNPSetSpec
snpSet_) =
PoseidonPackage {
posPacBaseDir :: FilePath
posPacBaseDir = FilePath
baseDir
, posPacPoseidonVersion :: Version
posPacPoseidonVersion = PoseidonVersion -> Version
asVersion PoseidonVersion
latestPoseidonVersion
, posPacNameAndVersion :: PacNameAndVersion
posPacNameAndVersion = FilePath -> Maybe Version -> PacNameAndVersion
PacNameAndVersion FilePath
name Maybe Version
forall a. Maybe a
Nothing
, posPacDescription :: Maybe FilePath
posPacDescription = Maybe FilePath
forall a. Maybe a
Nothing
, posPacContributor :: [ContributorSpec]
posPacContributor = []
, posPacLastModified :: Maybe Day
posPacLastModified = Maybe Day
forall a. Maybe a
Nothing
, posPacGenotypeData :: GenotypeDataSpec
posPacGenotypeData = GenotypeFormatSpec
-> FilePath
-> Maybe FilePath
-> FilePath
-> Maybe FilePath
-> FilePath
-> Maybe FilePath
-> Maybe SNPSetSpec
-> GenotypeDataSpec
GenotypeDataSpec GenotypeFormatSpec
format_ (ShowS
takeFileName FilePath
geno) Maybe FilePath
forall a. Maybe a
Nothing (ShowS
takeFileName FilePath
snp) Maybe FilePath
forall a. Maybe a
Nothing (ShowS
takeFileName FilePath
ind) Maybe FilePath
forall a. Maybe a
Nothing Maybe SNPSetSpec
snpSet_
, posPacJannoFile :: Maybe FilePath
posPacJannoFile = Maybe FilePath
forall a. Maybe a
Nothing
, posPacJanno :: JannoRows
posPacJanno = JannoRows
forall a. Monoid a => a
mempty
, posPacJannoFileChkSum :: Maybe FilePath
posPacJannoFileChkSum = Maybe FilePath
forall a. Maybe a
Nothing
, posPacSeqSourceFile :: Maybe FilePath
posPacSeqSourceFile = Maybe FilePath
forall a. Maybe a
Nothing
, posPacSeqSource :: SeqSourceRows
posPacSeqSource = SeqSourceRows
forall a. Monoid a => a
mempty
, posPacSeqSourceFileChkSum :: Maybe FilePath
posPacSeqSourceFileChkSum = Maybe FilePath
forall a. Maybe a
Nothing
, posPacBibFile :: Maybe FilePath
posPacBibFile = Maybe FilePath
forall a. Maybe a
Nothing
, posPacBib :: BibTeX
posPacBib = [] :: BibTeX
, posPacBibFileChkSum :: Maybe FilePath
posPacBibFileChkSum = Maybe FilePath
forall a. Maybe a
Nothing
, posPacReadmeFile :: Maybe FilePath
posPacReadmeFile = Maybe FilePath
forall a. Maybe a
Nothing
, posPacChangelogFile :: Maybe FilePath
posPacChangelogFile = Maybe FilePath
forall a. Maybe a
Nothing
}
makePseudoPackageFromGenotypeData :: GenotypeDataSpec -> PoseidonIO PoseidonPackage
makePseudoPackageFromGenotypeData :: GenotypeDataSpec -> ReaderT Env IO PoseidonPackage
makePseudoPackageFromGenotypeData (GenotypeDataSpec GenotypeFormatSpec
format_ FilePath
genoFile_ Maybe FilePath
_ FilePath
snpFile_ Maybe FilePath
_ FilePath
indFile_ Maybe FilePath
_ Maybe SNPSetSpec
snpSet_) = do
let baseDir :: FilePath
baseDir = FilePath -> FilePath -> ShowS
getBaseDir FilePath
genoFile_ FilePath
snpFile_ FilePath
indFile_
outInd :: FilePath
outInd = ShowS
takeFileName FilePath
indFile_
outSnp :: FilePath
outSnp = ShowS
takeFileName FilePath
snpFile_
outGeno :: FilePath
outGeno = ShowS
takeFileName FilePath
genoFile_
genotypeData :: GenotypeDataSpec
genotypeData = GenotypeFormatSpec
-> FilePath
-> Maybe FilePath
-> FilePath
-> Maybe FilePath
-> FilePath
-> Maybe FilePath
-> Maybe SNPSetSpec
-> GenotypeDataSpec
GenotypeDataSpec GenotypeFormatSpec
format_ FilePath
outGeno Maybe FilePath
forall a. Maybe a
Nothing FilePath
outSnp Maybe FilePath
forall a. Maybe a
Nothing FilePath
outInd Maybe FilePath
forall a. Maybe a
Nothing Maybe SNPSetSpec
snpSet_
pacName :: FilePath
pacName = ShowS
takeBaseName FilePath
genoFile_
[EigenstratIndEntry]
inds <- FilePath -> GenotypeDataSpec -> PoseidonIO [EigenstratIndEntry]
loadIndividuals FilePath
baseDir GenotypeDataSpec
genotypeData
FilePath
-> FilePath
-> GenotypeDataSpec
-> Maybe (Either [EigenstratIndEntry] JannoRows)
-> SeqSourceRows
-> BibTeX
-> ReaderT Env IO PoseidonPackage
newPackageTemplate FilePath
baseDir FilePath
pacName GenotypeDataSpec
genotypeData (Either [EigenstratIndEntry] JannoRows
-> Maybe (Either [EigenstratIndEntry] JannoRows)
forall a. a -> Maybe a
Just ([EigenstratIndEntry] -> Either [EigenstratIndEntry] JannoRows
forall a b. a -> Either a b
Left [EigenstratIndEntry]
inds)) SeqSourceRows
forall a. Monoid a => a
mempty []
where
getBaseDir :: FilePath -> FilePath -> FilePath -> FilePath
getBaseDir :: FilePath -> FilePath -> ShowS
getBaseDir FilePath
g FilePath
s FilePath
i =
let baseDirGeno :: FilePath
baseDirGeno = ShowS
takeDirectory FilePath
genoFile_
baseDirSnp :: FilePath
baseDirSnp = ShowS
takeDirectory FilePath
snpFile_
baseDirInd :: FilePath
baseDirInd = ShowS
takeDirectory FilePath
indFile_
in if FilePath
baseDirGeno FilePath -> FilePath -> Bool
forall a. Eq a => a -> a -> Bool
== FilePath
baseDirSnp Bool -> Bool -> Bool
&& FilePath
baseDirSnp FilePath -> FilePath -> Bool
forall a. Eq a => a -> a -> Bool
== FilePath
baseDirInd
then FilePath
baseDirGeno
else PoseidonException -> FilePath
forall e a. Exception e => e -> [a]
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (PoseidonException -> FilePath) -> PoseidonException -> FilePath
forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath -> FilePath -> PoseidonException
PoseidonUnequalBaseDirException FilePath
g FilePath
s FilePath
i
newPackageTemplate ::
FilePath
-> String
-> GenotypeDataSpec
-> Maybe (Either [EigenstratIndEntry] JannoRows)
-> SeqSourceRows
-> BibTeX
-> PoseidonIO PoseidonPackage
newPackageTemplate :: FilePath
-> FilePath
-> GenotypeDataSpec
-> Maybe (Either [EigenstratIndEntry] JannoRows)
-> SeqSourceRows
-> BibTeX
-> ReaderT Env IO PoseidonPackage
newPackageTemplate FilePath
baseDir FilePath
name GenotypeDataSpec
genoData Maybe (Either [EigenstratIndEntry] JannoRows)
indsOrJanno SeqSourceRows
seqSource BibTeX
bib = do
(UTCTime Day
today DiffTime
_) <- IO UTCTime -> ReaderT Env IO UTCTime
forall a. IO a -> ReaderT Env IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO UTCTime
getCurrentTime
let minimalTemplate :: PoseidonPackage
minimalTemplate = FilePath -> FilePath -> GenotypeDataSpec -> PoseidonPackage
newMinimalPackageTemplate FilePath
baseDir FilePath
name GenotypeDataSpec
genoData
fluffedUpTemplate :: PoseidonPackage
fluffedUpTemplate = PoseidonPackage
minimalTemplate {
posPacDescription :: Maybe FilePath
posPacDescription = FilePath -> Maybe FilePath
forall a. a -> Maybe a
Just FilePath
"Empty package template. Please add a description"
, posPacContributor :: [ContributorSpec]
posPacContributor = []
, posPacNameAndVersion :: PacNameAndVersion
posPacNameAndVersion = FilePath -> Maybe Version -> PacNameAndVersion
PacNameAndVersion FilePath
name (Version -> Maybe Version
forall a. a -> Maybe a
Just (Version -> Maybe Version) -> Version -> Maybe Version
forall a b. (a -> b) -> a -> b
$ [Int] -> Version
makeVersion [Int
0, Int
1, Int
0])
, posPacLastModified :: Maybe Day
posPacLastModified = Day -> Maybe Day
forall a. a -> Maybe a
Just Day
today
}
jannoFilledTemplate :: PoseidonPackage
jannoFilledTemplate = FilePath
-> Maybe (Either [EigenstratIndEntry] JannoRows)
-> PoseidonPackage
-> PoseidonPackage
completeJannoSpec FilePath
name Maybe (Either [EigenstratIndEntry] JannoRows)
indsOrJanno PoseidonPackage
fluffedUpTemplate
seqSourceFilledTemplate :: PoseidonPackage
seqSourceFilledTemplate = FilePath -> SeqSourceRows -> PoseidonPackage -> PoseidonPackage
completeSeqSourceSpec FilePath
name SeqSourceRows
seqSource PoseidonPackage
jannoFilledTemplate
bibFilledTemplate :: PoseidonPackage
bibFilledTemplate = FilePath -> BibTeX -> PoseidonPackage -> PoseidonPackage
completeBibSpec FilePath
name BibTeX
bib PoseidonPackage
seqSourceFilledTemplate
PoseidonPackage -> ReaderT Env IO PoseidonPackage
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return PoseidonPackage
bibFilledTemplate
where
completeJannoSpec :: FilePath
-> Maybe (Either [EigenstratIndEntry] JannoRows)
-> PoseidonPackage
-> PoseidonPackage
completeJannoSpec FilePath
_ Maybe (Either [EigenstratIndEntry] JannoRows)
Nothing PoseidonPackage
inTemplate = PoseidonPackage
inTemplate
completeJannoSpec FilePath
name_ (Just (Left [EigenstratIndEntry]
a)) PoseidonPackage
inTemplate =
PoseidonPackage
inTemplate {
posPacJannoFile :: Maybe FilePath
posPacJannoFile = FilePath -> Maybe FilePath
forall a. a -> Maybe a
Just (FilePath -> Maybe FilePath) -> FilePath -> Maybe FilePath
forall a b. (a -> b) -> a -> b
$ FilePath
name_ FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
".janno",
posPacJanno :: JannoRows
posPacJanno = [EigenstratIndEntry] -> JannoRows
createMinimalJanno [EigenstratIndEntry]
a
}
completeJannoSpec FilePath
name_ (Just (Right JannoRows
b)) PoseidonPackage
inTemplate =
PoseidonPackage
inTemplate {
posPacJannoFile :: Maybe FilePath
posPacJannoFile = FilePath -> Maybe FilePath
forall a. a -> Maybe a
Just (FilePath -> Maybe FilePath) -> FilePath -> Maybe FilePath
forall a b. (a -> b) -> a -> b
$ FilePath
name_ FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
".janno",
posPacJanno :: JannoRows
posPacJanno = JannoRows
b
}
completeSeqSourceSpec :: FilePath -> SeqSourceRows -> PoseidonPackage -> PoseidonPackage
completeSeqSourceSpec FilePath
_ (SeqSourceRows []) PoseidonPackage
inTemplate = PoseidonPackage
inTemplate
completeSeqSourceSpec FilePath
name_ SeqSourceRows
xs PoseidonPackage
inTemplate =
PoseidonPackage
inTemplate {
posPacSeqSourceFile :: Maybe FilePath
posPacSeqSourceFile = FilePath -> Maybe FilePath
forall a. a -> Maybe a
Just (FilePath -> Maybe FilePath) -> FilePath -> Maybe FilePath
forall a b. (a -> b) -> a -> b
$ FilePath
name_ FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
".ssf",
posPacSeqSource :: SeqSourceRows
posPacSeqSource = SeqSourceRows
xs
}
completeBibSpec :: FilePath -> BibTeX -> PoseidonPackage -> PoseidonPackage
completeBibSpec FilePath
_ [] PoseidonPackage
inTemplate = PoseidonPackage
inTemplate
completeBibSpec FilePath
name_ BibTeX
xs PoseidonPackage
inTemplate =
PoseidonPackage
inTemplate {
posPacBibFile :: Maybe FilePath
posPacBibFile = FilePath -> Maybe FilePath
forall a. a -> Maybe a
Just (FilePath -> Maybe FilePath) -> FilePath -> Maybe FilePath
forall a b. (a -> b) -> a -> b
$ FilePath
name_ FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
".bib",
posPacBib :: BibTeX
posPacBib = BibTeX
xs
}
writePoseidonPackage :: PoseidonPackage -> IO ()
writePoseidonPackage :: PoseidonPackage -> IO ()
writePoseidonPackage (PoseidonPackage FilePath
baseDir Version
ver PacNameAndVersion
nameAndVer Maybe FilePath
des [ContributorSpec]
con Maybe Day
mod_ GenotypeDataSpec
geno Maybe FilePath
jannoF JannoRows
_ Maybe FilePath
jannoC Maybe FilePath
seqSourceF SeqSourceRows
_ Maybe FilePath
seqSourceC Maybe FilePath
bibF BibTeX
_ Maybe FilePath
bibFC Maybe FilePath
readF Maybe FilePath
changeF) = do
let yamlPac :: PoseidonYamlStruct
yamlPac = Version
-> FilePath
-> Maybe FilePath
-> [ContributorSpec]
-> Maybe Version
-> Maybe Day
-> GenotypeDataSpec
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> Maybe FilePath
-> PoseidonYamlStruct
PoseidonYamlStruct Version
ver (PacNameAndVersion -> FilePath
forall a. HasNameAndVersion a => a -> FilePath
getPacName PacNameAndVersion
nameAndVer) Maybe FilePath
des [ContributorSpec]
con (PacNameAndVersion -> Maybe Version
forall a. HasNameAndVersion a => a -> Maybe Version
getPacVersion PacNameAndVersion
nameAndVer) Maybe Day
mod_ GenotypeDataSpec
geno Maybe FilePath
jannoF Maybe FilePath
jannoC Maybe FilePath
seqSourceF Maybe FilePath
seqSourceC Maybe FilePath
bibF Maybe FilePath
bibFC Maybe FilePath
readF Maybe FilePath
changeF
outF :: FilePath
outF = FilePath
baseDir FilePath -> ShowS
</> FilePath
"POSEIDON.yml"
FilePath -> ByteString -> IO ()
B.writeFile FilePath
outF (ByteString -> IO ()) -> ByteString -> IO ()
forall a b. NFData a => (a -> b) -> a -> b
$!! Config -> PoseidonYamlStruct -> ByteString
forall a. ToJSON a => Config -> a -> ByteString
encodePretty Config
opts PoseidonYamlStruct
yamlPac
where
opts :: Config
opts = Bool -> Config -> Config
setConfDropNull Bool
True (Config -> Config) -> Config -> Config
forall a b. (a -> b) -> a -> b
$ (Text -> Text -> Ordering) -> Config -> Config
setConfCompare (Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Int -> Int -> Ordering)
-> (Text -> Int) -> Text -> Text -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Text -> Int
fieldIndex) Config
defConfig
fieldIndex :: Text -> Int
fieldIndex Text
s = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe ([Text] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Text]
fields) (Maybe Int -> Int) -> Maybe Int -> Int
forall a b. (a -> b) -> a -> b
$ Text
s Text -> [Text] -> Maybe Int
forall a. Eq a => a -> [a] -> Maybe Int
`elemIndex` [Text]
fields
fields :: [Text]
fields = [
Text
"poseidonVersion",
Text
"title",
Text
"description",
Text
"contributor",
Text
"name",
Text
"email",
Text
"orcid",
Text
"packageVersion",
Text
"lastModified",
Text
"genotypeData",
Text
"format",
Text
"genoFile",
Text
"genoFileChkSum",
Text
"snpFile",
Text
"snpFileChkSum",
Text
"indFile",
Text
"indFileChkSum",
Text
"snpSet",
Text
"jannoFile",
Text
"jannoFileChkSum",
Text
"sequencingSourceFile",
Text
"sequencingSourceFileChkSum",
Text
"bibFile",
Text
"bibFileChkSum",
Text
"readmeFile",
Text
"changelogFile"
]
packagesToPackageInfos :: (MonadThrow m) => [PoseidonPackage] -> m [PackageInfo]
packagesToPackageInfos :: forall (m :: * -> *).
MonadThrow m =>
[PoseidonPackage] -> m [PackageInfo]
packagesToPackageInfos [PoseidonPackage]
pacs = do
[PoseidonPackage]
-> (PoseidonPackage -> m PackageInfo) -> m [PackageInfo]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [PoseidonPackage]
pacs ((PoseidonPackage -> m PackageInfo) -> m [PackageInfo])
-> (PoseidonPackage -> m PackageInfo) -> m [PackageInfo]
forall a b. (a -> b) -> a -> b
$ \PoseidonPackage
pac -> do
Bool
isLatest <- [PoseidonPackage] -> PoseidonPackage -> m Bool
forall (m :: * -> *) a.
(MonadThrow m, HasNameAndVersion a) =>
[a] -> a -> m Bool
isLatestInCollection [PoseidonPackage]
pacs PoseidonPackage
pac
PackageInfo -> m PackageInfo
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (PackageInfo -> m PackageInfo) -> PackageInfo -> m PackageInfo
forall a b. (a -> b) -> a -> b
$ PackageInfo {
pPac :: PacNameAndVersion
pPac = PoseidonPackage -> PacNameAndVersion
posPacNameAndVersion PoseidonPackage
pac,
pIsLatest :: Bool
pIsLatest = Bool
isLatest,
pPosVersion :: Version
pPosVersion = PoseidonPackage -> Version
posPacPoseidonVersion PoseidonPackage
pac,
pDescription :: Maybe FilePath
pDescription = PoseidonPackage -> Maybe FilePath
posPacDescription PoseidonPackage
pac,
pLastModified :: Maybe Day
pLastModified = PoseidonPackage -> Maybe Day
posPacLastModified PoseidonPackage
pac,
pNrIndividuals :: Int
pNrIndividuals = ([JannoRow] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([JannoRow] -> Int)
-> (PoseidonPackage -> [JannoRow]) -> PoseidonPackage -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PoseidonPackage -> [JannoRow]
getJannoRowsFromPac) PoseidonPackage
pac
}
getAllGroupInfo :: (MonadThrow m) => [PoseidonPackage] -> m [GroupInfo]
getAllGroupInfo :: forall (m :: * -> *).
MonadThrow m =>
[PoseidonPackage] -> m [GroupInfo]
getAllGroupInfo [PoseidonPackage]
packages = do
let individualInfoUnnested :: [(FilePath, PacNameAndVersion)]
individualInfoUnnested = do
PoseidonPackage
pac <- [PoseidonPackage]
packages
JannoRow
jannoRow <- PoseidonPackage -> [JannoRow]
getJannoRowsFromPac PoseidonPackage
pac
let groups :: [FilePath]
groups = JannoList FilePath -> [FilePath]
forall a. JannoList a -> [a]
getJannoList (JannoList FilePath -> [FilePath])
-> (JannoRow -> JannoList FilePath) -> JannoRow -> [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JannoRow -> JannoList FilePath
jGroupName (JannoRow -> [FilePath]) -> JannoRow -> [FilePath]
forall a b. (a -> b) -> a -> b
$ JannoRow
jannoRow
[(FilePath
g, PoseidonPackage -> PacNameAndVersion
forall a. HasNameAndVersion a => a -> PacNameAndVersion
makePacNameAndVersion PoseidonPackage
pac) | FilePath
g <- [FilePath]
groups]
[[(FilePath, PacNameAndVersion)]]
-> ([(FilePath, PacNameAndVersion)] -> m GroupInfo)
-> m [GroupInfo]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM (([(FilePath, PacNameAndVersion)]
-> [[(FilePath, PacNameAndVersion)]]
forall a. Eq a => [a] -> [[a]]
group ([(FilePath, PacNameAndVersion)]
-> [[(FilePath, PacNameAndVersion)]])
-> ([(FilePath, PacNameAndVersion)]
-> [(FilePath, PacNameAndVersion)])
-> [(FilePath, PacNameAndVersion)]
-> [[(FilePath, PacNameAndVersion)]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(FilePath, PacNameAndVersion)] -> [(FilePath, PacNameAndVersion)]
forall a. Ord a => [a] -> [a]
sort) [(FilePath, PacNameAndVersion)]
individualInfoUnnested) (([(FilePath, PacNameAndVersion)] -> m GroupInfo) -> m [GroupInfo])
-> ([(FilePath, PacNameAndVersion)] -> m GroupInfo)
-> m [GroupInfo]
forall a b. (a -> b) -> a -> b
$ \[(FilePath, PacNameAndVersion)]
group_ -> do
let groupName :: FilePath
groupName = [FilePath] -> FilePath
forall a. HasCallStack => [a] -> a
head ([FilePath] -> FilePath)
-> ([(FilePath, PacNameAndVersion)] -> [FilePath])
-> [(FilePath, PacNameAndVersion)]
-> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((FilePath, PacNameAndVersion) -> FilePath)
-> [(FilePath, PacNameAndVersion)] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath, PacNameAndVersion) -> FilePath
forall a b. (a, b) -> a
fst ([(FilePath, PacNameAndVersion)] -> FilePath)
-> [(FilePath, PacNameAndVersion)] -> FilePath
forall a b. (a -> b) -> a -> b
$ [(FilePath, PacNameAndVersion)]
group_
groupPac :: PacNameAndVersion
groupPac = [PacNameAndVersion] -> PacNameAndVersion
forall a. HasCallStack => [a] -> a
head ([PacNameAndVersion] -> PacNameAndVersion)
-> ([(FilePath, PacNameAndVersion)] -> [PacNameAndVersion])
-> [(FilePath, PacNameAndVersion)]
-> PacNameAndVersion
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((FilePath, PacNameAndVersion) -> PacNameAndVersion)
-> [(FilePath, PacNameAndVersion)] -> [PacNameAndVersion]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath, PacNameAndVersion) -> PacNameAndVersion
forall a b. (a, b) -> b
snd ([(FilePath, PacNameAndVersion)] -> PacNameAndVersion)
-> [(FilePath, PacNameAndVersion)] -> PacNameAndVersion
forall a b. (a -> b) -> a -> b
$ [(FilePath, PacNameAndVersion)]
group_
groupNrInds :: Int
groupNrInds = [(FilePath, PacNameAndVersion)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(FilePath, PacNameAndVersion)]
group_
Bool
isLatest <- [PacNameAndVersion] -> PacNameAndVersion -> m Bool
forall (m :: * -> *) a.
(MonadThrow m, HasNameAndVersion a) =>
[a] -> a -> m Bool
isLatestInCollection ((PoseidonPackage -> PacNameAndVersion)
-> [PoseidonPackage] -> [PacNameAndVersion]
forall a b. (a -> b) -> [a] -> [b]
map PoseidonPackage -> PacNameAndVersion
forall a. HasNameAndVersion a => a -> PacNameAndVersion
makePacNameAndVersion [PoseidonPackage]
packages) PacNameAndVersion
groupPac
GroupInfo -> m GroupInfo
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (GroupInfo -> m GroupInfo) -> GroupInfo -> m GroupInfo
forall a b. (a -> b) -> a -> b
$ FilePath -> PacNameAndVersion -> Bool -> Int -> GroupInfo
GroupInfo FilePath
groupName PacNameAndVersion
groupPac Bool
isLatest Int
groupNrInds
getJointIndividualInfo :: (MonadThrow m) => [PoseidonPackage] -> m IndividualInfoCollection
getJointIndividualInfo :: forall (m :: * -> *).
MonadThrow m =>
[PoseidonPackage] -> m IndividualInfoCollection
getJointIndividualInfo [PoseidonPackage]
packages = do
[[(IndividualInfo, Bool)]]
indInfoLatestPairs <- [PoseidonPackage]
-> (PoseidonPackage -> m [(IndividualInfo, Bool)])
-> m [[(IndividualInfo, Bool)]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [PoseidonPackage]
packages ((PoseidonPackage -> m [(IndividualInfo, Bool)])
-> m [[(IndividualInfo, Bool)]])
-> (PoseidonPackage -> m [(IndividualInfo, Bool)])
-> m [[(IndividualInfo, Bool)]]
forall a b. (a -> b) -> a -> b
$ \PoseidonPackage
pac -> do
Bool
isLatest <- [PoseidonPackage] -> PoseidonPackage -> m Bool
forall (m :: * -> *) a.
(MonadThrow m, HasNameAndVersion a) =>
[a] -> a -> m Bool
isLatestInCollection [PoseidonPackage]
packages PoseidonPackage
pac
[JannoRow]
-> (JannoRow -> m (IndividualInfo, Bool))
-> m [(IndividualInfo, Bool)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM (PoseidonPackage -> [JannoRow]
getJannoRowsFromPac PoseidonPackage
pac) ((JannoRow -> m (IndividualInfo, Bool))
-> m [(IndividualInfo, Bool)])
-> (JannoRow -> m (IndividualInfo, Bool))
-> m [(IndividualInfo, Bool)]
forall a b. (a -> b) -> a -> b
$ \JannoRow
jannoRow -> do
let indInfo :: IndividualInfo
indInfo = FilePath -> [FilePath] -> PacNameAndVersion -> IndividualInfo
IndividualInfo
(JannoRow -> FilePath
jPoseidonID JannoRow
jannoRow)
((JannoList FilePath -> [FilePath]
forall a. JannoList a -> [a]
getJannoList (JannoList FilePath -> [FilePath])
-> (JannoRow -> JannoList FilePath) -> JannoRow -> [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JannoRow -> JannoList FilePath
jGroupName) JannoRow
jannoRow)
(PoseidonPackage -> PacNameAndVersion
forall a. HasNameAndVersion a => a -> PacNameAndVersion
makePacNameAndVersion PoseidonPackage
pac)
(IndividualInfo, Bool) -> m (IndividualInfo, Bool)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (IndividualInfo
indInfo, Bool
isLatest)
IndividualInfoCollection -> m IndividualInfoCollection
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (((IndividualInfo, Bool) -> IndividualInfo)
-> [(IndividualInfo, Bool)] -> [IndividualInfo]
forall a b. (a -> b) -> [a] -> [b]
map (IndividualInfo, Bool) -> IndividualInfo
forall a b. (a, b) -> a
fst ([(IndividualInfo, Bool)] -> [IndividualInfo])
-> ([[(IndividualInfo, Bool)]] -> [(IndividualInfo, Bool)])
-> [[(IndividualInfo, Bool)]]
-> [IndividualInfo]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[(IndividualInfo, Bool)]] -> [(IndividualInfo, Bool)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[(IndividualInfo, Bool)]] -> [IndividualInfo])
-> [[(IndividualInfo, Bool)]] -> [IndividualInfo]
forall a b. (a -> b) -> a -> b
$ [[(IndividualInfo, Bool)]]
indInfoLatestPairs, ((IndividualInfo, Bool) -> Bool)
-> [(IndividualInfo, Bool)] -> [Bool]
forall a b. (a -> b) -> [a] -> [b]
map (IndividualInfo, Bool) -> Bool
forall a b. (a, b) -> b
snd ([(IndividualInfo, Bool)] -> [Bool])
-> ([[(IndividualInfo, Bool)]] -> [(IndividualInfo, Bool)])
-> [[(IndividualInfo, Bool)]]
-> [Bool]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[(IndividualInfo, Bool)]] -> [(IndividualInfo, Bool)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[(IndividualInfo, Bool)]] -> [Bool])
-> [[(IndividualInfo, Bool)]] -> [Bool]
forall a b. (a -> b) -> a -> b
$ [[(IndividualInfo, Bool)]]
indInfoLatestPairs)
getExtendedIndividualInfo :: (MonadThrow m) => [PoseidonPackage] -> AddJannoColSpec -> m [ExtendedIndividualInfo]
getExtendedIndividualInfo :: forall (m :: * -> *).
MonadThrow m =>
[PoseidonPackage] -> AddJannoColSpec -> m [ExtendedIndividualInfo]
getExtendedIndividualInfo [PoseidonPackage]
allPackages AddJannoColSpec
addJannoColSpec = [m ExtendedIndividualInfo] -> m [ExtendedIndividualInfo]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence ([m ExtendedIndividualInfo] -> m [ExtendedIndividualInfo])
-> [m ExtendedIndividualInfo] -> m [ExtendedIndividualInfo]
forall a b. (a -> b) -> a -> b
$ do
PoseidonPackage
pac <- [PoseidonPackage]
allPackages
JannoRow
jannoRow <- PoseidonPackage -> [JannoRow]
getJannoRowsFromPac PoseidonPackage
pac
let name :: FilePath
name = JannoRow -> FilePath
jPoseidonID JannoRow
jannoRow
groups :: [FilePath]
groups = JannoList FilePath -> [FilePath]
forall a. JannoList a -> [a]
getJannoList (JannoList FilePath -> [FilePath])
-> (JannoRow -> JannoList FilePath) -> JannoRow -> [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JannoRow -> JannoList FilePath
jGroupName (JannoRow -> [FilePath]) -> JannoRow -> [FilePath]
forall a b. (a -> b) -> a -> b
$ JannoRow
jannoRow
colNames :: [FilePath]
colNames = case AddJannoColSpec
addJannoColSpec of
AddJannoColSpec
AddJannoColAll -> [FilePath]
jannoHeaderString [FilePath] -> [FilePath] -> [FilePath]
forall a. Eq a => [a] -> [a] -> [a]
\\ [FilePath
"Poseidon_ID", FilePath
"Group_Name"]
AddJannoColList [FilePath]
c -> [FilePath]
c
additionalColumnEntries :: [(FilePath, Maybe FilePath)]
additionalColumnEntries = [(FilePath
k, ByteString -> FilePath
BSC.unpack (ByteString -> FilePath) -> Maybe ByteString -> Maybe FilePath
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> JannoRow -> NamedRecord
forall a. ToNamedRecord a => a -> NamedRecord
toNamedRecord JannoRow
jannoRow NamedRecord -> ByteString -> Maybe ByteString
forall k v. (Eq k, Hashable k) => HashMap k v -> k -> Maybe v
HM.!? FilePath -> ByteString
BSC.pack FilePath
k) | FilePath
k <- [FilePath]
colNames]
Bool
isLatest <- [PoseidonPackage] -> PoseidonPackage -> [Bool]
forall (m :: * -> *) a.
(MonadThrow m, HasNameAndVersion a) =>
[a] -> a -> m Bool
isLatestInCollection [PoseidonPackage]
allPackages PoseidonPackage
pac
m ExtendedIndividualInfo -> [m ExtendedIndividualInfo]
forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return (m ExtendedIndividualInfo -> [m ExtendedIndividualInfo])
-> (ExtendedIndividualInfo -> m ExtendedIndividualInfo)
-> ExtendedIndividualInfo
-> [m ExtendedIndividualInfo]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExtendedIndividualInfo -> m ExtendedIndividualInfo
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (ExtendedIndividualInfo -> [m ExtendedIndividualInfo])
-> ExtendedIndividualInfo -> [m ExtendedIndividualInfo]
forall a b. (a -> b) -> a -> b
$ FilePath
-> [FilePath]
-> PacNameAndVersion
-> Bool
-> [(FilePath, Maybe FilePath)]
-> ExtendedIndividualInfo
ExtendedIndividualInfo FilePath
name [FilePath]
groups (PoseidonPackage -> PacNameAndVersion
forall a. HasNameAndVersion a => a -> PacNameAndVersion
makePacNameAndVersion PoseidonPackage
pac) Bool
isLatest [(FilePath, Maybe FilePath)]
additionalColumnEntries
filterToRelevantPackages :: (MonadThrow m) => (EntitySpec a) => [a] -> [PoseidonPackage] -> m [PoseidonPackage]
filterToRelevantPackages :: forall (m :: * -> *) a.
(MonadThrow m, EntitySpec a) =>
[a] -> [PoseidonPackage] -> m [PoseidonPackage]
filterToRelevantPackages [a]
entities [PoseidonPackage]
packages = do
IndividualInfoCollection
indInfoCollection <- [PoseidonPackage] -> m IndividualInfoCollection
forall (m :: * -> *).
MonadThrow m =>
[PoseidonPackage] -> m IndividualInfoCollection
getJointIndividualInfo [PoseidonPackage]
packages
[PacNameAndVersion]
relevantPacs <- [a] -> IndividualInfoCollection -> m [PacNameAndVersion]
forall (m :: * -> *) a.
(MonadThrow m, EntitySpec a) =>
[a] -> IndividualInfoCollection -> m [PacNameAndVersion]
determineRelevantPackages [a]
entities IndividualInfoCollection
indInfoCollection
[PoseidonPackage] -> m [PoseidonPackage]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([PoseidonPackage] -> m [PoseidonPackage])
-> [PoseidonPackage] -> m [PoseidonPackage]
forall a b. (a -> b) -> a -> b
$ (PoseidonPackage -> Bool) -> [PoseidonPackage] -> [PoseidonPackage]
forall a. (a -> Bool) -> [a] -> [a]
filter (\PoseidonPackage
p -> PoseidonPackage -> PacNameAndVersion
forall a. HasNameAndVersion a => a -> PacNameAndVersion
makePacNameAndVersion PoseidonPackage
p PacNameAndVersion -> [PacNameAndVersion] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [PacNameAndVersion]
relevantPacs) [PoseidonPackage]
packages