annotate CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/lib/python3.8/site-packages/gprofiler/gprofiler.py @ 68:5028fdace37b

planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author jpayne
date Tue, 18 Mar 2025 16:23:26 -0400
parents
children
rev   line source
jpayne@68 1 from typing import Union, List, Dict, Any
jpayne@68 2
jpayne@68 3 import requests
jpayne@68 4
jpayne@68 5 from gprofiler.version import __version__
jpayne@68 6
jpayne@68 7
jpayne@68 8 class GProfiler():
jpayne@68 9 def __init__(self, user_agent: str = '', base_url: str = None, return_dataframe: bool = False):
jpayne@68 10 '''
jpayne@68 11 A class representing the g:Profiler toolkit. Contains methods for
jpayne@68 12 querying the g:GOSt, g:Convert, g:Orth and g:SNPense tools. Please see the
jpayne@68 13 g:Profiler web tool (https://biit.cs.ut.ee/gprofiler/) for extensive documentation on all the options to
jpayne@68 14 the methods.
jpayne@68 15
jpayne@68 16 :param user_agent: the URL used for the g:Profiler service.
jpayne@68 17 :param base_url: the URL used for the g:Profiler service.
jpayne@68 18 :param return_dataframe: if True, query results are presented as pandas DataFrames.
jpayne@68 19 '''
jpayne@68 20 self.user_agent = 'gprofiler-python {version}/{user_agent}'.format(version=__version__, user_agent=user_agent)
jpayne@68 21
jpayne@68 22 if base_url is None:
jpayne@68 23 self.base_url = 'https://biit.cs.ut.ee/gprofiler'
jpayne@68 24 else:
jpayne@68 25 self.base_url = base_url
jpayne@68 26
jpayne@68 27 self.return_dataframe = return_dataframe
jpayne@68 28 if return_dataframe:
jpayne@68 29 self._pandas = self._get_pandas_module()
jpayne@68 30
jpayne@68 31 self.meta = None
jpayne@68 32
jpayne@68 33 @staticmethod
jpayne@68 34 def _get_pandas_module():
jpayne@68 35 is_pandas_module = lambda x: getattr(x, '__name__', '') == 'pandas'
jpayne@68 36 namespace = globals()
jpayne@68 37 if 'pd' in namespace and is_pandas_module(namespace['pd']):
jpayne@68 38 return namespace['pd']
jpayne@68 39 elif 'pandas' in namespace and is_pandas_module(namespace['pandas']):
jpayne@68 40 return namespace['pandas']
jpayne@68 41 else:
jpayne@68 42 import importlib
jpayne@68 43 return importlib.import_module('pandas')
jpayne@68 44
jpayne@68 45
jpayne@68 46 def __getattr__(self, item):
jpayne@68 47 if item in ['gprofile', 'gorth', 'gconvert']:
jpayne@68 48 raise NotImplementedError('''`{}` has been renamed `{}` and has a new interface
jpayne@68 49 To use the previous version use the command `pip install --upgrade --no-deps --force-reinstall gprofiler-official==0.3.5`
jpayne@68 50 '''.format(item, item[1:]))
jpayne@68 51 raise AttributeError('{} is not an attribute of {}'.format(item, self.__class__.__name__))
jpayne@68 52
jpayne@68 53
jpayne@68 54
jpayne@68 55 def profile(
jpayne@68 56 self,
jpayne@68 57 query: Union[str, List[str], Dict[str, List[str]]],
jpayne@68 58 organism: str = 'hsapiens',
jpayne@68 59 sources: List[str] = tuple(),
jpayne@68 60 user_threshold: float = 0.05,
jpayne@68 61 all_results: bool = False,
jpayne@68 62 ordered: bool = False,
jpayne@68 63 no_evidences: bool = True,
jpayne@68 64 combined: bool = False,
jpayne@68 65 measure_underrepresentation: bool = False,
jpayne@68 66 no_iea: bool = False,
jpayne@68 67 domain_scope: str = 'annotated',
jpayne@68 68 numeric_namespace: str = '',
jpayne@68 69 significance_threshold_method: str = 'g_SCS',
jpayne@68 70 background: str = None,
jpayne@68 71
jpayne@68 72 ) -> List[Dict[str, Any]]:
jpayne@68 73 """
jpayne@68 74 performs functional profiling of gene lists using various kinds of biological evidence.
jpayne@68 75 The tool performs statistical enrichment analysis to find over-representation of information from Gene Ontology terms,
jpayne@68 76 biological pathways, regulatory DNA elements, human disease gene annotations, and protein-protein interaction networks.
jpayne@68 77
jpayne@68 78
jpayne@68 79
jpayne@68 80 :param query: list of genes to profile. For running multiple queries at once, accepts a dictionary of lists as well.
jpayne@68 81 :param organism: Organism id for profiling. For full list see https://biit.cs.ut.ee/gprofiler/page/organism-list
jpayne@68 82 :param sources: List of annotation sources to include in analysis. Defaults to all known.
jpayne@68 83 :param user_threshold: Significance threshold for analysis.
jpayne@68 84 :param all_results: If True, return all analysis results regardless of statistical significance.
jpayne@68 85 :param ordered: If True, considers the order of input query to be significant. See https://biit.cs.ut.ee/gprofiler/page/docs#ordered_gene_lists
jpayne@68 86 :param no_evidences: If False, the results include lists of intersections and evidences for the intersections
jpayne@68 87 :param combined: If True, performs all queries and combines the results into a single table. NB! changes the output format.
jpayne@68 88 :param measure_underrepresentation: if True, performs test for significantly under-represented functional terms.
jpayne@68 89 :param no_iea: If True, excludes electronically annotated Gene Ontology terms before analysis.
jpayne@68 90 :param domain_scope: "known" for using all known genes as background, "annotated" to use all genes annotated for particular datasource.
jpayne@68 91 :param numeric_namespace: name for the numeric namespace to use if there are numeric values in the query.
jpayne@68 92 :param significance_threshold_method: method for multiple correction. "g_SCS"|"bonferroni"|"fdr". https://biit.cs.ut.ee/gprofiler/page/docs#significance_threhshold
jpayne@68 93 :param background: List of genes to use as a statistical background.
jpayne@68 94 :return:
jpayne@68 95 """
jpayne@68 96
jpayne@68 97 if background is not None:
jpayne@68 98 domain_scope = 'custom'
jpayne@68 99
jpayne@68 100 r = requests.post(
jpayne@68 101 '{}/api/gost/profile/'.format(self.base_url.rstrip("/")),
jpayne@68 102 json={
jpayne@68 103 'organism': organism, # string, eg "hsapiens"
jpayne@68 104 'query': query, # whitespace-delimited string or list of strings or object of strings to lists of strings
jpayne@68 105 'sources': sources, # list of strings, for example:
jpayne@68 106 'user_threshold': user_threshold, # significance threshold, defaults to 0.05
jpayne@68 107 'all_results': all_results, # bool
jpayne@68 108 'no_evidences': no_evidences, # bool - if set to true, saves on database lookups
jpayne@68 109 'combined': combined, # bool, set to true for g:Cocoa output
jpayne@68 110 'measure_underrepresentation': measure_underrepresentation, # bool
jpayne@68 111 'no_iea': no_iea, # bool
jpayne@68 112 'numeric_ns': numeric_namespace, # string
jpayne@68 113 'domain_scope': domain_scope, # string 'known'|'annotated'|'custom'
jpayne@68 114 'ordered': ordered, # bool, set to true for ordered query
jpayne@68 115 'significance_threshold_method': significance_threshold_method, # string, "g_SCS"|"bonferroni"|"fdr", "g_SCS"by default
jpayne@68 116 'background': background if background is not None else '' # string, background name or query string
jpayne@68 117
jpayne@68 118 }
jpayne@68 119 , headers={'User-Agent': self.user_agent})
jpayne@68 120
jpayne@68 121 if r.status_code != 200:
jpayne@68 122 message = ''
jpayne@68 123 try:
jpayne@68 124 message = r.json()['message']
jpayne@68 125 except:
jpayne@68 126 message = 'query failed with error {}'.format(r.status_code)
jpayne@68 127 raise AssertionError(message)
jpayne@68 128 res = r.json()
jpayne@68 129
jpayne@68 130 meta = res['meta']
jpayne@68 131 self.meta = meta
jpayne@68 132
jpayne@68 133 if not combined:
jpayne@68 134 columns = ['source',
jpayne@68 135 'native',
jpayne@68 136 'name',
jpayne@68 137 'p_value',
jpayne@68 138 'significant',
jpayne@68 139 'description',
jpayne@68 140 'term_size',
jpayne@68 141 'query_size',
jpayne@68 142 'intersection_size',
jpayne@68 143 'effective_domain_size',
jpayne@68 144 'precision',
jpayne@68 145 'recall',
jpayne@68 146 'query',
jpayne@68 147 'parents']
jpayne@68 148 if not no_evidences:
jpayne@68 149 columns.append('intersections')
jpayne@68 150 columns.append('evidences')
jpayne@68 151 else:
jpayne@68 152 columns = [
jpayne@68 153 'source',
jpayne@68 154 'native',
jpayne@68 155 'name',
jpayne@68 156 'p_values',
jpayne@68 157 'description',
jpayne@68 158 'term_size',
jpayne@68 159 'query_sizes',
jpayne@68 160 'intersection_sizes',
jpayne@68 161 'effective_domain_size',
jpayne@68 162 'parents']
jpayne@68 163
jpayne@68 164 queries = (meta['query_metadata']['queries'].keys())
jpayne@68 165
jpayne@68 166 if not no_evidences and not combined:
jpayne@68 167 reverse_mappings = {}
jpayne@68 168 for query in queries:
jpayne@68 169 mapping = (meta['genes_metadata']['query'][query]['mapping'])
jpayne@68 170 reverse_mapping = {}
jpayne@68 171 for k, v in mapping.items():
jpayne@68 172 if len(v) == 1:
jpayne@68 173 # one-to-one mapping
jpayne@68 174 reverse_mapping[v[0]] = k
jpayne@68 175 else:
jpayne@68 176 # one-to=many mapping, we'll use the gene ID
jpayne@68 177 for i in v:
jpayne@68 178 reverse_mapping[i] = i
jpayne@68 179 reverse_mappings[query] = reverse_mapping
jpayne@68 180
jpayne@68 181 for result in res['result']:
jpayne@68 182 mapping = reverse_mappings[result['query']]
jpayne@68 183 genes = []
jpayne@68 184 for i in meta['genes_metadata']['query'][result['query']]['ensgs']:
jpayne@68 185 genes.append(mapping[i])
jpayne@68 186 result['evidences'] = [i for i in result['intersections'] if i]
jpayne@68 187 result['intersections'] = ([gene for ev, gene in zip(result['intersections'], genes) if ev])
jpayne@68 188
jpayne@68 189 if not self.return_dataframe:
jpayne@68 190 columns = set(columns)
jpayne@68 191
jpayne@68 192 # filter the columns
jpayne@68 193 result = [{k: v for k, v in i.items() if k in columns} for i in res['result']]
jpayne@68 194 return result
jpayne@68 195
jpayne@68 196 else:
jpayne@68 197
jpayne@68 198 df = self._pandas.DataFrame(res['result'])
jpayne@68 199
jpayne@68 200 if len(df) > 0:
jpayne@68 201 df = df[columns]
jpayne@68 202
jpayne@68 203 else:
jpayne@68 204 return self._pandas.DataFrame(columns=columns)
jpayne@68 205 return df
jpayne@68 206
jpayne@68 207 def convert(
jpayne@68 208 self,
jpayne@68 209 query: Union[str, List[str], Dict[str, List[str]]],
jpayne@68 210 organism: str = 'hsapiens',
jpayne@68 211 target_namespace: str = 'ENSG',
jpayne@68 212 numeric_namespace: str = 'ENTREZGENE'
jpayne@68 213 ) -> List[Dict[str, Any]]:
jpayne@68 214 """
jpayne@68 215 Query g:Convert.
jpayne@68 216
jpayne@68 217 :param query: list of genes to convert
jpayne@68 218 :param organism: organism id
jpayne@68 219 :param target_namespace: namespace to convert into
jpayne@68 220 :param numeric_namespace
jpayne@68 221 """
jpayne@68 222 r = requests.post(
jpayne@68 223 '{}/api/convert/convert'.format(self.base_url),
jpayne@68 224 json={
jpayne@68 225 'organism': organism,
jpayne@68 226 'query': query,
jpayne@68 227 'target': target_namespace,
jpayne@68 228 'numeric_ns': numeric_namespace,
jpayne@68 229 'output': 'json'
jpayne@68 230 },
jpayne@68 231 headers={'User-Agent': self.user_agent}
jpayne@68 232 )
jpayne@68 233
jpayne@68 234 if r.status_code != 200:
jpayne@68 235 message = ''
jpayne@68 236 try:
jpayne@68 237 message = r.json()['message']
jpayne@68 238 except:
jpayne@68 239 message = 'query failed with error {}'.format(r.status_code)
jpayne@68 240 raise AssertionError(message)
jpayne@68 241 res = r.json()
jpayne@68 242
jpayne@68 243 meta = res['meta']
jpayne@68 244 self.meta = meta
jpayne@68 245 columns = ['incoming', 'converted', 'n_incoming', 'n_converted', 'name', 'description', 'namespaces', 'query']
jpayne@68 246
jpayne@68 247 if not self.return_dataframe:
jpayne@68 248 columns = set(columns)
jpayne@68 249
jpayne@68 250 # filter the columns
jpayne@68 251 result = [{k: v for k, v in i.items() if k in columns} for i in res['result']]
jpayne@68 252 return result
jpayne@68 253
jpayne@68 254 df = self._pandas.DataFrame(res['result'])
jpayne@68 255 df = df[columns]
jpayne@68 256
jpayne@68 257 return df
jpayne@68 258
jpayne@68 259 def orth(self,
jpayne@68 260 query: List[str],
jpayne@68 261 organism: str = "hsapiens",
jpayne@68 262 target: str = "mmusculus",
jpayne@68 263 aresolve: Dict[str, str] = None,
jpayne@68 264 numeric_namespace: str = 'ENTREZGENE'):
jpayne@68 265 """
jpayne@68 266 Query g:Orth.
jpayne@68 267
jpayne@68 268
jpayne@68 269 :param query:
jpayne@68 270 :param organism:
jpayne@68 271 :param target:
jpayne@68 272 :param aresolve:
jpayne@68 273 :param numeric_namespace:
jpayne@68 274 """
jpayne@68 275 r = requests.post(
jpayne@68 276 '{}/api/orth/orth'.format(self.base_url),
jpayne@68 277 json={
jpayne@68 278 'organism': organism,
jpayne@68 279 'query': query,
jpayne@68 280 'target': target,
jpayne@68 281 'numeric_ns': numeric_namespace,
jpayne@68 282 'aresolve': aresolve,
jpayne@68 283 'output': 'json'
jpayne@68 284 },
jpayne@68 285 headers={'User-Agent': self.user_agent}
jpayne@68 286 )
jpayne@68 287
jpayne@68 288 if r.status_code != 200:
jpayne@68 289 message = ''
jpayne@68 290 try:
jpayne@68 291 message = r.json()['message']
jpayne@68 292 except:
jpayne@68 293 message = 'query failed with error {}'.format(r.status_code)
jpayne@68 294 raise AssertionError(message)
jpayne@68 295 res = r.json()
jpayne@68 296 meta = res['meta']
jpayne@68 297 self.meta = meta
jpayne@68 298 columns = ['incoming', 'converted', 'ortholog_ensg', 'n_incoming', 'n_converted', 'n_result', 'name', 'description', 'namespaces']
jpayne@68 299 if not self.return_dataframe:
jpayne@68 300 columns = set(columns)
jpayne@68 301
jpayne@68 302 # filter the columns
jpayne@68 303 result = [{k: v for k, v in i.items() if k in columns} for i in res['result']]
jpayne@68 304 return result
jpayne@68 305
jpayne@68 306
jpayne@68 307 df = self._pandas.DataFrame(res['result'])
jpayne@68 308 df = df[columns]
jpayne@68 309
jpayne@68 310 return df
jpayne@68 311
jpayne@68 312 def snpense(self,
jpayne@68 313 query: List[str]):
jpayne@68 314 """
jpayne@68 315
jpayne@68 316 :param query:
jpayne@68 317 """
jpayne@68 318 r = requests.post(
jpayne@68 319 '{}/api/snpense/snpense'.format(self.base_url),
jpayne@68 320 json={
jpayne@68 321 'query': query,
jpayne@68 322 'output': 'json+'
jpayne@68 323 },
jpayne@68 324 headers={'User-Agent': self.user_agent}
jpayne@68 325 )
jpayne@68 326
jpayne@68 327 if r.status_code != 200:
jpayne@68 328 message = ''
jpayne@68 329 try:
jpayne@68 330 message = r.json()['message']
jpayne@68 331 except:
jpayne@68 332 message = 'query failed with error {}'.format(r.status_code)
jpayne@68 333 raise AssertionError(message)
jpayne@68 334 res = r.json()
jpayne@68 335 meta = res['meta']
jpayne@68 336 self.meta = meta
jpayne@68 337 columns = ['rs_id', 'chromosome', 'strand', 'start', 'end', 'ensgs', 'gene_names', 'variants']
jpayne@68 338 if not self.return_dataframe:
jpayne@68 339 columns = set(columns)
jpayne@68 340
jpayne@68 341 # filter the columns
jpayne@68 342 result = [{k: v for k, v in i.items() if k in columns} for i in res['result']]
jpayne@68 343 return result
jpayne@68 344
jpayne@68 345 df = self._pandas.DataFrame(res['result'])
jpayne@68 346 df = df[columns]
jpayne@68 347
jpayne@68 348 return df