module Bio.Sequence.Basecalled.Type
  ( BasecalledSequence (..)
  , BasecalledSequenceWithRawData (..)
  ) where

import           Bio.Sequence (IsSequence (..), WeightedSequence)
import           Data.Coerce  (coerce)
import           Data.Int     (Int16)
import           Data.Vector  (Vector)

newtype BasecalledSequence = BasecalledSequence (WeightedSequence Double Char)
  deriving (BasecalledSequence -> BasecalledSequence -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BasecalledSequence -> BasecalledSequence -> Bool
$c/= :: BasecalledSequence -> BasecalledSequence -> Bool
== :: BasecalledSequence -> BasecalledSequence -> Bool
$c== :: BasecalledSequence -> BasecalledSequence -> Bool
Eq, Int -> BasecalledSequence -> ShowS
[BasecalledSequence] -> ShowS
BasecalledSequence -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BasecalledSequence] -> ShowS
$cshowList :: [BasecalledSequence] -> ShowS
show :: BasecalledSequence -> String
$cshow :: BasecalledSequence -> String
showsPrec :: Int -> BasecalledSequence -> ShowS
$cshowsPrec :: Int -> BasecalledSequence -> ShowS
Show)

data BasecalledSequenceWithRawData
  = BasecalledSequenceWithRawData
      { BasecalledSequenceWithRawData -> BasecalledSequence
bsSequence      :: BasecalledSequence
        -- A sequence with quality.
      , BasecalledSequenceWithRawData -> Vector Int16
bsRawG          :: Vector Int16
      , BasecalledSequenceWithRawData -> Vector Int16
bsRawA          :: Vector Int16
      , BasecalledSequenceWithRawData -> Vector Int16
bsRawT          :: Vector Int16
      , BasecalledSequenceWithRawData -> Vector Int16
bsRawC          :: Vector Int16
      , BasecalledSequenceWithRawData -> Vector Int
bsPeakLocations :: Vector Int
        -- ^ Same length as 'bsSequence'.
        --
        -- For every base in 'bsSequence' corresponding element in 'bsPeakLocations' is
        -- an index in one of the raw vectors.
      }
  deriving (BasecalledSequenceWithRawData
-> BasecalledSequenceWithRawData -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BasecalledSequenceWithRawData
-> BasecalledSequenceWithRawData -> Bool
$c/= :: BasecalledSequenceWithRawData
-> BasecalledSequenceWithRawData -> Bool
== :: BasecalledSequenceWithRawData
-> BasecalledSequenceWithRawData -> Bool
$c== :: BasecalledSequenceWithRawData
-> BasecalledSequenceWithRawData -> Bool
Eq, Int -> BasecalledSequenceWithRawData -> ShowS
[BasecalledSequenceWithRawData] -> ShowS
BasecalledSequenceWithRawData -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BasecalledSequenceWithRawData] -> ShowS
$cshowList :: [BasecalledSequenceWithRawData] -> ShowS
show :: BasecalledSequenceWithRawData -> String
$cshow :: BasecalledSequenceWithRawData -> String
showsPrec :: Int -> BasecalledSequenceWithRawData -> ShowS
$cshowsPrec :: Int -> BasecalledSequenceWithRawData -> ShowS
Show)

instance IsSequence BasecalledSequence where
  type Element BasecalledSequence = Char
  type Marking BasecalledSequence = ()
  type Weight BasecalledSequence  = Double

  toSequence :: BasecalledSequence
-> Sequence
     (Marking BasecalledSequence)
     (Weight BasecalledSequence)
     (Element BasecalledSequence)
toSequence = coerce :: forall a b. Coercible a b => a -> b
coerce
  fromSequence :: Sequence
  (Marking BasecalledSequence)
  (Weight BasecalledSequence)
  (Element BasecalledSequence)
-> BasecalledSequence
fromSequence = coerce :: forall a b. Coercible a b => a -> b
coerce