{-# LANGUAGE DeriveGeneric       #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Poseidon.SequencingSource where

import           Poseidon.Janno             (CsvNamedRecord (..),
                                             JannoStringList, ListColumn (..),
                                             decodingOptions, encodingOptions,
                                             explicitNA, filterLookup,
                                             filterLookupOptional, getCsvNR,
                                             parseCsvParseError,
                                             removeUselessSuffix,
                                             renderCsvParseError)
import           Poseidon.Utils             (PoseidonException (..), PoseidonIO,
                                             logDebug, logError, logWarning,
                                             renderPoseidonException)

import           Control.Exception          (throwIO)
import           Control.Monad              (unless, when)
import           Control.Monad.IO.Class     (liftIO)
import           Data.Bifunctor             (second)
import qualified Data.ByteString.Char8      as Bchs
import qualified Data.ByteString.Lazy.Char8 as Bch
import           Data.Char                  (isHexDigit)
import qualified Data.Csv                   as Csv
import           Data.Either                (lefts, rights)
import qualified Data.HashMap.Strict        as HM
import           Data.List                  (foldl', nub, sort)
import           Data.Maybe                 (isJust, mapMaybe)
import           Data.Time                  (Day)
import           Data.Time.Format           (defaultTimeLocale, formatTime,
                                             parseTimeM)
import qualified Data.Vector                as V
import           GHC.Generics               (Generic)
import           Network.URI                (isURIReference)
import qualified Text.Parsec                as P
import qualified Text.Regex.TDFA            as Reg

-- |A datatype to represent AccessionIDs in a ssf file
data AccessionID =
      INSDCProject String
    | INSDCStudy String
    | INSDCBioSample String
    | INSDCSample String
    | INSDCExperiment String
    | INSDCRun String
    | INSDCAnalysis String
    | OtherID String
    deriving (AccessionID -> AccessionID -> Bool
(AccessionID -> AccessionID -> Bool)
-> (AccessionID -> AccessionID -> Bool) -> Eq AccessionID
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: AccessionID -> AccessionID -> Bool
== :: AccessionID -> AccessionID -> Bool
$c/= :: AccessionID -> AccessionID -> Bool
/= :: AccessionID -> AccessionID -> Bool
Eq, Eq AccessionID
Eq AccessionID
-> (AccessionID -> AccessionID -> Ordering)
-> (AccessionID -> AccessionID -> Bool)
-> (AccessionID -> AccessionID -> Bool)
-> (AccessionID -> AccessionID -> Bool)
-> (AccessionID -> AccessionID -> Bool)
-> (AccessionID -> AccessionID -> AccessionID)
-> (AccessionID -> AccessionID -> AccessionID)
-> Ord AccessionID
AccessionID -> AccessionID -> Bool
AccessionID -> AccessionID -> Ordering
AccessionID -> AccessionID -> AccessionID
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: AccessionID -> AccessionID -> Ordering
compare :: AccessionID -> AccessionID -> Ordering
$c< :: AccessionID -> AccessionID -> Bool
< :: AccessionID -> AccessionID -> Bool
$c<= :: AccessionID -> AccessionID -> Bool
<= :: AccessionID -> AccessionID -> Bool
$c> :: AccessionID -> AccessionID -> Bool
> :: AccessionID -> AccessionID -> Bool
$c>= :: AccessionID -> AccessionID -> Bool
>= :: AccessionID -> AccessionID -> Bool
$cmax :: AccessionID -> AccessionID -> AccessionID
max :: AccessionID -> AccessionID -> AccessionID
$cmin :: AccessionID -> AccessionID -> AccessionID
min :: AccessionID -> AccessionID -> AccessionID
Ord, (forall x. AccessionID -> Rep AccessionID x)
-> (forall x. Rep AccessionID x -> AccessionID)
-> Generic AccessionID
forall x. Rep AccessionID x -> AccessionID
forall x. AccessionID -> Rep AccessionID x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. AccessionID -> Rep AccessionID x
from :: forall x. AccessionID -> Rep AccessionID x
$cto :: forall x. Rep AccessionID x -> AccessionID
to :: forall x. Rep AccessionID x -> AccessionID
Generic)

instance Show AccessionID where
    show :: AccessionID -> [Char]
show (INSDCProject [Char]
x)    = [Char]
x
    show (INSDCStudy [Char]
x)      = [Char]
x
    show (INSDCBioSample [Char]
x)  = [Char]
x
    show (INSDCSample [Char]
x)     = [Char]
x
    show (INSDCExperiment [Char]
x) = [Char]
x
    show (INSDCRun [Char]
x)        = [Char]
x
    show (INSDCAnalysis [Char]
x)   = [Char]
x
    show (OtherID [Char]
x)         = [Char]
x

-- the patterns are documented at:
-- https://ena-docs.readthedocs.io/en/latest/submit/general-guide/accessions.html
makeAccessionID :: MonadFail m => String -> m AccessionID
makeAccessionID :: forall (m :: * -> *). MonadFail m => [Char] -> m AccessionID
makeAccessionID [Char]
x
    | [Char]
x [Char] -> [Char] -> Bool
forall source source1 target.
(RegexMaker Regex CompOption ExecOption source,
 RegexContext Regex source1 target) =>
source1 -> source -> target
Reg.=~ ([Char]
"PRJ[EDN][A-Z][0-9]+"  :: String) = AccessionID -> m AccessionID
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AccessionID -> m AccessionID) -> AccessionID -> m AccessionID
forall a b. (a -> b) -> a -> b
$ [Char] -> AccessionID
INSDCProject [Char]
x
    | [Char]
x [Char] -> [Char] -> Bool
forall source source1 target.
(RegexMaker Regex CompOption ExecOption source,
 RegexContext Regex source1 target) =>
source1 -> source -> target
Reg.=~ ([Char]
"[EDS]RP[0-9]{6,}"     :: String) = AccessionID -> m AccessionID
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AccessionID -> m AccessionID) -> AccessionID -> m AccessionID
forall a b. (a -> b) -> a -> b
$ [Char] -> AccessionID
INSDCStudy [Char]
x
    | [Char]
x [Char] -> [Char] -> Bool
forall source source1 target.
(RegexMaker Regex CompOption ExecOption source,
 RegexContext Regex source1 target) =>
source1 -> source -> target
Reg.=~ ([Char]
"SAM[EDN][A-Z]?[0-9]+" :: String) = AccessionID -> m AccessionID
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AccessionID -> m AccessionID) -> AccessionID -> m AccessionID
forall a b. (a -> b) -> a -> b
$ [Char] -> AccessionID
INSDCBioSample [Char]
x
    | [Char]
x [Char] -> [Char] -> Bool
forall source source1 target.
(RegexMaker Regex CompOption ExecOption source,
 RegexContext Regex source1 target) =>
source1 -> source -> target
Reg.=~ ([Char]
"[EDS]RS[0-9]{6,}"     :: String) = AccessionID -> m AccessionID
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AccessionID -> m AccessionID) -> AccessionID -> m AccessionID
forall a b. (a -> b) -> a -> b
$ [Char] -> AccessionID
INSDCSample [Char]
x
    | [Char]
x [Char] -> [Char] -> Bool
forall source source1 target.
(RegexMaker Regex CompOption ExecOption source,
 RegexContext Regex source1 target) =>
source1 -> source -> target
Reg.=~ ([Char]
"[EDS]RX[0-9]{6,}"     :: String) = AccessionID -> m AccessionID
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AccessionID -> m AccessionID) -> AccessionID -> m AccessionID
forall a b. (a -> b) -> a -> b
$ [Char] -> AccessionID
INSDCExperiment [Char]
x
    | [Char]
x [Char] -> [Char] -> Bool
forall source source1 target.
(RegexMaker Regex CompOption ExecOption source,
 RegexContext Regex source1 target) =>
source1 -> source -> target
Reg.=~ ([Char]
"[EDS]RR[0-9]{6,}"     :: String) = AccessionID -> m AccessionID
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AccessionID -> m AccessionID) -> AccessionID -> m AccessionID
forall a b. (a -> b) -> a -> b
$ [Char] -> AccessionID
INSDCRun [Char]
x
    | [Char]
x [Char] -> [Char] -> Bool
forall source source1 target.
(RegexMaker Regex CompOption ExecOption source,
 RegexContext Regex source1 target) =>
source1 -> source -> target
Reg.=~ ([Char]
"[EDS]RZ[0-9]{6,}"     :: String) = AccessionID -> m AccessionID
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AccessionID -> m AccessionID) -> AccessionID -> m AccessionID
forall a b. (a -> b) -> a -> b
$ [Char] -> AccessionID
INSDCAnalysis [Char]
x
    | Bool
otherwise                                   = AccessionID -> m AccessionID
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AccessionID -> m AccessionID) -> AccessionID -> m AccessionID
forall a b. (a -> b) -> a -> b
$ [Char] -> AccessionID
OtherID [Char]
x

instance Csv.ToField AccessionID where
    toField :: AccessionID -> ByteString
toField AccessionID
x = [Char] -> ByteString
forall a. ToField a => a -> ByteString
Csv.toField ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ AccessionID -> [Char]
forall a. Show a => a -> [Char]
show AccessionID
x
instance Csv.FromField AccessionID where
    parseField :: ByteString -> Parser AccessionID
parseField ByteString
x = ByteString -> Parser [Char]
forall a. FromField a => ByteString -> Parser a
Csv.parseField ByteString
x Parser [Char]
-> ([Char] -> Parser AccessionID) -> Parser AccessionID
forall a b. Parser a -> (a -> Parser b) -> Parser b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [Char] -> Parser AccessionID
forall (m :: * -> *). MonadFail m => [Char] -> m AccessionID
makeAccessionID

-- | A datatype to represent URIs in a ssf file
newtype JURI =
        JURI String
    deriving (JURI -> JURI -> Bool
(JURI -> JURI -> Bool) -> (JURI -> JURI -> Bool) -> Eq JURI
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: JURI -> JURI -> Bool
== :: JURI -> JURI -> Bool
$c/= :: JURI -> JURI -> Bool
/= :: JURI -> JURI -> Bool
Eq, Eq JURI
Eq JURI
-> (JURI -> JURI -> Ordering)
-> (JURI -> JURI -> Bool)
-> (JURI -> JURI -> Bool)
-> (JURI -> JURI -> Bool)
-> (JURI -> JURI -> Bool)
-> (JURI -> JURI -> JURI)
-> (JURI -> JURI -> JURI)
-> Ord JURI
JURI -> JURI -> Bool
JURI -> JURI -> Ordering
JURI -> JURI -> JURI
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: JURI -> JURI -> Ordering
compare :: JURI -> JURI -> Ordering
$c< :: JURI -> JURI -> Bool
< :: JURI -> JURI -> Bool
$c<= :: JURI -> JURI -> Bool
<= :: JURI -> JURI -> Bool
$c> :: JURI -> JURI -> Bool
> :: JURI -> JURI -> Bool
$c>= :: JURI -> JURI -> Bool
>= :: JURI -> JURI -> Bool
$cmax :: JURI -> JURI -> JURI
max :: JURI -> JURI -> JURI
$cmin :: JURI -> JURI -> JURI
min :: JURI -> JURI -> JURI
Ord, (forall x. JURI -> Rep JURI x)
-> (forall x. Rep JURI x -> JURI) -> Generic JURI
forall x. Rep JURI x -> JURI
forall x. JURI -> Rep JURI x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. JURI -> Rep JURI x
from :: forall x. JURI -> Rep JURI x
$cto :: forall x. Rep JURI x -> JURI
to :: forall x. Rep JURI x -> JURI
Generic)

instance Show JURI where
    show :: JURI -> [Char]
show (JURI [Char]
x) = [Char]
x

makeJURI :: MonadFail m => String -> m JURI
makeJURI :: forall (m :: * -> *). MonadFail m => [Char] -> m JURI
makeJURI [Char]
x
    | [Char] -> Bool
isURIReference [Char]
x   = JURI -> m JURI
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (JURI -> m JURI) -> JURI -> m JURI
forall a b. (a -> b) -> a -> b
$ [Char] -> JURI
JURI [Char]
x
    | Bool
otherwise          = [Char] -> m JURI
forall a. [Char] -> m a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> m JURI) -> [Char] -> m JURI
forall a b. (a -> b) -> a -> b
$ [Char]
"URI " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> [Char]
show [Char]
x [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
" not well structured"

instance Csv.ToField JURI where
    toField :: JURI -> ByteString
toField JURI
x = [Char] -> ByteString
forall a. ToField a => a -> ByteString
Csv.toField ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ JURI -> [Char]
forall a. Show a => a -> [Char]
show JURI
x
instance Csv.FromField JURI where
    parseField :: ByteString -> Parser JURI
parseField ByteString
x = ByteString -> Parser [Char]
forall a. FromField a => ByteString -> Parser a
Csv.parseField ByteString
x Parser [Char] -> ([Char] -> Parser JURI) -> Parser JURI
forall a b. Parser a -> (a -> Parser b) -> Parser b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [Char] -> Parser JURI
forall (m :: * -> *). MonadFail m => [Char] -> m JURI
makeJURI

-- |A datatype to represent UDG in a ssf file
data SSFUDG =
      SSFMinus
    | SSFHalf
    | SSFPlus
    deriving (SSFUDG -> SSFUDG -> Bool
(SSFUDG -> SSFUDG -> Bool)
-> (SSFUDG -> SSFUDG -> Bool) -> Eq SSFUDG
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SSFUDG -> SSFUDG -> Bool
== :: SSFUDG -> SSFUDG -> Bool
$c/= :: SSFUDG -> SSFUDG -> Bool
/= :: SSFUDG -> SSFUDG -> Bool
Eq, Eq SSFUDG
Eq SSFUDG
-> (SSFUDG -> SSFUDG -> Ordering)
-> (SSFUDG -> SSFUDG -> Bool)
-> (SSFUDG -> SSFUDG -> Bool)
-> (SSFUDG -> SSFUDG -> Bool)
-> (SSFUDG -> SSFUDG -> Bool)
-> (SSFUDG -> SSFUDG -> SSFUDG)
-> (SSFUDG -> SSFUDG -> SSFUDG)
-> Ord SSFUDG
SSFUDG -> SSFUDG -> Bool
SSFUDG -> SSFUDG -> Ordering
SSFUDG -> SSFUDG -> SSFUDG
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: SSFUDG -> SSFUDG -> Ordering
compare :: SSFUDG -> SSFUDG -> Ordering
$c< :: SSFUDG -> SSFUDG -> Bool
< :: SSFUDG -> SSFUDG -> Bool
$c<= :: SSFUDG -> SSFUDG -> Bool
<= :: SSFUDG -> SSFUDG -> Bool
$c> :: SSFUDG -> SSFUDG -> Bool
> :: SSFUDG -> SSFUDG -> Bool
$c>= :: SSFUDG -> SSFUDG -> Bool
>= :: SSFUDG -> SSFUDG -> Bool
$cmax :: SSFUDG -> SSFUDG -> SSFUDG
max :: SSFUDG -> SSFUDG -> SSFUDG
$cmin :: SSFUDG -> SSFUDG -> SSFUDG
min :: SSFUDG -> SSFUDG -> SSFUDG
Ord, (forall x. SSFUDG -> Rep SSFUDG x)
-> (forall x. Rep SSFUDG x -> SSFUDG) -> Generic SSFUDG
forall x. Rep SSFUDG x -> SSFUDG
forall x. SSFUDG -> Rep SSFUDG x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. SSFUDG -> Rep SSFUDG x
from :: forall x. SSFUDG -> Rep SSFUDG x
$cto :: forall x. Rep SSFUDG x -> SSFUDG
to :: forall x. Rep SSFUDG x -> SSFUDG
Generic, Int -> SSFUDG
SSFUDG -> Int
SSFUDG -> [SSFUDG]
SSFUDG -> SSFUDG
SSFUDG -> SSFUDG -> [SSFUDG]
SSFUDG -> SSFUDG -> SSFUDG -> [SSFUDG]
(SSFUDG -> SSFUDG)
-> (SSFUDG -> SSFUDG)
-> (Int -> SSFUDG)
-> (SSFUDG -> Int)
-> (SSFUDG -> [SSFUDG])
-> (SSFUDG -> SSFUDG -> [SSFUDG])
-> (SSFUDG -> SSFUDG -> [SSFUDG])
-> (SSFUDG -> SSFUDG -> SSFUDG -> [SSFUDG])
-> Enum SSFUDG
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: SSFUDG -> SSFUDG
succ :: SSFUDG -> SSFUDG
$cpred :: SSFUDG -> SSFUDG
pred :: SSFUDG -> SSFUDG
$ctoEnum :: Int -> SSFUDG
toEnum :: Int -> SSFUDG
$cfromEnum :: SSFUDG -> Int
fromEnum :: SSFUDG -> Int
$cenumFrom :: SSFUDG -> [SSFUDG]
enumFrom :: SSFUDG -> [SSFUDG]
$cenumFromThen :: SSFUDG -> SSFUDG -> [SSFUDG]
enumFromThen :: SSFUDG -> SSFUDG -> [SSFUDG]
$cenumFromTo :: SSFUDG -> SSFUDG -> [SSFUDG]
enumFromTo :: SSFUDG -> SSFUDG -> [SSFUDG]
$cenumFromThenTo :: SSFUDG -> SSFUDG -> SSFUDG -> [SSFUDG]
enumFromThenTo :: SSFUDG -> SSFUDG -> SSFUDG -> [SSFUDG]
Enum, SSFUDG
SSFUDG -> SSFUDG -> Bounded SSFUDG
forall a. a -> a -> Bounded a
$cminBound :: SSFUDG
minBound :: SSFUDG
$cmaxBound :: SSFUDG
maxBound :: SSFUDG
Bounded)

instance Show SSFUDG where
    show :: SSFUDG -> [Char]
show SSFUDG
SSFMinus = [Char]
"minus"
    show SSFUDG
SSFHalf  = [Char]
"half"
    show SSFUDG
SSFPlus  = [Char]
"plus"

makeSSFUDG :: MonadFail m => String -> m SSFUDG
makeSSFUDG :: forall (m :: * -> *). MonadFail m => [Char] -> m SSFUDG
makeSSFUDG [Char]
x
    | [Char]
x [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== [Char]
"minus" = SSFUDG -> m SSFUDG
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SSFUDG
SSFMinus
    | [Char]
x [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== [Char]
"half"  = SSFUDG -> m SSFUDG
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SSFUDG
SSFHalf
    | [Char]
x [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== [Char]
"plus"  = SSFUDG -> m SSFUDG
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SSFUDG
SSFPlus
    | Bool
otherwise    = [Char] -> m SSFUDG
forall a. [Char] -> m a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> m SSFUDG) -> [Char] -> m SSFUDG
forall a b. (a -> b) -> a -> b
$ [Char]
"UDG " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> [Char]
show [Char]
x [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
" not in [minus, half, plus]"

instance Csv.ToField SSFUDG where
    toField :: SSFUDG -> ByteString
toField SSFUDG
x = [Char] -> ByteString
forall a. ToField a => a -> ByteString
Csv.toField ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ SSFUDG -> [Char]
forall a. Show a => a -> [Char]
show SSFUDG
x
instance Csv.FromField SSFUDG where
    parseField :: ByteString -> Parser SSFUDG
parseField ByteString
x = ByteString -> Parser [Char]
forall a. FromField a => ByteString -> Parser a
Csv.parseField ByteString
x Parser [Char] -> ([Char] -> Parser SSFUDG) -> Parser SSFUDG
forall a b. Parser a -> (a -> Parser b) -> Parser b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [Char] -> Parser SSFUDG
forall (m :: * -> *). MonadFail m => [Char] -> m SSFUDG
makeSSFUDG

-- |A datatype to represent Library_Built in a janno file
data SSFLibraryBuilt =
      SSFDS
    | SSFSS
    deriving (SSFLibraryBuilt -> SSFLibraryBuilt -> Bool
(SSFLibraryBuilt -> SSFLibraryBuilt -> Bool)
-> (SSFLibraryBuilt -> SSFLibraryBuilt -> Bool)
-> Eq SSFLibraryBuilt
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SSFLibraryBuilt -> SSFLibraryBuilt -> Bool
== :: SSFLibraryBuilt -> SSFLibraryBuilt -> Bool
$c/= :: SSFLibraryBuilt -> SSFLibraryBuilt -> Bool
/= :: SSFLibraryBuilt -> SSFLibraryBuilt -> Bool
Eq, Eq SSFLibraryBuilt
Eq SSFLibraryBuilt
-> (SSFLibraryBuilt -> SSFLibraryBuilt -> Ordering)
-> (SSFLibraryBuilt -> SSFLibraryBuilt -> Bool)
-> (SSFLibraryBuilt -> SSFLibraryBuilt -> Bool)
-> (SSFLibraryBuilt -> SSFLibraryBuilt -> Bool)
-> (SSFLibraryBuilt -> SSFLibraryBuilt -> Bool)
-> (SSFLibraryBuilt -> SSFLibraryBuilt -> SSFLibraryBuilt)
-> (SSFLibraryBuilt -> SSFLibraryBuilt -> SSFLibraryBuilt)
-> Ord SSFLibraryBuilt
SSFLibraryBuilt -> SSFLibraryBuilt -> Bool
SSFLibraryBuilt -> SSFLibraryBuilt -> Ordering
SSFLibraryBuilt -> SSFLibraryBuilt -> SSFLibraryBuilt
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: SSFLibraryBuilt -> SSFLibraryBuilt -> Ordering
compare :: SSFLibraryBuilt -> SSFLibraryBuilt -> Ordering
$c< :: SSFLibraryBuilt -> SSFLibraryBuilt -> Bool
< :: SSFLibraryBuilt -> SSFLibraryBuilt -> Bool
$c<= :: SSFLibraryBuilt -> SSFLibraryBuilt -> Bool
<= :: SSFLibraryBuilt -> SSFLibraryBuilt -> Bool
$c> :: SSFLibraryBuilt -> SSFLibraryBuilt -> Bool
> :: SSFLibraryBuilt -> SSFLibraryBuilt -> Bool
$c>= :: SSFLibraryBuilt -> SSFLibraryBuilt -> Bool
>= :: SSFLibraryBuilt -> SSFLibraryBuilt -> Bool
$cmax :: SSFLibraryBuilt -> SSFLibraryBuilt -> SSFLibraryBuilt
max :: SSFLibraryBuilt -> SSFLibraryBuilt -> SSFLibraryBuilt
$cmin :: SSFLibraryBuilt -> SSFLibraryBuilt -> SSFLibraryBuilt
min :: SSFLibraryBuilt -> SSFLibraryBuilt -> SSFLibraryBuilt
Ord, (forall x. SSFLibraryBuilt -> Rep SSFLibraryBuilt x)
-> (forall x. Rep SSFLibraryBuilt x -> SSFLibraryBuilt)
-> Generic SSFLibraryBuilt
forall x. Rep SSFLibraryBuilt x -> SSFLibraryBuilt
forall x. SSFLibraryBuilt -> Rep SSFLibraryBuilt x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. SSFLibraryBuilt -> Rep SSFLibraryBuilt x
from :: forall x. SSFLibraryBuilt -> Rep SSFLibraryBuilt x
$cto :: forall x. Rep SSFLibraryBuilt x -> SSFLibraryBuilt
to :: forall x. Rep SSFLibraryBuilt x -> SSFLibraryBuilt
Generic, Int -> SSFLibraryBuilt
SSFLibraryBuilt -> Int
SSFLibraryBuilt -> [SSFLibraryBuilt]
SSFLibraryBuilt -> SSFLibraryBuilt
SSFLibraryBuilt -> SSFLibraryBuilt -> [SSFLibraryBuilt]
SSFLibraryBuilt
-> SSFLibraryBuilt -> SSFLibraryBuilt -> [SSFLibraryBuilt]
(SSFLibraryBuilt -> SSFLibraryBuilt)
-> (SSFLibraryBuilt -> SSFLibraryBuilt)
-> (Int -> SSFLibraryBuilt)
-> (SSFLibraryBuilt -> Int)
-> (SSFLibraryBuilt -> [SSFLibraryBuilt])
-> (SSFLibraryBuilt -> SSFLibraryBuilt -> [SSFLibraryBuilt])
-> (SSFLibraryBuilt -> SSFLibraryBuilt -> [SSFLibraryBuilt])
-> (SSFLibraryBuilt
    -> SSFLibraryBuilt -> SSFLibraryBuilt -> [SSFLibraryBuilt])
-> Enum SSFLibraryBuilt
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: SSFLibraryBuilt -> SSFLibraryBuilt
succ :: SSFLibraryBuilt -> SSFLibraryBuilt
$cpred :: SSFLibraryBuilt -> SSFLibraryBuilt
pred :: SSFLibraryBuilt -> SSFLibraryBuilt
$ctoEnum :: Int -> SSFLibraryBuilt
toEnum :: Int -> SSFLibraryBuilt
$cfromEnum :: SSFLibraryBuilt -> Int
fromEnum :: SSFLibraryBuilt -> Int
$cenumFrom :: SSFLibraryBuilt -> [SSFLibraryBuilt]
enumFrom :: SSFLibraryBuilt -> [SSFLibraryBuilt]
$cenumFromThen :: SSFLibraryBuilt -> SSFLibraryBuilt -> [SSFLibraryBuilt]
enumFromThen :: SSFLibraryBuilt -> SSFLibraryBuilt -> [SSFLibraryBuilt]
$cenumFromTo :: SSFLibraryBuilt -> SSFLibraryBuilt -> [SSFLibraryBuilt]
enumFromTo :: SSFLibraryBuilt -> SSFLibraryBuilt -> [SSFLibraryBuilt]
$cenumFromThenTo :: SSFLibraryBuilt
-> SSFLibraryBuilt -> SSFLibraryBuilt -> [SSFLibraryBuilt]
enumFromThenTo :: SSFLibraryBuilt
-> SSFLibraryBuilt -> SSFLibraryBuilt -> [SSFLibraryBuilt]
Enum, SSFLibraryBuilt
SSFLibraryBuilt -> SSFLibraryBuilt -> Bounded SSFLibraryBuilt
forall a. a -> a -> Bounded a
$cminBound :: SSFLibraryBuilt
minBound :: SSFLibraryBuilt
$cmaxBound :: SSFLibraryBuilt
maxBound :: SSFLibraryBuilt
Bounded)

instance Show SSFLibraryBuilt where
    show :: SSFLibraryBuilt -> [Char]
show SSFLibraryBuilt
SSFDS = [Char]
"ds"
    show SSFLibraryBuilt
SSFSS = [Char]
"ss"

makeSSFLibraryBuilt :: MonadFail m => String -> m SSFLibraryBuilt
makeSSFLibraryBuilt :: forall (m :: * -> *). MonadFail m => [Char] -> m SSFLibraryBuilt
makeSSFLibraryBuilt [Char]
x
    | [Char]
x [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== [Char]
"ds"    = SSFLibraryBuilt -> m SSFLibraryBuilt
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SSFLibraryBuilt
SSFDS
    | [Char]
x [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== [Char]
"ss"    = SSFLibraryBuilt -> m SSFLibraryBuilt
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SSFLibraryBuilt
SSFSS
    | Bool
otherwise    = [Char] -> m SSFLibraryBuilt
forall a. [Char] -> m a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> m SSFLibraryBuilt) -> [Char] -> m SSFLibraryBuilt
forall a b. (a -> b) -> a -> b
$ [Char]
"Library_Built " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> [Char]
show [Char]
x [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
" not in [ds, ss]"

instance Csv.ToField SSFLibraryBuilt where
    toField :: SSFLibraryBuilt -> ByteString
toField SSFLibraryBuilt
x = [Char] -> ByteString
forall a. ToField a => a -> ByteString
Csv.toField ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ SSFLibraryBuilt -> [Char]
forall a. Show a => a -> [Char]
show SSFLibraryBuilt
x
instance Csv.FromField SSFLibraryBuilt where
    parseField :: ByteString -> Parser SSFLibraryBuilt
parseField ByteString
x = ByteString -> Parser [Char]
forall a. FromField a => ByteString -> Parser a
Csv.parseField ByteString
x Parser [Char]
-> ([Char] -> Parser SSFLibraryBuilt) -> Parser SSFLibraryBuilt
forall a b. Parser a -> (a -> Parser b) -> Parser b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [Char] -> Parser SSFLibraryBuilt
forall (m :: * -> *). MonadFail m => [Char] -> m SSFLibraryBuilt
makeSSFLibraryBuilt

-- | A data type to represent a seqSourceFile
newtype SeqSourceRows = SeqSourceRows {SeqSourceRows -> [SeqSourceRow]
getSeqSourceRowList :: [SeqSourceRow]}
    deriving (Int -> SeqSourceRows -> ShowS
[SeqSourceRows] -> ShowS
SeqSourceRows -> [Char]
(Int -> SeqSourceRows -> ShowS)
-> (SeqSourceRows -> [Char])
-> ([SeqSourceRows] -> ShowS)
-> Show SeqSourceRows
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SeqSourceRows -> ShowS
showsPrec :: Int -> SeqSourceRows -> ShowS
$cshow :: SeqSourceRows -> [Char]
show :: SeqSourceRows -> [Char]
$cshowList :: [SeqSourceRows] -> ShowS
showList :: [SeqSourceRows] -> ShowS
Show, SeqSourceRows -> SeqSourceRows -> Bool
(SeqSourceRows -> SeqSourceRows -> Bool)
-> (SeqSourceRows -> SeqSourceRows -> Bool) -> Eq SeqSourceRows
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SeqSourceRows -> SeqSourceRows -> Bool
== :: SeqSourceRows -> SeqSourceRows -> Bool
$c/= :: SeqSourceRows -> SeqSourceRows -> Bool
/= :: SeqSourceRows -> SeqSourceRows -> Bool
Eq, (forall x. SeqSourceRows -> Rep SeqSourceRows x)
-> (forall x. Rep SeqSourceRows x -> SeqSourceRows)
-> Generic SeqSourceRows
forall x. Rep SeqSourceRows x -> SeqSourceRows
forall x. SeqSourceRows -> Rep SeqSourceRows x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. SeqSourceRows -> Rep SeqSourceRows x
from :: forall x. SeqSourceRows -> Rep SeqSourceRows x
$cto :: forall x. Rep SeqSourceRows x -> SeqSourceRows
to :: forall x. Rep SeqSourceRows x -> SeqSourceRows
Generic)

instance Semigroup SeqSourceRows where
    (SeqSourceRows [SeqSourceRow]
j1) <> :: SeqSourceRows -> SeqSourceRows -> SeqSourceRows
<> (SeqSourceRows [SeqSourceRow]
j2) = [SeqSourceRow] -> SeqSourceRows
SeqSourceRows ([SeqSourceRow] -> SeqSourceRows)
-> [SeqSourceRow] -> SeqSourceRows
forall a b. (a -> b) -> a -> b
$ [SeqSourceRow]
j1 [SeqSourceRow] -> [SeqSourceRow] -> [SeqSourceRow]
`combineTwoSeqSources` [SeqSourceRow]
j2
        where
        combineTwoSeqSources :: [SeqSourceRow] -> [SeqSourceRow] -> [SeqSourceRow]
        combineTwoSeqSources :: [SeqSourceRow] -> [SeqSourceRow] -> [SeqSourceRow]
combineTwoSeqSources [SeqSourceRow]
seqSource1 [SeqSourceRow]
seqSource2 =
            let simpleSeqSourceSum :: [SeqSourceRow]
simpleSeqSourceSum = [SeqSourceRow]
seqSource1 [SeqSourceRow] -> [SeqSourceRow] -> [SeqSourceRow]
forall a. [a] -> [a] -> [a]
++ [SeqSourceRow]
seqSource2
                toAddColNames :: [ByteString]
toAddColNames = HashMap ByteString ByteString -> [ByteString]
forall k v. HashMap k v -> [k]
HM.keys ([HashMap ByteString ByteString] -> HashMap ByteString ByteString
forall k v. (Eq k, Hashable k) => [HashMap k v] -> HashMap k v
HM.unions ((SeqSourceRow -> HashMap ByteString ByteString)
-> [SeqSourceRow] -> [HashMap ByteString ByteString]
forall a b. (a -> b) -> [a] -> [b]
map (CsvNamedRecord -> HashMap ByteString ByteString
getCsvNR (CsvNamedRecord -> HashMap ByteString ByteString)
-> (SeqSourceRow -> CsvNamedRecord)
-> SeqSourceRow
-> HashMap ByteString ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SeqSourceRow -> CsvNamedRecord
sAdditionalColumns) [SeqSourceRow]
simpleSeqSourceSum))
                toAddEmptyCols :: HashMap ByteString ByteString
toAddEmptyCols = [(ByteString, ByteString)] -> HashMap ByteString ByteString
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HM.fromList ((ByteString -> (ByteString, ByteString))
-> [ByteString] -> [(ByteString, ByteString)]
forall a b. (a -> b) -> [a] -> [b]
map (\ByteString
k -> (ByteString
k, ByteString
"n/a")) [ByteString]
toAddColNames)
            in (SeqSourceRow -> SeqSourceRow) -> [SeqSourceRow] -> [SeqSourceRow]
forall a b. (a -> b) -> [a] -> [b]
map (HashMap ByteString ByteString -> SeqSourceRow -> SeqSourceRow
addEmptyAddColsToSeqSourceRow HashMap ByteString ByteString
toAddEmptyCols) [SeqSourceRow]
simpleSeqSourceSum
        addEmptyAddColsToSeqSourceRow :: Csv.NamedRecord -> SeqSourceRow -> SeqSourceRow
        addEmptyAddColsToSeqSourceRow :: HashMap ByteString ByteString -> SeqSourceRow -> SeqSourceRow
addEmptyAddColsToSeqSourceRow HashMap ByteString ByteString
toAdd SeqSourceRow
x =
            SeqSourceRow
x { sAdditionalColumns :: CsvNamedRecord
sAdditionalColumns = HashMap ByteString ByteString -> CsvNamedRecord
CsvNamedRecord (HashMap ByteString ByteString -> CsvNamedRecord)
-> HashMap ByteString ByteString -> CsvNamedRecord
forall a b. (a -> b) -> a -> b
$ HashMap ByteString ByteString
-> HashMap ByteString ByteString -> HashMap ByteString ByteString
fillAddCols HashMap ByteString ByteString
toAdd (CsvNamedRecord -> HashMap ByteString ByteString
getCsvNR (CsvNamedRecord -> HashMap ByteString ByteString)
-> CsvNamedRecord -> HashMap ByteString ByteString
forall a b. (a -> b) -> a -> b
$ SeqSourceRow -> CsvNamedRecord
sAdditionalColumns SeqSourceRow
x) }
        fillAddCols :: Csv.NamedRecord -> Csv.NamedRecord -> Csv.NamedRecord
        fillAddCols :: HashMap ByteString ByteString
-> HashMap ByteString ByteString -> HashMap ByteString ByteString
fillAddCols HashMap ByteString ByteString
toAdd HashMap ByteString ByteString
cur = HashMap ByteString ByteString
-> HashMap ByteString ByteString -> HashMap ByteString ByteString
forall k v.
(Eq k, Hashable k) =>
HashMap k v -> HashMap k v -> HashMap k v
HM.union HashMap ByteString ByteString
cur (HashMap ByteString ByteString
toAdd HashMap ByteString ByteString
-> HashMap ByteString ByteString -> HashMap ByteString ByteString
forall k v w.
(Eq k, Hashable k) =>
HashMap k v -> HashMap k w -> HashMap k v
`HM.difference` HashMap ByteString ByteString
cur)

instance Monoid SeqSourceRows where
    mempty :: SeqSourceRows
mempty = [SeqSourceRow] -> SeqSourceRows
SeqSourceRows []
    mconcat :: [SeqSourceRows] -> SeqSourceRows
mconcat = (SeqSourceRows -> SeqSourceRows -> SeqSourceRows)
-> SeqSourceRows -> [SeqSourceRows] -> SeqSourceRows
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' SeqSourceRows -> SeqSourceRows -> SeqSourceRows
forall a. Monoid a => a -> a -> a
mappend SeqSourceRows
forall a. Monoid a => a
mempty

-- A data type to represent a run accession ID
newtype AccessionIDRun = AccessionIDRun {AccessionIDRun -> AccessionID
getRunAccession :: AccessionID}
    deriving (AccessionIDRun -> AccessionIDRun -> Bool
(AccessionIDRun -> AccessionIDRun -> Bool)
-> (AccessionIDRun -> AccessionIDRun -> Bool) -> Eq AccessionIDRun
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: AccessionIDRun -> AccessionIDRun -> Bool
== :: AccessionIDRun -> AccessionIDRun -> Bool
$c/= :: AccessionIDRun -> AccessionIDRun -> Bool
/= :: AccessionIDRun -> AccessionIDRun -> Bool
Eq, (forall x. AccessionIDRun -> Rep AccessionIDRun x)
-> (forall x. Rep AccessionIDRun x -> AccessionIDRun)
-> Generic AccessionIDRun
forall x. Rep AccessionIDRun x -> AccessionIDRun
forall x. AccessionIDRun -> Rep AccessionIDRun x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. AccessionIDRun -> Rep AccessionIDRun x
from :: forall x. AccessionIDRun -> Rep AccessionIDRun x
$cto :: forall x. Rep AccessionIDRun x -> AccessionIDRun
to :: forall x. Rep AccessionIDRun x -> AccessionIDRun
Generic)

makeAccessionIDRun :: MonadFail m => String -> m AccessionIDRun
makeAccessionIDRun :: forall (m :: * -> *). MonadFail m => [Char] -> m AccessionIDRun
makeAccessionIDRun [Char]
x = do
    AccessionID
accsID <- [Char] -> m AccessionID
forall (m :: * -> *). MonadFail m => [Char] -> m AccessionID
makeAccessionID [Char]
x
    case AccessionID
accsID of
        (INSDCRun [Char]
y) -> AccessionIDRun -> m AccessionIDRun
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AccessionIDRun -> m AccessionIDRun)
-> AccessionIDRun -> m AccessionIDRun
forall a b. (a -> b) -> a -> b
$ AccessionID -> AccessionIDRun
AccessionIDRun ([Char] -> AccessionID
INSDCRun [Char]
y)
        AccessionID
_            -> [Char] -> m AccessionIDRun
forall a. [Char] -> m a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> m AccessionIDRun) -> [Char] -> m AccessionIDRun
forall a b. (a -> b) -> a -> b
$ [Char]
"Accession " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> [Char]
show [Char]
x [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
" not a correct run accession"

instance Show AccessionIDRun where
    show :: AccessionIDRun -> [Char]
show (AccessionIDRun AccessionID
x) = AccessionID -> [Char]
forall a. Show a => a -> [Char]
show AccessionID
x

instance Csv.ToField AccessionIDRun where
    toField :: AccessionIDRun -> ByteString
toField AccessionIDRun
x = [Char] -> ByteString
forall a. ToField a => a -> ByteString
Csv.toField ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ AccessionIDRun -> [Char]
forall a. Show a => a -> [Char]
show AccessionIDRun
x
instance Csv.FromField AccessionIDRun where
    parseField :: ByteString -> Parser AccessionIDRun
parseField ByteString
x = ByteString -> Parser [Char]
forall a. FromField a => ByteString -> Parser a
Csv.parseField ByteString
x Parser [Char]
-> ([Char] -> Parser AccessionIDRun) -> Parser AccessionIDRun
forall a b. Parser a -> (a -> Parser b) -> Parser b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [Char] -> Parser AccessionIDRun
forall (m :: * -> *). MonadFail m => [Char] -> m AccessionIDRun
makeAccessionIDRun

-- A data type to represent a sample accession ID
newtype AccessionIDSample = AccessionIDSample {AccessionIDSample -> AccessionID
getSampleAccession :: AccessionID}
    deriving (AccessionIDSample -> AccessionIDSample -> Bool
(AccessionIDSample -> AccessionIDSample -> Bool)
-> (AccessionIDSample -> AccessionIDSample -> Bool)
-> Eq AccessionIDSample
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: AccessionIDSample -> AccessionIDSample -> Bool
== :: AccessionIDSample -> AccessionIDSample -> Bool
$c/= :: AccessionIDSample -> AccessionIDSample -> Bool
/= :: AccessionIDSample -> AccessionIDSample -> Bool
Eq, (forall x. AccessionIDSample -> Rep AccessionIDSample x)
-> (forall x. Rep AccessionIDSample x -> AccessionIDSample)
-> Generic AccessionIDSample
forall x. Rep AccessionIDSample x -> AccessionIDSample
forall x. AccessionIDSample -> Rep AccessionIDSample x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. AccessionIDSample -> Rep AccessionIDSample x
from :: forall x. AccessionIDSample -> Rep AccessionIDSample x
$cto :: forall x. Rep AccessionIDSample x -> AccessionIDSample
to :: forall x. Rep AccessionIDSample x -> AccessionIDSample
Generic)

makeAccessionIDSample :: MonadFail m => String -> m AccessionIDSample
makeAccessionIDSample :: forall (m :: * -> *). MonadFail m => [Char] -> m AccessionIDSample
makeAccessionIDSample [Char]
x = do
    AccessionID
accsID <- [Char] -> m AccessionID
forall (m :: * -> *). MonadFail m => [Char] -> m AccessionID
makeAccessionID [Char]
x
    case AccessionID
accsID of
        (INSDCBioSample [Char]
y) -> AccessionIDSample -> m AccessionIDSample
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AccessionIDSample -> m AccessionIDSample)
-> AccessionIDSample -> m AccessionIDSample
forall a b. (a -> b) -> a -> b
$ AccessionID -> AccessionIDSample
AccessionIDSample ([Char] -> AccessionID
INSDCBioSample [Char]
y)
        (INSDCSample [Char]
y)    -> AccessionIDSample -> m AccessionIDSample
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AccessionIDSample -> m AccessionIDSample)
-> AccessionIDSample -> m AccessionIDSample
forall a b. (a -> b) -> a -> b
$ AccessionID -> AccessionIDSample
AccessionIDSample ([Char] -> AccessionID
INSDCSample [Char]
y)
        AccessionID
_                  -> [Char] -> m AccessionIDSample
forall a. [Char] -> m a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> m AccessionIDSample) -> [Char] -> m AccessionIDSample
forall a b. (a -> b) -> a -> b
$ [Char]
"Accession " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> [Char]
show [Char]
x [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
" not a correct biosample/sample accession"

instance Show AccessionIDSample where
    show :: AccessionIDSample -> [Char]
show (AccessionIDSample AccessionID
x) = AccessionID -> [Char]
forall a. Show a => a -> [Char]
show AccessionID
x

instance Csv.ToField AccessionIDSample where
    toField :: AccessionIDSample -> ByteString
toField AccessionIDSample
x = [Char] -> ByteString
forall a. ToField a => a -> ByteString
Csv.toField ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ AccessionIDSample -> [Char]
forall a. Show a => a -> [Char]
show AccessionIDSample
x
instance Csv.FromField AccessionIDSample where
    parseField :: ByteString -> Parser AccessionIDSample
parseField ByteString
x = ByteString -> Parser [Char]
forall a. FromField a => ByteString -> Parser a
Csv.parseField ByteString
x Parser [Char]
-> ([Char] -> Parser AccessionIDSample) -> Parser AccessionIDSample
forall a b. Parser a -> (a -> Parser b) -> Parser b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [Char] -> Parser AccessionIDSample
forall (m :: * -> *). MonadFail m => [Char] -> m AccessionIDSample
makeAccessionIDSample

-- A data type to represent a study accession ID
newtype AccessionIDStudy = AccessionIDStudy {AccessionIDStudy -> AccessionID
getStudyAccession :: AccessionID}
    deriving (AccessionIDStudy -> AccessionIDStudy -> Bool
(AccessionIDStudy -> AccessionIDStudy -> Bool)
-> (AccessionIDStudy -> AccessionIDStudy -> Bool)
-> Eq AccessionIDStudy
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: AccessionIDStudy -> AccessionIDStudy -> Bool
== :: AccessionIDStudy -> AccessionIDStudy -> Bool
$c/= :: AccessionIDStudy -> AccessionIDStudy -> Bool
/= :: AccessionIDStudy -> AccessionIDStudy -> Bool
Eq, (forall x. AccessionIDStudy -> Rep AccessionIDStudy x)
-> (forall x. Rep AccessionIDStudy x -> AccessionIDStudy)
-> Generic AccessionIDStudy
forall x. Rep AccessionIDStudy x -> AccessionIDStudy
forall x. AccessionIDStudy -> Rep AccessionIDStudy x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. AccessionIDStudy -> Rep AccessionIDStudy x
from :: forall x. AccessionIDStudy -> Rep AccessionIDStudy x
$cto :: forall x. Rep AccessionIDStudy x -> AccessionIDStudy
to :: forall x. Rep AccessionIDStudy x -> AccessionIDStudy
Generic)

instance Show AccessionIDStudy where
    show :: AccessionIDStudy -> [Char]
show (AccessionIDStudy AccessionID
x) = AccessionID -> [Char]
forall a. Show a => a -> [Char]
show AccessionID
x

makeAccessionIDStudy :: MonadFail m => String -> m AccessionIDStudy
makeAccessionIDStudy :: forall (m :: * -> *). MonadFail m => [Char] -> m AccessionIDStudy
makeAccessionIDStudy [Char]
x = do
    AccessionID
accsID <- [Char] -> m AccessionID
forall (m :: * -> *). MonadFail m => [Char] -> m AccessionID
makeAccessionID [Char]
x
    case AccessionID
accsID of
        (INSDCProject [Char]
y) -> AccessionIDStudy -> m AccessionIDStudy
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AccessionIDStudy -> m AccessionIDStudy)
-> AccessionIDStudy -> m AccessionIDStudy
forall a b. (a -> b) -> a -> b
$ AccessionID -> AccessionIDStudy
AccessionIDStudy ([Char] -> AccessionID
INSDCProject [Char]
y)
        (INSDCStudy [Char]
y)   -> AccessionIDStudy -> m AccessionIDStudy
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AccessionIDStudy -> m AccessionIDStudy)
-> AccessionIDStudy -> m AccessionIDStudy
forall a b. (a -> b) -> a -> b
$ AccessionID -> AccessionIDStudy
AccessionIDStudy ([Char] -> AccessionID
INSDCStudy [Char]
y)
        AccessionID
_                -> [Char] -> m AccessionIDStudy
forall a. [Char] -> m a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> m AccessionIDStudy) -> [Char] -> m AccessionIDStudy
forall a b. (a -> b) -> a -> b
$ [Char]
"Accession " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> [Char]
show [Char]
x [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
" not a correct project/study accession"

instance Csv.ToField AccessionIDStudy where
    toField :: AccessionIDStudy -> ByteString
toField AccessionIDStudy
x = [Char] -> ByteString
forall a. ToField a => a -> ByteString
Csv.toField ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ AccessionIDStudy -> [Char]
forall a. Show a => a -> [Char]
show AccessionIDStudy
x
instance Csv.FromField AccessionIDStudy where
    parseField :: ByteString -> Parser AccessionIDStudy
parseField ByteString
x = ByteString -> Parser [Char]
forall a. FromField a => ByteString -> Parser a
Csv.parseField ByteString
x Parser [Char]
-> ([Char] -> Parser AccessionIDStudy) -> Parser AccessionIDStudy
forall a b. Parser a -> (a -> Parser b) -> Parser b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [Char] -> Parser AccessionIDStudy
forall (m :: * -> *). MonadFail m => [Char] -> m AccessionIDStudy
makeAccessionIDStudy

-- | A datatype for calendar dates
newtype SimpleDate = SimpleDate Day
    deriving (SimpleDate -> SimpleDate -> Bool
(SimpleDate -> SimpleDate -> Bool)
-> (SimpleDate -> SimpleDate -> Bool) -> Eq SimpleDate
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SimpleDate -> SimpleDate -> Bool
== :: SimpleDate -> SimpleDate -> Bool
$c/= :: SimpleDate -> SimpleDate -> Bool
/= :: SimpleDate -> SimpleDate -> Bool
Eq, Eq SimpleDate
Eq SimpleDate
-> (SimpleDate -> SimpleDate -> Ordering)
-> (SimpleDate -> SimpleDate -> Bool)
-> (SimpleDate -> SimpleDate -> Bool)
-> (SimpleDate -> SimpleDate -> Bool)
-> (SimpleDate -> SimpleDate -> Bool)
-> (SimpleDate -> SimpleDate -> SimpleDate)
-> (SimpleDate -> SimpleDate -> SimpleDate)
-> Ord SimpleDate
SimpleDate -> SimpleDate -> Bool
SimpleDate -> SimpleDate -> Ordering
SimpleDate -> SimpleDate -> SimpleDate
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: SimpleDate -> SimpleDate -> Ordering
compare :: SimpleDate -> SimpleDate -> Ordering
$c< :: SimpleDate -> SimpleDate -> Bool
< :: SimpleDate -> SimpleDate -> Bool
$c<= :: SimpleDate -> SimpleDate -> Bool
<= :: SimpleDate -> SimpleDate -> Bool
$c> :: SimpleDate -> SimpleDate -> Bool
> :: SimpleDate -> SimpleDate -> Bool
$c>= :: SimpleDate -> SimpleDate -> Bool
>= :: SimpleDate -> SimpleDate -> Bool
$cmax :: SimpleDate -> SimpleDate -> SimpleDate
max :: SimpleDate -> SimpleDate -> SimpleDate
$cmin :: SimpleDate -> SimpleDate -> SimpleDate
min :: SimpleDate -> SimpleDate -> SimpleDate
Ord, (forall x. SimpleDate -> Rep SimpleDate x)
-> (forall x. Rep SimpleDate x -> SimpleDate) -> Generic SimpleDate
forall x. Rep SimpleDate x -> SimpleDate
forall x. SimpleDate -> Rep SimpleDate x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. SimpleDate -> Rep SimpleDate x
from :: forall x. SimpleDate -> Rep SimpleDate x
$cto :: forall x. Rep SimpleDate x -> SimpleDate
to :: forall x. Rep SimpleDate x -> SimpleDate
Generic)

instance Show SimpleDate where
    show :: SimpleDate -> [Char]
show (SimpleDate Day
x) = TimeLocale -> [Char] -> Day -> [Char]
forall t. FormatTime t => TimeLocale -> [Char] -> t -> [Char]
formatTime TimeLocale
defaultTimeLocale [Char]
"%Y-%-m-%-d" Day
x

makeSimpleDate :: MonadFail m => String -> m SimpleDate
makeSimpleDate :: forall (m :: * -> *). MonadFail m => [Char] -> m SimpleDate
makeSimpleDate [Char]
x = do
    Day
mday <- Bool -> TimeLocale -> [Char] -> [Char] -> m Day
forall (m :: * -> *) t.
(MonadFail m, ParseTime t) =>
Bool -> TimeLocale -> [Char] -> [Char] -> m t
parseTimeM Bool
False TimeLocale
defaultTimeLocale [Char]
"%Y-%-m-%-d" [Char]
x
    SimpleDate -> m SimpleDate
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Day -> SimpleDate
SimpleDate Day
mday)

instance Csv.ToField SimpleDate where
    toField :: SimpleDate -> ByteString
toField (SimpleDate Day
x) = [Char] -> ByteString
forall a. ToField a => a -> ByteString
Csv.toField ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ Day -> [Char]
forall a. Show a => a -> [Char]
show Day
x
instance Csv.FromField SimpleDate where
    parseField :: ByteString -> Parser SimpleDate
parseField ByteString
x = ByteString -> Parser [Char]
forall a. FromField a => ByteString -> Parser a
Csv.parseField ByteString
x Parser [Char] -> ([Char] -> Parser SimpleDate) -> Parser SimpleDate
forall a b. Parser a -> (a -> Parser b) -> Parser b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [Char] -> Parser SimpleDate
forall (m :: * -> *). MonadFail m => [Char] -> m SimpleDate
makeSimpleDate

-- | A datatype to represent MD5 hashes
newtype MD5 = MD5 String
    deriving (MD5 -> MD5 -> Bool
(MD5 -> MD5 -> Bool) -> (MD5 -> MD5 -> Bool) -> Eq MD5
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MD5 -> MD5 -> Bool
== :: MD5 -> MD5 -> Bool
$c/= :: MD5 -> MD5 -> Bool
/= :: MD5 -> MD5 -> Bool
Eq, Eq MD5
Eq MD5
-> (MD5 -> MD5 -> Ordering)
-> (MD5 -> MD5 -> Bool)
-> (MD5 -> MD5 -> Bool)
-> (MD5 -> MD5 -> Bool)
-> (MD5 -> MD5 -> Bool)
-> (MD5 -> MD5 -> MD5)
-> (MD5 -> MD5 -> MD5)
-> Ord MD5
MD5 -> MD5 -> Bool
MD5 -> MD5 -> Ordering
MD5 -> MD5 -> MD5
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: MD5 -> MD5 -> Ordering
compare :: MD5 -> MD5 -> Ordering
$c< :: MD5 -> MD5 -> Bool
< :: MD5 -> MD5 -> Bool
$c<= :: MD5 -> MD5 -> Bool
<= :: MD5 -> MD5 -> Bool
$c> :: MD5 -> MD5 -> Bool
> :: MD5 -> MD5 -> Bool
$c>= :: MD5 -> MD5 -> Bool
>= :: MD5 -> MD5 -> Bool
$cmax :: MD5 -> MD5 -> MD5
max :: MD5 -> MD5 -> MD5
$cmin :: MD5 -> MD5 -> MD5
min :: MD5 -> MD5 -> MD5
Ord, (forall x. MD5 -> Rep MD5 x)
-> (forall x. Rep MD5 x -> MD5) -> Generic MD5
forall x. Rep MD5 x -> MD5
forall x. MD5 -> Rep MD5 x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. MD5 -> Rep MD5 x
from :: forall x. MD5 -> Rep MD5 x
$cto :: forall x. Rep MD5 x -> MD5
to :: forall x. Rep MD5 x -> MD5
Generic)

instance Show MD5 where
    show :: MD5 -> [Char]
show (MD5 [Char]
x) = [Char]
x

makeMD5 :: MonadFail m => String -> m MD5
makeMD5 :: forall (m :: * -> *). MonadFail m => [Char] -> m MD5
makeMD5 [Char]
x
    | [Char] -> Bool
isMD5Hash [Char]
x = MD5 -> m MD5
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (MD5 -> m MD5) -> MD5 -> m MD5
forall a b. (a -> b) -> a -> b
$ [Char] -> MD5
MD5 [Char]
x
    | Bool
otherwise   = [Char] -> m MD5
forall a. [Char] -> m a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> m MD5) -> [Char] -> m MD5
forall a b. (a -> b) -> a -> b
$ [Char]
"MD5 hash " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> [Char]
show [Char]
x [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
" not well structured"

isMD5Hash :: String -> Bool
isMD5Hash :: [Char] -> Bool
isMD5Hash [Char]
x = [Char] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Char]
x Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
32 Bool -> Bool -> Bool
&& (Char -> Bool) -> [Char] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isHexDigit [Char]
x

instance Csv.ToField MD5 where
    toField :: MD5 -> ByteString
toField MD5
x = [Char] -> ByteString
forall a. ToField a => a -> ByteString
Csv.toField ([Char] -> ByteString) -> [Char] -> ByteString
forall a b. (a -> b) -> a -> b
$ MD5 -> [Char]
forall a. Show a => a -> [Char]
show MD5
x
instance Csv.FromField MD5 where
    parseField :: ByteString -> Parser MD5
parseField ByteString
x = ByteString -> Parser [Char]
forall a. FromField a => ByteString -> Parser a
Csv.parseField ByteString
x Parser [Char] -> ([Char] -> Parser MD5) -> Parser MD5
forall a b. Parser a -> (a -> Parser b) -> Parser b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [Char] -> Parser MD5
forall (m :: * -> *). MonadFail m => [Char] -> m MD5
makeMD5

-- | A data type to represent a row in the seqSourceFile
-- See https://github.com/poseidon-framework/poseidon2-schema/blob/master/seqSourceFile_columns.tsv
-- for more details
data SeqSourceRow = SeqSourceRow
    { SeqSourceRow -> Maybe JannoStringList
sPoseidonID               :: Maybe JannoStringList
    , SeqSourceRow -> Maybe SSFUDG
sUDG                      :: Maybe SSFUDG
    , SeqSourceRow -> Maybe SSFLibraryBuilt
sLibraryBuilt             :: Maybe SSFLibraryBuilt
    , SeqSourceRow -> Maybe AccessionIDSample
sSampleAccession          :: Maybe AccessionIDSample
    , SeqSourceRow -> Maybe AccessionIDStudy
sStudyAccession           :: Maybe AccessionIDStudy
    , SeqSourceRow -> Maybe AccessionIDRun
sRunAccession             :: Maybe AccessionIDRun
    , SeqSourceRow -> Maybe [Char]
sSampleAlias              :: Maybe String
    , SeqSourceRow -> Maybe [Char]
sSecondarySampleAccession :: Maybe String
    , SeqSourceRow -> Maybe SimpleDate
sFirstPublic              :: Maybe SimpleDate
    , SeqSourceRow -> Maybe SimpleDate
sLastUpdated              :: Maybe SimpleDate
    , SeqSourceRow -> Maybe [Char]
sInstrumentModel          :: Maybe String
    , SeqSourceRow -> Maybe [Char]
sLibraryLayout            :: Maybe String
    , SeqSourceRow -> Maybe [Char]
sLibrarySource            :: Maybe String
    , SeqSourceRow -> Maybe [Char]
sInstrumentPlatform       :: Maybe String
    , SeqSourceRow -> Maybe [Char]
sLibraryName              :: Maybe String
    , SeqSourceRow -> Maybe [Char]
sLibraryStrategy          :: Maybe String
    , SeqSourceRow -> Maybe (ListColumn JURI)
sFastqFTP                 :: Maybe (ListColumn JURI)
    , SeqSourceRow -> Maybe (ListColumn JURI)
sFastqASPERA              :: Maybe (ListColumn JURI)
    , SeqSourceRow -> Maybe (ListColumn Integer)
sFastqBytes               :: Maybe (ListColumn Integer) -- integer, not int, because it can be a very large number
    , SeqSourceRow -> Maybe (ListColumn MD5)
sFastqMD5                 :: Maybe (ListColumn MD5)
    , SeqSourceRow -> Maybe Integer
sReadCount                :: Maybe Integer             -- integer, not int, because it can be a very large number
    , SeqSourceRow -> Maybe (ListColumn JURI)
sSubmittedFTP             :: Maybe (ListColumn JURI)
    , SeqSourceRow -> CsvNamedRecord
sAdditionalColumns        :: CsvNamedRecord
    }
    deriving (Int -> SeqSourceRow -> ShowS
[SeqSourceRow] -> ShowS
SeqSourceRow -> [Char]
(Int -> SeqSourceRow -> ShowS)
-> (SeqSourceRow -> [Char])
-> ([SeqSourceRow] -> ShowS)
-> Show SeqSourceRow
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SeqSourceRow -> ShowS
showsPrec :: Int -> SeqSourceRow -> ShowS
$cshow :: SeqSourceRow -> [Char]
show :: SeqSourceRow -> [Char]
$cshowList :: [SeqSourceRow] -> ShowS
showList :: [SeqSourceRow] -> ShowS
Show, SeqSourceRow -> SeqSourceRow -> Bool
(SeqSourceRow -> SeqSourceRow -> Bool)
-> (SeqSourceRow -> SeqSourceRow -> Bool) -> Eq SeqSourceRow
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SeqSourceRow -> SeqSourceRow -> Bool
== :: SeqSourceRow -> SeqSourceRow -> Bool
$c/= :: SeqSourceRow -> SeqSourceRow -> Bool
/= :: SeqSourceRow -> SeqSourceRow -> Bool
Eq, (forall x. SeqSourceRow -> Rep SeqSourceRow x)
-> (forall x. Rep SeqSourceRow x -> SeqSourceRow)
-> Generic SeqSourceRow
forall x. Rep SeqSourceRow x -> SeqSourceRow
forall x. SeqSourceRow -> Rep SeqSourceRow x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. SeqSourceRow -> Rep SeqSourceRow x
from :: forall x. SeqSourceRow -> Rep SeqSourceRow x
$cto :: forall x. Rep SeqSourceRow x -> SeqSourceRow
to :: forall x. Rep SeqSourceRow x -> SeqSourceRow
Generic)

-- This header also defines the output column order when writing to csv!
seqSourceHeader :: [Bchs.ByteString]
seqSourceHeader :: [ByteString]
seqSourceHeader = [
      ByteString
"poseidon_IDs"
    , ByteString
"udg"
    , ByteString
"library_built"
    , ByteString
"sample_accession"
    , ByteString
"study_accession"
    , ByteString
"run_accession"
    , ByteString
"sample_alias"
    , ByteString
"secondary_sample_accession"
    , ByteString
"first_public"
    , ByteString
"last_updated"
    , ByteString
"instrument_model"
    , ByteString
"library_layout"
    , ByteString
"library_source"
    , ByteString
"instrument_platform"
    , ByteString
"library_name"
    , ByteString
"library_strategy"
    , ByteString
"fastq_ftp"
    , ByteString
"fastq_aspera"
    , ByteString
"fastq_bytes"
    , ByteString
"fastq_md5"
    , ByteString
"read_count"
    , ByteString
"submitted_ftp"
    ]

instance Csv.DefaultOrdered SeqSourceRow where
    headerOrder :: SeqSourceRow -> Header
headerOrder SeqSourceRow
_ = [ByteString] -> Header
Csv.header [ByteString]
seqSourceHeader

seqSourceHeaderString :: [String]
seqSourceHeaderString :: [[Char]]
seqSourceHeaderString = (ByteString -> [Char]) -> [ByteString] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ByteString -> [Char]
Bchs.unpack [ByteString]
seqSourceHeader

-- This hashmap represents an empty seqSourceFile with all normal, specified columns
seqSourceRefHashMap :: HM.HashMap Bchs.ByteString ()
seqSourceRefHashMap :: HashMap ByteString ()
seqSourceRefHashMap = [(ByteString, ())] -> HashMap ByteString ()
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HM.fromList ([(ByteString, ())] -> HashMap ByteString ())
-> [(ByteString, ())] -> HashMap ByteString ()
forall a b. (a -> b) -> a -> b
$ (ByteString -> (ByteString, ()))
-> [ByteString] -> [(ByteString, ())]
forall a b. (a -> b) -> [a] -> [b]
map (\ByteString
x -> (ByteString
x, ())) [ByteString]
seqSourceHeader

instance Csv.FromNamedRecord SeqSourceRow where
    parseNamedRecord :: HashMap ByteString ByteString -> Parser SeqSourceRow
parseNamedRecord HashMap ByteString ByteString
m = Maybe JannoStringList
-> Maybe SSFUDG
-> Maybe SSFLibraryBuilt
-> Maybe AccessionIDSample
-> Maybe AccessionIDStudy
-> Maybe AccessionIDRun
-> Maybe [Char]
-> Maybe [Char]
-> Maybe SimpleDate
-> Maybe SimpleDate
-> Maybe [Char]
-> Maybe [Char]
-> Maybe [Char]
-> Maybe [Char]
-> Maybe [Char]
-> Maybe [Char]
-> Maybe (ListColumn JURI)
-> Maybe (ListColumn JURI)
-> Maybe (ListColumn Integer)
-> Maybe (ListColumn MD5)
-> Maybe Integer
-> Maybe (ListColumn JURI)
-> CsvNamedRecord
-> SeqSourceRow
SeqSourceRow
        (Maybe JannoStringList
 -> Maybe SSFUDG
 -> Maybe SSFLibraryBuilt
 -> Maybe AccessionIDSample
 -> Maybe AccessionIDStudy
 -> Maybe AccessionIDRun
 -> Maybe [Char]
 -> Maybe [Char]
 -> Maybe SimpleDate
 -> Maybe SimpleDate
 -> Maybe [Char]
 -> Maybe [Char]
 -> Maybe [Char]
 -> Maybe [Char]
 -> Maybe [Char]
 -> Maybe [Char]
 -> Maybe (ListColumn JURI)
 -> Maybe (ListColumn JURI)
 -> Maybe (ListColumn Integer)
 -> Maybe (ListColumn MD5)
 -> Maybe Integer
 -> Maybe (ListColumn JURI)
 -> CsvNamedRecord
 -> SeqSourceRow)
-> Parser (Maybe JannoStringList)
-> Parser
     (Maybe SSFUDG
      -> Maybe SSFLibraryBuilt
      -> Maybe AccessionIDSample
      -> Maybe AccessionIDStudy
      -> Maybe AccessionIDRun
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe SimpleDate
      -> Maybe SimpleDate
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn Integer)
      -> Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe JannoStringList)
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"poseidon_IDs"
        Parser
  (Maybe SSFUDG
   -> Maybe SSFLibraryBuilt
   -> Maybe AccessionIDSample
   -> Maybe AccessionIDStudy
   -> Maybe AccessionIDRun
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe SimpleDate
   -> Maybe SimpleDate
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn Integer)
   -> Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe SSFUDG)
-> Parser
     (Maybe SSFLibraryBuilt
      -> Maybe AccessionIDSample
      -> Maybe AccessionIDStudy
      -> Maybe AccessionIDRun
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe SimpleDate
      -> Maybe SimpleDate
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn Integer)
      -> Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe SSFUDG)
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"udg"
        Parser
  (Maybe SSFLibraryBuilt
   -> Maybe AccessionIDSample
   -> Maybe AccessionIDStudy
   -> Maybe AccessionIDRun
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe SimpleDate
   -> Maybe SimpleDate
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn Integer)
   -> Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe SSFLibraryBuilt)
-> Parser
     (Maybe AccessionIDSample
      -> Maybe AccessionIDStudy
      -> Maybe AccessionIDRun
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe SimpleDate
      -> Maybe SimpleDate
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn Integer)
      -> Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe SSFLibraryBuilt)
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"library_built"
        Parser
  (Maybe AccessionIDSample
   -> Maybe AccessionIDStudy
   -> Maybe AccessionIDRun
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe SimpleDate
   -> Maybe SimpleDate
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn Integer)
   -> Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe AccessionIDSample)
-> Parser
     (Maybe AccessionIDStudy
      -> Maybe AccessionIDRun
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe SimpleDate
      -> Maybe SimpleDate
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn Integer)
      -> Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe AccessionIDSample)
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"sample_accession"
        Parser
  (Maybe AccessionIDStudy
   -> Maybe AccessionIDRun
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe SimpleDate
   -> Maybe SimpleDate
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn Integer)
   -> Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe AccessionIDStudy)
-> Parser
     (Maybe AccessionIDRun
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe SimpleDate
      -> Maybe SimpleDate
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn Integer)
      -> Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe AccessionIDStudy)
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"study_accession"
        Parser
  (Maybe AccessionIDRun
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe SimpleDate
   -> Maybe SimpleDate
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn Integer)
   -> Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe AccessionIDRun)
-> Parser
     (Maybe [Char]
      -> Maybe [Char]
      -> Maybe SimpleDate
      -> Maybe SimpleDate
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn Integer)
      -> Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe AccessionIDRun)
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser a
filterLookup         HashMap ByteString ByteString
m ByteString
"run_accession"
        Parser
  (Maybe [Char]
   -> Maybe [Char]
   -> Maybe SimpleDate
   -> Maybe SimpleDate
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn Integer)
   -> Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe [Char])
-> Parser
     (Maybe [Char]
      -> Maybe SimpleDate
      -> Maybe SimpleDate
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn Integer)
      -> Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe [Char])
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"sample_alias"
        Parser
  (Maybe [Char]
   -> Maybe SimpleDate
   -> Maybe SimpleDate
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn Integer)
   -> Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe [Char])
-> Parser
     (Maybe SimpleDate
      -> Maybe SimpleDate
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn Integer)
      -> Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe [Char])
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"secondary_sample_accession"
        Parser
  (Maybe SimpleDate
   -> Maybe SimpleDate
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn Integer)
   -> Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe SimpleDate)
-> Parser
     (Maybe SimpleDate
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn Integer)
      -> Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe SimpleDate)
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"first_public"
        Parser
  (Maybe SimpleDate
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn Integer)
   -> Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe SimpleDate)
-> Parser
     (Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn Integer)
      -> Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe SimpleDate)
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"last_updated"
        Parser
  (Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn Integer)
   -> Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe [Char])
-> Parser
     (Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn Integer)
      -> Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe [Char])
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"instrument_model"
        Parser
  (Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn Integer)
   -> Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe [Char])
-> Parser
     (Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn Integer)
      -> Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe [Char])
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"library_layout"
        Parser
  (Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn Integer)
   -> Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe [Char])
-> Parser
     (Maybe [Char]
      -> Maybe [Char]
      -> Maybe [Char]
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn Integer)
      -> Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe [Char])
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"library_source"
        Parser
  (Maybe [Char]
   -> Maybe [Char]
   -> Maybe [Char]
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn Integer)
   -> Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe [Char])
-> Parser
     (Maybe [Char]
      -> Maybe [Char]
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn Integer)
      -> Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe [Char])
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"instrument_platform"
        Parser
  (Maybe [Char]
   -> Maybe [Char]
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn Integer)
   -> Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe [Char])
-> Parser
     (Maybe [Char]
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn Integer)
      -> Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe [Char])
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"library_name"
        Parser
  (Maybe [Char]
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn Integer)
   -> Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe [Char])
-> Parser
     (Maybe (ListColumn JURI)
      -> Maybe (ListColumn JURI)
      -> Maybe (ListColumn Integer)
      -> Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe [Char])
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"library_strategy"
        Parser
  (Maybe (ListColumn JURI)
   -> Maybe (ListColumn JURI)
   -> Maybe (ListColumn Integer)
   -> Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe (ListColumn JURI))
-> Parser
     (Maybe (ListColumn JURI)
      -> Maybe (ListColumn Integer)
      -> Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe (ListColumn JURI))
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"fastq_ftp"
        Parser
  (Maybe (ListColumn JURI)
   -> Maybe (ListColumn Integer)
   -> Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe (ListColumn JURI))
-> Parser
     (Maybe (ListColumn Integer)
      -> Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe (ListColumn JURI))
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"fastq_aspera"
        Parser
  (Maybe (ListColumn Integer)
   -> Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe (ListColumn Integer))
-> Parser
     (Maybe (ListColumn MD5)
      -> Maybe Integer
      -> Maybe (ListColumn JURI)
      -> CsvNamedRecord
      -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe (ListColumn Integer))
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"fastq_bytes"
        Parser
  (Maybe (ListColumn MD5)
   -> Maybe Integer
   -> Maybe (ListColumn JURI)
   -> CsvNamedRecord
   -> SeqSourceRow)
-> Parser (Maybe (ListColumn MD5))
-> Parser
     (Maybe Integer
      -> Maybe (ListColumn JURI) -> CsvNamedRecord -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe (ListColumn MD5))
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"fastq_md5"
        Parser
  (Maybe Integer
   -> Maybe (ListColumn JURI) -> CsvNamedRecord -> SeqSourceRow)
-> Parser (Maybe Integer)
-> Parser
     (Maybe (ListColumn JURI) -> CsvNamedRecord -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe Integer)
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"read_count"
        Parser (Maybe (ListColumn JURI) -> CsvNamedRecord -> SeqSourceRow)
-> Parser (Maybe (ListColumn JURI))
-> Parser (CsvNamedRecord -> SeqSourceRow)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap ByteString ByteString
-> ByteString -> Parser (Maybe (ListColumn JURI))
forall a.
FromField a =>
HashMap ByteString ByteString -> ByteString -> Parser (Maybe a)
filterLookupOptional HashMap ByteString ByteString
m ByteString
"submitted_ftp"
        -- beyond that read everything that is not in the set of defined variables
        -- as a separate hashmap
        Parser (CsvNamedRecord -> SeqSourceRow)
-> Parser CsvNamedRecord -> Parser SeqSourceRow
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> CsvNamedRecord -> Parser CsvNamedRecord
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (HashMap ByteString ByteString -> CsvNamedRecord
CsvNamedRecord (HashMap ByteString ByteString
m HashMap ByteString ByteString
-> HashMap ByteString () -> HashMap ByteString ByteString
forall k v w.
(Eq k, Hashable k) =>
HashMap k v -> HashMap k w -> HashMap k v
`HM.difference` HashMap ByteString ()
seqSourceRefHashMap))

instance Csv.ToNamedRecord SeqSourceRow where
    toNamedRecord :: SeqSourceRow -> HashMap ByteString ByteString
toNamedRecord SeqSourceRow
s = [(ByteString, ByteString)] -> HashMap ByteString ByteString
Csv.namedRecord [
          ByteString
"poseidon_IDs"               ByteString -> Maybe JannoStringList -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe JannoStringList
sPoseidonID SeqSourceRow
s
        , ByteString
"udg"                        ByteString -> Maybe SSFUDG -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe SSFUDG
sUDG SeqSourceRow
s
        , ByteString
"library_built"              ByteString -> Maybe SSFLibraryBuilt -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe SSFLibraryBuilt
sLibraryBuilt SeqSourceRow
s
        , ByteString
"sample_accession"           ByteString -> Maybe AccessionIDSample -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe AccessionIDSample
sSampleAccession SeqSourceRow
s
        , ByteString
"study_accession"            ByteString -> Maybe AccessionIDStudy -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe AccessionIDStudy
sStudyAccession SeqSourceRow
s
        , ByteString
"run_accession"              ByteString -> Maybe AccessionIDRun -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe AccessionIDRun
sRunAccession SeqSourceRow
s
        , ByteString
"sample_alias"               ByteString -> Maybe [Char] -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe [Char]
sSampleAlias SeqSourceRow
s
        , ByteString
"secondary_sample_accession" ByteString -> Maybe [Char] -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe [Char]
sSecondarySampleAccession SeqSourceRow
s
        , ByteString
"first_public"               ByteString -> Maybe SimpleDate -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe SimpleDate
sFirstPublic SeqSourceRow
s
        , ByteString
"last_updated"               ByteString -> Maybe SimpleDate -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe SimpleDate
sLastUpdated SeqSourceRow
s
        , ByteString
"instrument_model"           ByteString -> Maybe [Char] -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe [Char]
sInstrumentModel SeqSourceRow
s
        , ByteString
"library_layout"             ByteString -> Maybe [Char] -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe [Char]
sLibraryLayout SeqSourceRow
s
        , ByteString
"library_source"             ByteString -> Maybe [Char] -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe [Char]
sLibrarySource SeqSourceRow
s
        , ByteString
"instrument_platform"        ByteString -> Maybe [Char] -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe [Char]
sInstrumentPlatform SeqSourceRow
s
        , ByteString
"library_name"               ByteString -> Maybe [Char] -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe [Char]
sLibraryName SeqSourceRow
s
        , ByteString
"library_strategy"           ByteString -> Maybe [Char] -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe [Char]
sLibraryStrategy SeqSourceRow
s
        , ByteString
"fastq_ftp"                  ByteString -> Maybe (ListColumn JURI) -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe (ListColumn JURI)
sFastqFTP SeqSourceRow
s
        , ByteString
"fastq_aspera"               ByteString -> Maybe (ListColumn JURI) -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe (ListColumn JURI)
sFastqASPERA SeqSourceRow
s
        , ByteString
"fastq_bytes"                ByteString
-> Maybe (ListColumn Integer) -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe (ListColumn Integer)
sFastqBytes SeqSourceRow
s
        , ByteString
"fastq_md5"                  ByteString -> Maybe (ListColumn MD5) -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe (ListColumn MD5)
sFastqMD5 SeqSourceRow
s
        , ByteString
"read_count"                 ByteString -> Maybe Integer -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe Integer
sReadCount SeqSourceRow
s
        , ByteString
"submitted_ftp"              ByteString -> Maybe (ListColumn JURI) -> (ByteString, ByteString)
forall a. ToField a => ByteString -> a -> (ByteString, ByteString)
Csv..= SeqSourceRow -> Maybe (ListColumn JURI)
sSubmittedFTP SeqSourceRow
s
        -- beyond that add what is in the hashmap of additional columns
        ] HashMap ByteString ByteString
-> HashMap ByteString ByteString -> HashMap ByteString ByteString
forall k v.
(Eq k, Hashable k) =>
HashMap k v -> HashMap k v -> HashMap k v
`HM.union` (CsvNamedRecord -> HashMap ByteString ByteString
getCsvNR (CsvNamedRecord -> HashMap ByteString ByteString)
-> CsvNamedRecord -> HashMap ByteString ByteString
forall a b. (a -> b) -> a -> b
$ SeqSourceRow -> CsvNamedRecord
sAdditionalColumns SeqSourceRow
s)

-- | A function to write one seqSourceFile
writeSeqSourceFile :: FilePath -> SeqSourceRows -> IO ()
writeSeqSourceFile :: [Char] -> SeqSourceRows -> IO ()
writeSeqSourceFile [Char]
path (SeqSourceRows [SeqSourceRow]
rows) = do
    let seqSourceAsBytestring :: ByteString
seqSourceAsBytestring = EncodeOptions -> Header -> [SeqSourceRow] -> ByteString
forall a.
ToNamedRecord a =>
EncodeOptions -> Header -> [a] -> ByteString
Csv.encodeByNameWith EncodeOptions
encodingOptions Header
makeHeaderWithAdditionalColumns [SeqSourceRow]
rows
    let seqSourceAsBytestringwithNA :: ByteString
seqSourceAsBytestringwithNA = ByteString -> ByteString
explicitNA ByteString
seqSourceAsBytestring
    [Char] -> ByteString -> IO ()
Bch.writeFile [Char]
path ByteString
seqSourceAsBytestringwithNA
    where
        makeHeaderWithAdditionalColumns :: Csv.Header
        makeHeaderWithAdditionalColumns :: Header
makeHeaderWithAdditionalColumns =
            [ByteString] -> Header
forall a. [a] -> Vector a
V.fromList ([ByteString] -> Header) -> [ByteString] -> Header
forall a b. (a -> b) -> a -> b
$ [ByteString]
seqSourceHeader [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ [ByteString] -> [ByteString]
forall a. Ord a => [a] -> [a]
sort (HashMap ByteString ByteString -> [ByteString]
forall k v. HashMap k v -> [k]
HM.keys ([HashMap ByteString ByteString] -> HashMap ByteString ByteString
forall k v. (Eq k, Hashable k) => [HashMap k v] -> HashMap k v
HM.unions ((SeqSourceRow -> HashMap ByteString ByteString)
-> [SeqSourceRow] -> [HashMap ByteString ByteString]
forall a b. (a -> b) -> [a] -> [b]
map (CsvNamedRecord -> HashMap ByteString ByteString
getCsvNR (CsvNamedRecord -> HashMap ByteString ByteString)
-> (SeqSourceRow -> CsvNamedRecord)
-> SeqSourceRow
-> HashMap ByteString ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SeqSourceRow -> CsvNamedRecord
sAdditionalColumns) [SeqSourceRow]
rows)))

-- | A function to read one seqSourceFile
readSeqSourceFile :: FilePath -> PoseidonIO SeqSourceRows
readSeqSourceFile :: [Char] -> PoseidonIO SeqSourceRows
readSeqSourceFile [Char]
seqSourcePath = do
    [Char] -> PoseidonIO ()
logDebug ([Char] -> PoseidonIO ()) -> [Char] -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ [Char]
"Reading: " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
seqSourcePath
    ByteString
seqSourceFile <- 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
$ [Char] -> IO ByteString
Bch.readFile [Char]
seqSourcePath
    let seqSourceFileRows :: [ByteString]
seqSourceFileRows = ByteString -> [ByteString]
Bch.lines ByteString
seqSourceFile
    Bool -> PoseidonIO () -> PoseidonIO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([ByteString] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [ByteString]
seqSourceFileRows Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
2) (PoseidonIO () -> PoseidonIO ()) -> PoseidonIO () -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ 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
$ PoseidonException -> IO ()
forall e a. Exception e => e -> IO a
throwIO (PoseidonException -> IO ()) -> PoseidonException -> IO ()
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char] -> PoseidonException
PoseidonFileConsistencyException [Char]
seqSourcePath [Char]
"File has less than two lines"
    [Char] -> PoseidonIO ()
logDebug ([Char] -> PoseidonIO ()) -> [Char] -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ Int -> [Char]
forall a. Show a => a -> [Char]
show ([ByteString] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [ByteString]
seqSourceFileRows Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
" sequencing entities in this file"
    -- tupel with row number and row bytestring
    let seqSourceFileRowsWithNumber :: [(Int, ByteString)]
seqSourceFileRowsWithNumber = [Int] -> [ByteString] -> [(Int, ByteString)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
1..([ByteString] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [ByteString]
seqSourceFileRows)] [ByteString]
seqSourceFileRows
    -- filter out empty lines
        seqSourceFileRowsWithNumberFiltered :: [(Int, ByteString)]
seqSourceFileRowsWithNumberFiltered = ((Int, ByteString) -> Bool)
-> [(Int, ByteString)] -> [(Int, ByteString)]
forall a. (a -> Bool) -> [a] -> [a]
filter (\(Int
_, ByteString
y) -> ByteString
y ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
/= ByteString
Bch.empty) [(Int, ByteString)]
seqSourceFileRowsWithNumber
    -- create header + individual line combination
        headerOnlyPotentiallyWithQuotes :: ByteString
headerOnlyPotentiallyWithQuotes = (Int, ByteString) -> ByteString
forall a b. (a, b) -> b
snd ((Int, ByteString) -> ByteString)
-> (Int, ByteString) -> ByteString
forall a b. (a -> b) -> a -> b
$ [(Int, ByteString)] -> (Int, ByteString)
forall a. HasCallStack => [a] -> a
head [(Int, ByteString)]
seqSourceFileRowsWithNumberFiltered
        -- removing the quotes like this might cause issues in edge cases
        headerOnly :: ByteString
headerOnly = (Char -> Bool) -> ByteString -> ByteString
Bch.filter (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'"') ByteString
headerOnlyPotentiallyWithQuotes
        rowsOnly :: [(Int, ByteString)]
rowsOnly = [(Int, ByteString)] -> [(Int, ByteString)]
forall a. HasCallStack => [a] -> [a]
tail [(Int, ByteString)]
seqSourceFileRowsWithNumberFiltered
        seqSourceFileRowsWithHeader :: [(Int, ByteString)]
seqSourceFileRowsWithHeader = ((Int, ByteString) -> (Int, ByteString))
-> [(Int, ByteString)] -> [(Int, ByteString)]
forall a b. (a -> b) -> [a] -> [b]
map ((ByteString -> ByteString)
-> (Int, ByteString) -> (Int, ByteString)
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (\ByteString
x -> ByteString
headerOnly ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
"\n" ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
x)) [(Int, ByteString)]
rowsOnly
    -- read seqSourceFile by rows
    [Either PoseidonException SeqSourceRow]
seqSourceRepresentation <- ((Int, ByteString)
 -> ReaderT Env IO (Either PoseidonException SeqSourceRow))
-> [(Int, ByteString)]
-> ReaderT Env IO [Either PoseidonException SeqSourceRow]
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]
-> (Int, ByteString)
-> ReaderT Env IO (Either PoseidonException SeqSourceRow)
readSeqSourceFileRow [Char]
seqSourcePath) [(Int, ByteString)]
seqSourceFileRowsWithHeader
    -- error case management
    if Bool -> Bool
not ([PoseidonException] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Either PoseidonException SeqSourceRow] -> [PoseidonException]
forall a b. [Either a b] -> [a]
lefts [Either PoseidonException SeqSourceRow]
seqSourceRepresentation))
    then do
        (PoseidonException -> PoseidonIO ())
-> [PoseidonException] -> PoseidonIO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ([Char] -> PoseidonIO ()
logError ([Char] -> PoseidonIO ())
-> (PoseidonException -> [Char])
-> PoseidonException
-> PoseidonIO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PoseidonException -> [Char]
renderPoseidonException) ([PoseidonException] -> PoseidonIO ())
-> [PoseidonException] -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ Int -> [PoseidonException] -> [PoseidonException]
forall a. Int -> [a] -> [a]
take Int
5 ([PoseidonException] -> [PoseidonException])
-> [PoseidonException] -> [PoseidonException]
forall a b. (a -> b) -> a -> b
$ [Either PoseidonException SeqSourceRow] -> [PoseidonException]
forall a b. [Either a b] -> [a]
lefts [Either PoseidonException SeqSourceRow]
seqSourceRepresentation
        IO SeqSourceRows -> PoseidonIO SeqSourceRows
forall a. IO a -> ReaderT Env IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO SeqSourceRows -> PoseidonIO SeqSourceRows)
-> IO SeqSourceRows -> PoseidonIO SeqSourceRows
forall a b. (a -> b) -> a -> b
$ PoseidonException -> IO SeqSourceRows
forall e a. Exception e => e -> IO a
throwIO (PoseidonException -> IO SeqSourceRows)
-> PoseidonException -> IO SeqSourceRows
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char] -> PoseidonException
PoseidonFileConsistencyException [Char]
seqSourcePath [Char]
"Broken lines."
    else do
        let seqSource :: SeqSourceRows
seqSource = [SeqSourceRow] -> SeqSourceRows
SeqSourceRows ([SeqSourceRow] -> SeqSourceRows)
-> [SeqSourceRow] -> SeqSourceRows
forall a b. (a -> b) -> a -> b
$ [Either PoseidonException SeqSourceRow] -> [SeqSourceRow]
forall a b. [Either a b] -> [b]
rights [Either PoseidonException SeqSourceRow]
seqSourceRepresentation
        [Char] -> SeqSourceRows -> PoseidonIO ()
warnSeqSourceConsistency [Char]
seqSourcePath SeqSourceRows
seqSource
        SeqSourceRows -> PoseidonIO SeqSourceRows
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return SeqSourceRows
seqSource

-- | A function to read one row of a seqSourceFile
readSeqSourceFileRow :: FilePath -> (Int, Bch.ByteString) -> PoseidonIO (Either PoseidonException SeqSourceRow)
readSeqSourceFileRow :: [Char]
-> (Int, ByteString)
-> ReaderT Env IO (Either PoseidonException SeqSourceRow)
readSeqSourceFileRow [Char]
seqSourcePath (Int
lineNumber, ByteString
row) = do
    let decoded :: Either [Char] (Header, Vector SeqSourceRow)
decoded = DecodeOptions
-> ByteString -> Either [Char] (Header, Vector SeqSourceRow)
forall a.
FromNamedRecord a =>
DecodeOptions -> ByteString -> Either [Char] (Header, Vector a)
Csv.decodeByNameWith DecodeOptions
decodingOptions ByteString
row
        simplifiedDecoded :: Either [Char] SeqSourceRow
simplifiedDecoded = (\(Header
_,Vector SeqSourceRow
rs) -> Vector SeqSourceRow -> SeqSourceRow
forall a. Vector a -> a
V.head Vector SeqSourceRow
rs) ((Header, Vector SeqSourceRow) -> SeqSourceRow)
-> Either [Char] (Header, Vector SeqSourceRow)
-> Either [Char] SeqSourceRow
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Either [Char] (Header, Vector SeqSourceRow)
decoded
    case Either [Char] SeqSourceRow
simplifiedDecoded of
        Left [Char]
e -> do
            let betterError :: [Char]
betterError = case Parsec [Char] () CsvParseError
-> [Char] -> [Char] -> Either ParseError CsvParseError
forall s t a.
Stream s Identity t =>
Parsec s () a -> [Char] -> s -> Either ParseError a
P.parse Parsec [Char] () CsvParseError
parseCsvParseError [Char]
"" [Char]
e of
                    Left ParseError
_       -> ShowS
removeUselessSuffix [Char]
e
                    Right CsvParseError
result -> CsvParseError -> [Char]
renderCsvParseError CsvParseError
result
            Either PoseidonException SeqSourceRow
-> ReaderT Env IO (Either PoseidonException SeqSourceRow)
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either PoseidonException SeqSourceRow
 -> ReaderT Env IO (Either PoseidonException SeqSourceRow))
-> Either PoseidonException SeqSourceRow
-> ReaderT Env IO (Either PoseidonException SeqSourceRow)
forall a b. (a -> b) -> a -> b
$ PoseidonException -> Either PoseidonException SeqSourceRow
forall a b. a -> Either a b
Left (PoseidonException -> Either PoseidonException SeqSourceRow)
-> PoseidonException -> Either PoseidonException SeqSourceRow
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char] -> [Char] -> PoseidonException
PoseidonFileRowException [Char]
seqSourcePath (Int -> [Char]
forall a. Show a => a -> [Char]
show Int
lineNumber) [Char]
betterError
        Right SeqSourceRow
seqSourceRow -> do
            Either PoseidonException SeqSourceRow
-> ReaderT Env IO (Either PoseidonException SeqSourceRow)
forall a. a -> ReaderT Env IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either PoseidonException SeqSourceRow
 -> ReaderT Env IO (Either PoseidonException SeqSourceRow))
-> Either PoseidonException SeqSourceRow
-> ReaderT Env IO (Either PoseidonException SeqSourceRow)
forall a b. (a -> b) -> a -> b
$ SeqSourceRow -> Either PoseidonException SeqSourceRow
forall a b. b -> Either a b
Right SeqSourceRow
seqSourceRow

-- Global SSF consistency checks

warnSeqSourceConsistency :: FilePath -> SeqSourceRows -> PoseidonIO ()
warnSeqSourceConsistency :: [Char] -> SeqSourceRows -> PoseidonIO ()
warnSeqSourceConsistency [Char]
seqSourcePath SeqSourceRows
xs = do
    Bool -> PoseidonIO () -> PoseidonIO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (SeqSourceRows -> Bool
checkRunsUnique SeqSourceRows
xs) (PoseidonIO () -> PoseidonIO ()) -> PoseidonIO () -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$
        [Char] -> PoseidonIO ()
logWarning ([Char] -> PoseidonIO ()) -> [Char] -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ [Char]
"Potential consistency issues in file " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
seqSourcePath [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
": " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++
                     [Char]
"The values in the run_accession column are not unique"
    Bool -> PoseidonIO () -> PoseidonIO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (SeqSourceRows -> Bool
checkAtLeastOnePoseidonID SeqSourceRows
xs) (PoseidonIO () -> PoseidonIO ()) -> PoseidonIO () -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$
        [Char] -> PoseidonIO ()
logWarning ([Char] -> PoseidonIO ()) -> [Char] -> PoseidonIO ()
forall a b. (a -> b) -> a -> b
$ [Char]
"Potential consistency issues in file " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
seqSourcePath [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [Char]
": " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++
                     [Char]
"The poseidon_IDs column is completely empty. Package and .ssf file are not linked"

checkRunsUnique :: SeqSourceRows -> Bool
checkRunsUnique :: SeqSourceRows -> Bool
checkRunsUnique (SeqSourceRows [SeqSourceRow]
rows) =
    let justRunAccessions :: [AccessionIDRun]
justRunAccessions = (SeqSourceRow -> Maybe AccessionIDRun)
-> [SeqSourceRow] -> [AccessionIDRun]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe SeqSourceRow -> Maybe AccessionIDRun
sRunAccession [SeqSourceRow]
rows
    in [AccessionIDRun]
justRunAccessions [AccessionIDRun] -> [AccessionIDRun] -> Bool
forall a. Eq a => a -> a -> Bool
== [AccessionIDRun] -> [AccessionIDRun]
forall a. Eq a => [a] -> [a]
nub [AccessionIDRun]
justRunAccessions

checkAtLeastOnePoseidonID :: SeqSourceRows -> Bool
checkAtLeastOnePoseidonID :: SeqSourceRows -> Bool
checkAtLeastOnePoseidonID (SeqSourceRows [SeqSourceRow]
rows) =
    (SeqSourceRow -> Bool) -> [SeqSourceRow] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Maybe JannoStringList -> Bool
forall a. Maybe a -> Bool
isJust (Maybe JannoStringList -> Bool)
-> (SeqSourceRow -> Maybe JannoStringList) -> SeqSourceRow -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SeqSourceRow -> Maybe JannoStringList
sPoseidonID) [SeqSourceRow]
rows