{-# LANGUAGE OverloadedStrings #-}{-# LANGUAGE RecordWildCards #-}-- | FR3D provides a very convenient library of explored RNA structures. We are-- mostly interested in the "basepairs" files. In contrast to the RNAstrand-- library or melting experiments, these data sets provide non-canonical RNA-- pairing.---- NOTE that FR3D entries contain basepairs both in (i,j) as well as (j,i)-- orientation (with i<j).moduleBiobase.FR3DwhereimportData.ByteString.Char8asBSimportData.ListasLimportBiobase.PrimaryimportBiobase.Secondary-- | Encapsulates all the "basepairs" information.dataFR3D=FR3D{pdbid::ByteString,chains::[(ByteString,ByteString)],basepairs::[Basepair]}deriving(Show)-- | A single basepair in a basepair system.dataBasepair=Basepair{interaction::ExtPairAnnotation-- nucleotide 1,nucleotide1::Char,pdbnumber1::Int,chain1::ByteString,seqpos1::Int-- nucleotide 2,nucleotide2::Char,pdbnumber2::Int,chain2::ByteString,seqpos2::Int}deriving(Show)-- | Linearized FR3D format.dataLinFR3D=LinFR3D{pdbID::ByteString,sequence::ByteString,pairs::[(ExtPairIdx,ExtPair)]-- we keep the ExtPair information as provided by the non-linearized FR3D data}deriving(Show)-- | The default format is a bit unwieldy; Linearization assumes that all-- sequences are in 5'->3' order; then produces one sequence with "&"-- separating the sequences and pairs reduced to (Int,Int,cWW).linearizeFR3D::FR3D->LinFR3DlinearizeFR3DFR3D{..}=LinFR3D{pdbID=pdbid,sequence=BS.intercalate"&"$L.mapsndchains,pairs=L.mapfbasepairs}wheretrans=snd$L.mapAccumL(\acc(x,y)->(acc+1+BS.lengthy,(x,acc)))0chainsfBasepair{..}=(pi,p)wherepi=((maybe(-1)(\v->v+seqpos1)$L.lookupchain1trans,maybe(-1)(\v->v+seqpos2)$L.lookupchain2trans),interaction)p=((mkNucnucleotide1,mkNucnucleotide2),interaction)classRemoveDuplicatePairsawhereremoveDuplicatePairs::a->ainstanceRemoveDuplicatePairsFR3DwhereremoveDuplicatePairsx@FR3D{..}=x{basepairs=L.filterfbasepairs}wherefBasepair{..}=(chain1,seqpos1)<(chain2,seqpos2)instanceRemoveDuplicatePairsLinFR3DwhereremoveDuplicatePairsx@LinFR3D{..}=x{pairs=L.filter(f.fst)pairs}wheref((x,y),_)=x<y-- ** Checking data structures-- | Checks an FR3D file for correctness. Returns either a Left on errors or-- Right FR3D if correct.---- TODO chain existence checkcheckFR3Dfr3d@FR3D{..}|L.nullxs=Rightfr3d|otherwise=Left(fr3d,xs)wherexs=[x|x<-basepairs,letJustc1=lookup(chain1x)chains,letJustc2=lookup(chain2x)chains,seqpos1x<0||seqpos2x<0||seqpos1x>=BS.lengthc1||seqpos2x>=BS.lengthc2||nucleotide1x/=c1`BS.index`seqpos1x||nucleotide2x/=c2`BS.index`seqpos2x]checkLinFR3Dlinfr3d@LinFR3D{..}|L.nullxs=Rightlinfr3d|otherwise=Left(linfr3d,xs)wherexs=[x|x@(pi,p)<-pairs,baseLpi<0||baseRpi<0||baseLpi>=BS.lengthsequence||baseRpi>=BS.lengthsequence||mkNuc(sequence`BS.index`baseLpi)/=baseLp||mkNuc(sequence`BS.index`baseRpi)/=baseRp]