{-# LANGUAGE RecordWildCards #-} module BioInf.RNAwolf.Interior where import qualified Data.Vector.Unboxed as VU import Biobase.Primary import Biobase.Secondary import Data.PrimitiveArray import Data.PrimitiveArray.Ix import BioInf.Params import BioInf.RNAwolf.Types import Debug.Trace -- * Outer part -- | The outer part of an interior loop. Given a certain basepair type, add the -- cost from the unpaired part. fInteriorOuter :: BaseF (NInteLoop -> ExtFeatures (VU.Vector (PairIdx,Double))) fInteriorOuter Params{..} inp (NInteLoop nInteLoop) i j ct eI eJ | j-i<4 = VU.empty | otherwise = VU.map f $ VU.singleton (i,j) where f (k,l) = ( (i,j) , nInteLoop ! (i,j) + ijSc -- + if j-i-1<=maxDistance then pairDistance ! (j-i-1) else 0 ) ijSc = interiorClose ! (((nI,nJ),(ct,eI,eJ)),nIp1,nJm1) -- ijSc = interiorClose ! (((nN,nN),(cis,wc,wc)),nN,nN) nI = inp VU.! i nJ = inp VU.! j nIp1 = inp VU.! (i+1) nJm1 = inp VU.! (j-1) {-# INLINE fInteriorOuter #-} -- | btInteriorOuter :: Params -> Primary -> EStem -> NInteLoop -> NBT -- recursive backtracking function for loops -> ExtBT btInteriorOuter ps inp (EStem eStem) nInteLoop btILoop i j ct eI eJ d = -- iltrc ("ilOuter",i,j,lol) $ [ (ij:x,z) -- interior loop | i>=0,i Features (VU.Vector (PairIdx,Double))) fInteriorLoop Params{..} inp (NInte nInte) i j | j-i<4 = VU.empty | otherwise = VU.map f kls where f (k,l) = ( (k,l) , nInte ! (k,l) + interiorLength ! (lenI+lenJ) + interiorAsym ! (abs $ lenI - lenJ) ) where lenI = k-i-1; lenJ = j-l-1 kls = VU.map (\(dI,dJ) -> (i+dI,j-dJ)) $ fInteriorKLs i j {-# INLINE fInteriorLoop #-} -- | Backtrack the unpaired loop region btInteriorLoop :: Params -> Primary -> NInteLoop -> NInte -> NBT -> NBT btInteriorLoop ps inp (NInteLoop nInteLoop) nInte btIL i j d = -- iltrc ("ilLoop",i,j) $ [ (x,z) | i>=0,i Features (VU.Vector (ExtPairIdx,Double))) fInteriorInner Params{..} inp (EStem eStem) i j | j-i<2 = VU.empty | i==0 || j+1==VU.length inp = VU.empty | otherwise = VU.map f kls where f ijExt@((i,j),(ctIJ,eI,eJ)) = ( ijExt , eStem ! ijExt + interiorClose ! (((nJ,nI),(ctIJ,eJ,eI)),nJp1,nIm1) ) where nI = inp VU.! i nJ = inp VU.! j nIm1 = inp VU.! (i-1) nJp1 = inp VU.! (j+1) kls = VU.fromList [ ((i,j),(ctIJ,eI,eJ)) | eI<-wsh, eJ<-wsh, ctIJ<-citr ] {-# INLINE fInteriorInner #-} -- | Backtrack from an NInte result to the corresponding EStem parts btInteriorInner :: Params -> Primary -> NInte -> EStem -> ExtBT -> NBT btInteriorInner ps inp (NInte nInte) eStem btES i j d = -- iltrc ("ilInner",i,j) $ [ (x,z) | i>=0,i Primary -> EStem -> NInteLoop -> NInte -> ExtBT -> ExtBT btInteriorComplete ps pri eStem nInteLoop nInte btExtStem i j ct eI eJ d = btInteriorOuter ps pri eStem btiloop i j ct eI eJ d where btiloop i j d = btInteriorLoop ps pri nInteLoop nInte btinner i j d btinner = btInteriorInner ps pri nInte eStem btExtStem -} -- | Given the outer indices (i,j), produces delta_i and delta_j so that -- i+delta_i and j-delta_j are the inner indices. 'fInteriorKLs' should fuse -- and should make sure that l-k>=4 is always true (maxd). Furthermore the -- maximal unpaired length of both sides combined is determined by 'maxLength'. -- -- TODO better name than 'maxLength' fInteriorKLs :: Int -> Int -> VU.Vector (Int,Int) fInteriorKLs i j = didjs where didjs = VU.unfoldr mkDs (4,2) mkDs (d,s) | d>maxd = Nothing | s>=d-2 = Just ((d-s,s),(d+1,2)) | otherwise = Just ((d-s,s),(d,s+1)) {-# INLINE mkDs #-} maxd = min maxLength (j-i-4) {-# INLINE fInteriorKLs #-}