mkContactMap' :: PrimMonad m => BED3 -> Int -> Int -> Sink Bam1 m (U.Vector Int)
mkContactMap' (BED3 chr s e) w extend = do
    vec <- lift $ GM.replicate vecLen 0
    loop vec
    lift . liftM (G.map (`div` 2)) . G.unsafeFreeze $ vec
  where
    n = (e - s) `div` w
    e' = n * w
    vecLen = n * (n+1) `div` 2
    loop v = do
        x <- await
        case x of
            Just bam ->
                let flag = do bamChr <- targetName bam
                              matChr <- mateTargetName bam
                              return $ bamChr == chr && matChr == chr
                in case flag of
                    Just True -> do
                        let (p, pMate) = getStarts bam
                            a = (p - s) `div` w
                            b = (pMate - s) `div` w
                            i | a < b = idx a b
                              | otherwise = idx b a
                        when (p >= s && pMate >= s && p < e' && pMate < e') $ 
                            lift $ GM.read v i >>= GM.write v i . (+1)
                        loop v
                    _ -> loop v
            _ -> return ()
    idx i j = i * (2 * n - i + 1) `div` 2 + j - i

-- | get starting location of bam and its mate
mkContactMap' :: PrimMonad m => BED3 -> Int -> Int -> Sink Bam1 m (U.Vector Int)
mkContactMap' (BED3 chr s e) w extend = do
    vec <- lift $ GM.replicate vecLen 0
    loop vec
    lift . liftM (G.map (`div` 2)) . G.unsafeFreeze $ vec
  where
    n = (e - s) `div` w
    e' = n * w
    vecLen = n * (n+1) `div` 2
    loop v = do
        x <- await
        case x of
            Just bam ->
                let flag = do bamChr <- targetName bam
                              matChr <- mateTargetName bam
                              return $ bamChr == chr && matChr == chr
                in case flag of
                    Just True -> do
                        let (p, pMate) = getStarts bam
                            a = (p - s) `div` w
                            b = (pMate - s) `div` w
                            i | a < b = idx a b
                              | otherwise = idx b a
                        when (p >= s && pMate >= s && p < e' && pMate < e') $ 
                            lift $ GM.read v i >>= GM.write v i . (+1)
                        loop v
                    _ -> loop v
            _ -> return ()
    idx i j = i * (2 * n - i + 1) `div` 2 + j - i

-- | get starting location of bam and its mate
mkContactMap' (BED3 chr s e) w extend = do
    vec <- lift $ GM.replicate vecLen 0
    loop vec
    lift . liftM (G.map (`div` 2)) . G.unsafeFreeze $ vec
  where
    n = (e - s) `div` w
    e' = n * w
    vecLen = n * (n+1) `div` 2
    loop v = do
        x <- await
        case x of
            Just bam ->
                let flag = do bamChr <- targetName bam
                              matChr <- mateTargetName bam
                              return $ bamChr == chr && matChr == chr
                in case flag of
                    Just True -> do
                        let (p, pMate) = getStarts bam
                            a = (p - s) `div` w
                            b = (pMate - s) `div` w
                            i | a < b = idx a b
                              | otherwise = idx b a
                        when (p >= s && pMate >= s && p < e' && pMate < e') $ 
                            lift $ GM.read v i >>= GM.write v i . (+1)
                        loop v
                    _ -> loop v
            _ -> return ()
    idx i j = i * (2 * n - i + 1) `div` 2 + j - i

-- | get starting location of bam and its mate