2 Module : Gargantext.API.Ngrams.Tools
3 Description : Tools to manage Ngrams Elements (from the API)
4 Copyright : (c) CNRS, 2017-Present
5 License : AGPL + CECILL v3
6 Maintainer : team@gargantext.org
7 Stability : experimental
13 module Gargantext.API.Ngrams.Tools
16 import Control.Concurrent
17 import Control.Lens (_Just, (^.), at, view)
18 import Control.Monad.Reader
19 import Data.Map.Strict (Map)
20 import qualified Data.Map.Strict as Map
21 import qualified Data.Set as Set
23 import Data.Text (Text)
26 import Gargantext.API.Ngrams.Types
27 import Gargantext.Core.Types (ListType(..), NodeId, ListId)
28 import Gargantext.Database.Schema.Ngrams (NgramsType)
29 import Gargantext.Prelude
31 mergeNgramsElement :: NgramsRepoElement -> NgramsRepoElement -> NgramsRepoElement
32 mergeNgramsElement _neOld neNew = neNew
36 getRepo :: RepoCmdM env err m => m NgramsRepo
41 listNgramsFromRepo :: [ListId] -> NgramsType
42 -> NgramsRepo -> Map Text NgramsRepoElement
43 listNgramsFromRepo nodeIds ngramsType repo = Map.mapKeys unNgramsTerm ngrams
45 ngramsMap = repo ^. r_state . at ngramsType . _Just
47 ngrams = Map.unionsWith mergeNgramsElement
48 [ ngramsMap ^. at nodeId . _Just | nodeId <- nodeIds ]
52 -- TODO-ACCESS: We want to do the security check before entering here.
53 -- Add a static capability parameter would be nice.
54 -- Ideally this is the access to `repoVar` which needs to
55 -- be properly guarded.
56 getListNgrams :: RepoCmdM env err m
57 => [ListId] -> NgramsType
58 -> m (Map Text NgramsRepoElement)
59 getListNgrams nodeIds ngramsType = listNgramsFromRepo nodeIds ngramsType <$> getRepo
61 getTermsWith :: (RepoCmdM env err m, Ord a)
62 => (Text -> a ) -> [ListId]
63 -> NgramsType -> ListType
65 getTermsWith f ls ngt lt = Map.fromListWith (<>)
66 <$> map (toTreeWith f)
68 <$> Map.filter (\f' -> (fst f') == lt)
69 <$> mapTermListRoot ls ngt
72 toTreeWith f'' (t, (_lt, maybeRoot)) = case maybeRoot of
73 Nothing -> (f'' t, [])
74 Just r -> (f'' r, map f'' [t])
76 mapTermListRoot :: [ListId]
79 -> Map Text (ListType, (Maybe Text))
80 mapTermListRoot nodeIds ngramsType repo =
81 Map.fromList [ (t, (_nre_list nre, unNgramsTerm <$> _nre_root nre))
82 | (t, nre) <- Map.toList ngrams
84 where ngrams = listNgramsFromRepo nodeIds ngramsType repo
86 filterListWithRoot :: ListType
87 -> Map Text (ListType, Maybe Text)
88 -> Map Text (Maybe RootTerm)
89 filterListWithRoot lt m = Map.fromList
90 $ map (\(t,(_,r)) -> (t,r))
91 $ filter isMapTerm (Map.toList m)
93 isMapTerm (_t,(l, maybeRoot)) = case maybeRoot of
95 Just r -> case Map.lookup r m of
96 Nothing -> panic $ "Garg.API.Ngrams.Tools: filterWithRoot, unknown key: " <> r
97 Just (l',_) -> l' == lt
99 groupNodesByNgrams :: Map Text (Maybe RootTerm)
100 -> Map Text (Set NodeId)
101 -> Map Text (Set NodeId)
102 groupNodesByNgrams syn occs = Map.fromListWith (<>) occs'
104 occs' = map toSyn (Map.toList occs)
105 toSyn (t,ns) = case Map.lookup t syn of
106 Nothing -> panic $ "[Garg.API.Ngrams.Tools.groupNodesByNgrams] unknown key: " <> t
111 data Diagonal = Diagonal Bool
113 getCoocByNgrams :: Diagonal -> Map Text (Set NodeId) -> Map (Text, Text) Int
114 getCoocByNgrams = getCoocByNgrams' identity
117 getCoocByNgrams' :: (Ord a, Ord c) => (b -> Set c) -> Diagonal -> Map a b -> Map (a, a) Int
118 getCoocByNgrams' f (Diagonal diag) m =
119 Map.fromList [( (t1,t2)
120 , maybe 0 Set.size $ Set.intersection
121 <$> (fmap f $ Map.lookup t1 m)
122 <*> (fmap f $ Map.lookup t2 m)
123 ) | (t1,t2) <- case diag of
124 True -> [ (x,y) | x <- Map.keys m, y <- Map.keys m, x <= y]
125 False -> listToCombi identity (Map.keys m)