Skip to content

Commit 1ad1367

Browse files
Copilotsdhutchins
andcommitted
Add bioinformatics wrappers, wet-lab utilities with save functionality
Co-authored-by: sdhutchins <20976111+sdhutchins@users.noreply.github.com>
1 parent 8f738e1 commit 1ad1367

13 files changed

Lines changed: 3028 additions & 2 deletions

File tree

labrat/bioinformatics/__init__.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# -*- coding: utf-8 -*-
2+
"""Bioinformatics tools and wrappers for gene and variant lookups."""
3+
4+
from .gene import GeneClient, get_gene_info, query_genes
5+
from .variant import VariantClient, get_variant_info, query_variants
6+
from .enrichment import EnrichmentClient, run_enrichment
7+
8+
__all__ = [
9+
"GeneClient",
10+
"VariantClient",
11+
"EnrichmentClient",
12+
"get_gene_info",
13+
"query_genes",
14+
"get_variant_info",
15+
"query_variants",
16+
"run_enrichment",
17+
]
Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
# -*- coding: utf-8 -*-
2+
"""Gene set enrichment analysis wrapper using Enrichr and GSEApy."""
3+
4+
from typing import Any, Dict, List, Optional, Union
5+
6+
import gseapy as gp
7+
import pandas as pd
8+
9+
10+
class EnrichmentClient:
11+
"""
12+
A wrapper client for gene set enrichment analysis.
13+
14+
This client provides a simplified interface for running enrichment analysis
15+
using Enrichr via the GSEApy library. It supports multiple gene set libraries
16+
and organisms.
17+
18+
Attributes:
19+
organism: The organism to use for analysis.
20+
21+
Example:
22+
>>> client = EnrichmentClient()
23+
>>> results = client.enrichr(["BRCA1", "BRCA2", "TP53"])
24+
>>> print(results.head())
25+
"""
26+
27+
# Common gene set libraries for different analysis types
28+
PATHWAY_LIBRARIES = [
29+
"KEGG_2021_Human",
30+
"Reactome_2022",
31+
"WikiPathway_2023_Human",
32+
"BioPlanet_2019",
33+
]
34+
35+
ONTOLOGY_LIBRARIES = [
36+
"GO_Biological_Process_2023",
37+
"GO_Molecular_Function_2023",
38+
"GO_Cellular_Component_2023",
39+
]
40+
41+
DISEASE_LIBRARIES = [
42+
"DisGeNET",
43+
"OMIM_Disease",
44+
"GWAS_Catalog_2023",
45+
]
46+
47+
TRANSCRIPTION_LIBRARIES = [
48+
"ENCODE_TF_ChIP-seq_2015",
49+
"ChEA_2022",
50+
"TRRUST_Transcription_Factors_2019",
51+
]
52+
53+
def __init__(self, organism: str = "human") -> None:
54+
"""
55+
Initialize the EnrichmentClient.
56+
57+
Args:
58+
organism: The organism to use for analysis.
59+
Options: "human", "mouse", "fly", "yeast", "worm", "fish".
60+
"""
61+
self.organism = organism
62+
63+
def enrichr(
64+
self,
65+
gene_list: List[str],
66+
gene_sets: Optional[Union[str, List[str]]] = None,
67+
description: str = "labrat_enrichment",
68+
cutoff: float = 0.05,
69+
) -> pd.DataFrame:
70+
"""
71+
Run Enrichr enrichment analysis on a gene list.
72+
73+
Args:
74+
gene_list: List of gene symbols to analyze.
75+
gene_sets: Gene set library or list of libraries to query.
76+
Defaults to common pathway libraries if None.
77+
description: Description for the analysis job.
78+
cutoff: P-value cutoff for significant results.
79+
80+
Returns:
81+
DataFrame with enrichment results including:
82+
- Term: The enriched term name
83+
- Overlap: Number of genes overlapping with term
84+
- P-value: Uncorrected p-value
85+
- Adjusted P-value: Benjamini-Hochberg corrected p-value
86+
- Combined Score: Enrichr combined score
87+
- Genes: Overlapping genes
88+
89+
Example:
90+
>>> client = EnrichmentClient()
91+
>>> results = client.enrichr(
92+
... ["BRCA1", "BRCA2", "TP53"],
93+
... gene_sets="KEGG_2021_Human"
94+
... )
95+
"""
96+
if gene_sets is None:
97+
gene_sets = self.PATHWAY_LIBRARIES
98+
99+
if isinstance(gene_sets, str):
100+
gene_sets = [gene_sets]
101+
102+
# Run Enrichr analysis
103+
enr = gp.enrichr(
104+
gene_list=gene_list,
105+
gene_sets=gene_sets,
106+
organism=self.organism,
107+
description=description,
108+
outdir=None, # Don't save to file
109+
cutoff=cutoff,
110+
)
111+
112+
return enr.results
113+
114+
def pathway_enrichment(
115+
self,
116+
gene_list: List[str],
117+
cutoff: float = 0.05,
118+
) -> pd.DataFrame:
119+
"""
120+
Run pathway enrichment analysis.
121+
122+
Uses KEGG, Reactome, WikiPathway, and BioPlanet databases.
123+
124+
Args:
125+
gene_list: List of gene symbols to analyze.
126+
cutoff: P-value cutoff for significant results.
127+
128+
Returns:
129+
DataFrame with pathway enrichment results.
130+
131+
Example:
132+
>>> client = EnrichmentClient()
133+
>>> results = client.pathway_enrichment(["BRCA1", "BRCA2", "TP53"])
134+
"""
135+
return self.enrichr(
136+
gene_list,
137+
gene_sets=self.PATHWAY_LIBRARIES,
138+
description="pathway_enrichment",
139+
cutoff=cutoff,
140+
)
141+
142+
def go_enrichment(
143+
self,
144+
gene_list: List[str],
145+
cutoff: float = 0.05,
146+
) -> pd.DataFrame:
147+
"""
148+
Run Gene Ontology (GO) enrichment analysis.
149+
150+
Analyzes Biological Process, Molecular Function, and Cellular Component.
151+
152+
Args:
153+
gene_list: List of gene symbols to analyze.
154+
cutoff: P-value cutoff for significant results.
155+
156+
Returns:
157+
DataFrame with GO enrichment results.
158+
159+
Example:
160+
>>> client = EnrichmentClient()
161+
>>> results = client.go_enrichment(["BRCA1", "BRCA2", "TP53"])
162+
"""
163+
return self.enrichr(
164+
gene_list,
165+
gene_sets=self.ONTOLOGY_LIBRARIES,
166+
description="go_enrichment",
167+
cutoff=cutoff,
168+
)
169+
170+
def disease_enrichment(
171+
self,
172+
gene_list: List[str],
173+
cutoff: float = 0.05,
174+
) -> pd.DataFrame:
175+
"""
176+
Run disease association enrichment analysis.
177+
178+
Uses DisGeNET, OMIM, and GWAS Catalog databases.
179+
180+
Args:
181+
gene_list: List of gene symbols to analyze.
182+
cutoff: P-value cutoff for significant results.
183+
184+
Returns:
185+
DataFrame with disease enrichment results.
186+
187+
Example:
188+
>>> client = EnrichmentClient()
189+
>>> results = client.disease_enrichment(["BRCA1", "BRCA2", "TP53"])
190+
"""
191+
return self.enrichr(
192+
gene_list,
193+
gene_sets=self.DISEASE_LIBRARIES,
194+
description="disease_enrichment",
195+
cutoff=cutoff,
196+
)
197+
198+
def tf_enrichment(
199+
self,
200+
gene_list: List[str],
201+
cutoff: float = 0.05,
202+
) -> pd.DataFrame:
203+
"""
204+
Run transcription factor enrichment analysis.
205+
206+
Identifies transcription factors that may regulate the gene list.
207+
208+
Args:
209+
gene_list: List of gene symbols to analyze.
210+
cutoff: P-value cutoff for significant results.
211+
212+
Returns:
213+
DataFrame with transcription factor enrichment results.
214+
215+
Example:
216+
>>> client = EnrichmentClient()
217+
>>> results = client.tf_enrichment(["BRCA1", "BRCA2", "TP53"])
218+
"""
219+
return self.enrichr(
220+
gene_list,
221+
gene_sets=self.TRANSCRIPTION_LIBRARIES,
222+
description="tf_enrichment",
223+
cutoff=cutoff,
224+
)
225+
226+
@staticmethod
227+
def list_libraries(organism: str = "human") -> List[str]:
228+
"""
229+
List all available Enrichr gene set libraries.
230+
231+
Args:
232+
organism: Organism to list libraries for.
233+
234+
Returns:
235+
List of available library names.
236+
237+
Example:
238+
>>> libraries = EnrichmentClient.list_libraries()
239+
>>> print(len(libraries))
240+
"""
241+
return gp.get_library_name(organism=organism)
242+
243+
244+
def run_enrichment(
245+
gene_list: List[str],
246+
analysis_type: str = "pathway",
247+
organism: str = "human",
248+
cutoff: float = 0.05,
249+
) -> pd.DataFrame:
250+
"""
251+
Convenience function to run enrichment analysis.
252+
253+
Args:
254+
gene_list: List of gene symbols to analyze.
255+
analysis_type: Type of analysis to run.
256+
Options: "pathway", "go", "disease", "tf", "all".
257+
organism: Organism for analysis.
258+
cutoff: P-value cutoff.
259+
260+
Returns:
261+
DataFrame with enrichment results.
262+
263+
Example:
264+
>>> results = run_enrichment(
265+
... ["BRCA1", "BRCA2", "TP53"],
266+
... analysis_type="pathway"
267+
... )
268+
"""
269+
client = EnrichmentClient(organism=organism)
270+
271+
if analysis_type == "pathway":
272+
return client.pathway_enrichment(gene_list, cutoff=cutoff)
273+
elif analysis_type == "go":
274+
return client.go_enrichment(gene_list, cutoff=cutoff)
275+
elif analysis_type == "disease":
276+
return client.disease_enrichment(gene_list, cutoff=cutoff)
277+
elif analysis_type == "tf":
278+
return client.tf_enrichment(gene_list, cutoff=cutoff)
279+
elif analysis_type == "all":
280+
all_libraries = (
281+
client.PATHWAY_LIBRARIES
282+
+ client.ONTOLOGY_LIBRARIES
283+
+ client.DISEASE_LIBRARIES
284+
+ client.TRANSCRIPTION_LIBRARIES
285+
)
286+
return client.enrichr(gene_list, gene_sets=all_libraries, cutoff=cutoff)
287+
else:
288+
raise ValueError(
289+
f"Unknown analysis type: {analysis_type}. "
290+
"Options: 'pathway', 'go', 'disease', 'tf', 'all'"
291+
)

0 commit comments

Comments
 (0)