{-| Efficient lookup of query positions in a collection of target sequence locations where positions and locations are associated with specific sequence names. This is an extension of 'LocMap' to use locations and positions on named sequences as in 'SeqLocation'. -} module Bio.Location.SeqLocMap ( -- * Location lookup maps for named sequences SeqLocMap, empty, fromList -- * Modifying location lookup maps , insert -- * Searching for target locations , lookupWithin, lookupOverlaps ) where import Control.Arrow (first) import Data.List hiding (insert) import qualified Data.Map as M import Bio.Location.OnSeq import qualified Bio.Location.LocMap as LM import qualified Bio.Location.SeqLocation as SeqLoc -- | A data structure for efficiently finding target sequence -- locations ('SeqLoc.Loc') that overlap query positions or locations. -- Each target location can be associated with an arbitrary additional -- value in the lookup map. type SeqLocMap a = OnSeqs (LM.LocMap a) -- | Empty lookup map. empty :: SeqLocMap a empty = M.empty -- | Creates a 'SeqLocMap' from a list of target locations and their -- associated objects fromList :: [(SeqLoc.SeqLoc, a)] -> SeqLocMap a fromList = foldl' (\lm (sl,x) -> insert sl x lm) M.empty -- | Inserts a new target location and associated object into the -- location lookup map. insert :: SeqLoc.SeqLoc -> a -> SeqLocMap a -> SeqLocMap a insert sloc x = perSeqUpdate (\loc locmap -> LM.insert loc x locmap) sloc -- | Find the (possibly empty) list of target locations and associated -- objects that contain a sequence position, in the sense of -- 'Loc.isWithin'. lookupWithin :: SeqLoc.SeqPos -> SeqLocMap a -> [(SeqLoc.SeqLoc, a)] lookupWithin = withNameAndSeq namedLookupWithin where namedLookupWithin seqname pos = map (first $ OnSeq seqname) . LM.lookupWithin pos -- | Find the (possibly empty) list of target locations and associated -- objects that overlap a sequence location, in the sense of -- 'Loc.overlaps'. lookupOverlaps :: SeqLoc.SeqLoc -> SeqLocMap a -> [(SeqLoc.SeqLoc, a)] lookupOverlaps = withNameAndSeq namedLookupOverlaps where namedLookupOverlaps seqname loc = map (first $ OnSeq seqname) . LM.lookupOverlaps loc