Skip to content

Commit

Permalink
finish switch to peotry
Browse files Browse the repository at this point in the history
  • Loading branch information
jkobject committed Jan 5, 2024
1 parent e32d275 commit 91f00b4
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 244 deletions.
10 changes: 0 additions & 10 deletions .github/backup/requirements-test.txt

This file was deleted.

5 changes: 0 additions & 5 deletions .github/backup/requirements.txt

This file was deleted.

46 changes: 0 additions & 46 deletions .github/backup/setup.py

This file was deleted.

36 changes: 0 additions & 36 deletions .github/rename_project.sh

This file was deleted.

20 changes: 11 additions & 9 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.10]
python-version: ["3.10"]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
Expand All @@ -28,6 +28,7 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'poetry'
- name: Install project
run: make install
- name: Run linter
Expand All @@ -38,7 +39,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.10]
python-version: ["3.10"]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
Expand All @@ -48,43 +49,44 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'poetry'
- name: Install project
run: make install
- name: Run tests
run: make test
- name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
# with:
# fail_ci_if_error: true

#
#tests_mac:
# needs: linter
# strategy:
# fail-fast: false
# matrix:
# python-version: [3.10]
# python-version: ["3.10"]
# os: [macos-latest]
# runs-on: ${{ matrix.os }}
# steps:
# - uses: actions/checkout@v3
# - uses: actions/checkout@v4
# - uses: actions/setup-python@v5
# with:
# python-version: ${{ matrix.python-version }}
# - name: Install project
# run: make install
# - name: Run tests
# run: make test

#
#tests_win:
# needs: linter
# strategy:
# fail-fast: false
# matrix:
# python-version: [3.9]
# python-version: ["3.10"]
# os: [windows-latest]
# runs-on: ${{ matrix.os }}
# steps:
# - uses: actions/checkout@v3
# - uses: actions/checkout@v4
# - uses: actions/setup-python@v5
# with:
# python-version: ${{ matrix.python-version }}
Expand Down
14 changes: 0 additions & 14 deletions ABOUT_THIS_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,6 @@ Lets take a look at the structure of this template:
└── test_base.py # The base test case for the project
```

### Why to include `tests`, `history` and `Containerfile` as part of the release?

The `MANIFEST.in` file is used to include the files in the release, once the
project is released to PyPI all the files listed on MANIFEST.in will be included
even if the files are static or not related to Python.

Some build systems such as RPM, DEB, AUR for some Linux distributions, and also
internal repackaging systems tends to run the tests before the packaging is performed.

The Containerfile can be useful to provide a safer execution environment for
the project when running on a testing environment.

I added those files to make it easier for packaging in different formats.

## The Makefile

All the utilities for the template and project are on the Makefile
Expand Down
170 changes: 46 additions & 124 deletions grnndata/GRNAnnData.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from anndata import AnnData
import scipy
import scipy.sparse
import pandas as pd
import numpy as np


class GRNAnnData(AnnData):
def __init__(self, grn, **kwargs):
super().__init__(**kwargs)
def __init__(self, *args, grn, **kwargs):
super().__init__(*args, **kwargs)

self.varp["GRN"] = grn

Expand All @@ -12,143 +15,62 @@ def concat(self, other):
if not isinstance(other, GRNAnnData):
raise ValueError("Can only concatenate with another GRNAnnData object")
return GRNAnnData(
grn = scipy.sparse.vstack([self.varp["GRN"], other.varp["GRN"]]),
self.concatenate(other)
self.concatenate(other),
grn=scipy.sparse.vstack([self.varp["GRN"], other.varp["GRN"]]),
)

## add slice
def __getitem__(self, name):
if isinstance(index, str):
if isinstance(name, str):
index = self.var_names.tolist().index(name)
return GRNAnnData(
grn = self.varp["GRN"][index],
self[:,name]
)
#need to put it in varm
if isinstance(name, list):
index = [self.var_names.tolist().index(i) for i in name]
return GRNAnnData(
grn = self.varp["GRN"][index],
X = self.X[index]
)
#need to put it in varm too
if isinstance(index, np.ndarray):
return GRNAnnData(
grn = self.varp["GRN"][index],
X = self.X[index]
self[:, name],
grn=self.varp["GRN"][index],
)
#need to put it in varm too
if isinstance(index, slice)
# need to put it in varm
if isinstance(name, list):
index = [self.var_names.tolist().index(i) for i in name]
return GRNAnnData(grn=self.varp["GRN"][index], X=self.X[index])
# need to put it in varm too
if isinstance(name, np.ndarray):
return GRNAnnData(grn=self.varp["GRN"][name], X=self.X[name])
# need to put it in varm too
if isinstance(name, slice):
return GRNAnnData(
grn = self.varp["GRN"][index,index],
X = self.X[index]
grn=self.varp["GRN"][name, name],
X=self.X[name],
)
#need to put it in varm too
# need to put it in varm too

## add return list of genes and corresponding weights
def extract_links(
adata, #AnnData object
columns = ['row', 'col', 'weight'] # output col names (e.g. 'TF', 'gene', 'score')
adata, # AnnData object
columns=[
"row",
"col",
"weight",
], # output col names (e.g. 'TF', 'gene', 'score')
):
"""
little function to extract scores from anndata.varp['key'] as a pd.DataFrame :
TF Gene Score
A B 5
C D 8
"""
"""
little function to extract scores from anndata.varp['key'] as a pd.DataFrame :
TF Gene Score
A B 5
C D 8
"""
return pd.DataFrame(
[a for a in zip(
[adata.var_names[i] for i in adata.varp['GRN'].row],
[adata.var_names[i] for i in adata.varp['GRN'].col],
adata.varp['GRN'].data)
[
a
for a in zip(
[adata.var_names[i] for i in adata.varp["GRN"].row],
[adata.var_names[i] for i in adata.varp["GRN"].col],
adata.varp["GRN"].data,
)
],
columns = columns
).sort_values(by=columns[2], ascending=False)
columns=columns,
).sort_values(by=columns[2], ascending=False)


def from_anndata(adata):
if "GRN" not in adata.obsp:
raise ValueError("GRN not found in adata.obsp")
return GRNAnnData(adata.obsp["GRN"], X=adata)


def get_centrality(GRNAnnData, k=30):
"""
get_centrality uses the networkx library to calculate the centrality of each node in the GRN.
The centrality is added to the GRNAnnData object as a new column in the var dataframe.
also prints the top K most central nodes in the GRN.
Args:
GRNAnnData (_type_): _description_
"""
import networkx as nx

G = nx.from_scipy_sparse_matrix(GRNAnnData.obsp["GRN"])
centrality = nx.eigenvector_centrality(G)

GRNAnnData.var["centrality"] = [
centrality.get(gene, 0) for gene in GRNAnnData.var_names
]

top_central_genes = sorted(
[(node, centrality) for node, centrality in centrality.items()],
key=lambda x: x[1],
reverse=True,
)[:k]
print("Top central genes:", top_central_genes)


def enrichment(GRNAnnData, of="Targets", for_="TFs", doplot=True, **kwargs):
"""
enrichment uses the gseapy library to calculate the enrichment of the target genes in the adata
the enrichment is returned and plotted
Args:
GRNAnnData (_type_): _description_
of (str, optional): _description_. Defaults to "Targets".
for_ (str, optional): _description_. Defaults to "TFs".
"""
import gseapy as gp
from gseapy.plot import barplot, dotplot

mapping = {
"TFs": "KEGG_2019_Human",
}

# define gene sets
if of == "Targets":
gene_sets = GRNAnnData.var_names
elif of == "TFs":
gene_sets = GRNAnnData.var["TFs"]
else:
raise ValueError("of must be one of 'Targets', 'TFs'")

# run enrichment analysis
enr = gp.enrichr(
gene_list=gene_sets, description=for_, gene_sets=mapping[for_], **kwargs
)

# plot results
if doplot:
barplot(enr.res2d, title=for_)

return enr


def similarity(GRNAnnData, other_GRNAnnData):
pass


def get_subnetwork(GRNAnnData, on="TFs"):
if type(on) is list:
pass
elif on == "TFs":
pass
elif on == "Regulators":
pass
else:
raise ValueError("on must be one of 'TFs', 'Regulators', or a list of genes")
pass


def focuses_more_on(GRNAnnData, on="TFs"):
pass
return GRNAnnData(adata, grn=adata.obsp["GRN"])
Loading

0 comments on commit 91f00b4

Please sign in to comment.