Skip to content

Commit

Permalink
Merge pull request #9 from saeyslab/interop-pytometry
Browse files Browse the repository at this point in the history
Better interoperability with pytometry 0.1.6.
  • Loading branch information
berombau authored Sep 25, 2024
2 parents 80529c6 + 5a1efd9 commit fa09653
Show file tree
Hide file tree
Showing 6 changed files with 305 additions and 309 deletions.
1 change: 0 additions & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ For more background information, see the paper for this software package {cite:p
:toctree: generated
pp.aggregate_flowframes
pp.normalize_estimate_logicle
```

## Models
Expand Down
554 changes: 283 additions & 271 deletions docs/notebooks/example.ipynb

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ dependencies = [
"pandas",
"scipy",
"readfcs",
"pytometry",
"scikit-learn",
"igraph",
"session-info",
Expand All @@ -57,6 +56,8 @@ doc = [
"ipykernel",
"ipython",
"sphinx-copybutton",
# For example notebooks
"pytometry>=0.1.5",
]
test = ["pytest", "coverage"]

Expand Down
22 changes: 19 additions & 3 deletions src/flowsom/pl/plot_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,16 @@ def plot_numbers(fsom, level="clusters", max_node_size=0, **kwargs):


def plot_variable(
fsom, variable, cmap=FlowSOM_colors(), labels=None, text_size=5, text_color="black", lim=None, title=None, **kwargs
fsom,
variable,
cmap=FlowSOM_colors(),
labels=None,
text_size=5,
text_color="black",
lim=None,
title=None,
categorical=True,
**kwargs,
):
"""Plot FlowSOM grid or tree, colored by node values given in variable.
Expand Down Expand Up @@ -260,7 +269,14 @@ def plot_variable(
if labels is not None:
ax = add_text(ax, layout, labels, text_size=text_size, text_color=text_color, ha=["center"], va=["center"])
ax, fig = add_legend(
fig=fig, ax=ax, data=variable, title="Marker", cmap=cmap, location="upper left", bbox_to_anchor=(1.04, 1)
fig=fig,
ax=ax,
data=variable,
title="Marker",
cmap=cmap,
location="upper left",
bbox_to_anchor=(1.04, 1),
categorical=categorical,
)
ax.axis("equal")
if title is not None:
Expand Down Expand Up @@ -294,7 +310,7 @@ def plot_marker(fsom, marker, ref_markers=None, lim=None, cmap=FlowSOM_colors(),
lim = (mfis[:, indices_markers].min(), mfis[:, indices_markers].max())
marker = list(get_channels(fsom, marker).keys())[0]
marker_index = np.where(fsom.get_cell_data().var_names == marker)[0][0]
fig = plot_variable(fsom, variable=mfis[:, marker_index], cmap=cmap, lim=lim, **kwargs)
fig = plot_variable(fsom, variable=mfis[:, marker_index], cmap=cmap, lim=lim, categorical=False, **kwargs)
return fig


Expand Down
2 changes: 1 addition & 1 deletion src/flowsom/pp/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .fcs_functions import aggregate_flowframes, normalize_estimate_logicle
from .fcs_functions import aggregate_flowframes
32 changes: 0 additions & 32 deletions src/flowsom/pp/fcs_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

import anndata as ad
import numpy as np
import pandas as pd
import pytometry as pm

from flowsom.io import read_FCS
from flowsom.tl import get_markers
Expand Down Expand Up @@ -54,33 +52,3 @@ def aggregate_flowframes(filenames, c_total, channels=None, keep_order=False):
flow_frame.append(f)
flow_frame = ad.concat(flow_frame, join="outer", uns_merge="first")
return flow_frame


def normalize_estimate_logicle(adata, channels, m=4.5, q=0.05):
"""Normalize and estimate logicle parameters.
:param adata: An AnnData object
:type adata: AnnData
:param channels: Channels/markers to normalize
:type channels: list
:param m: Logicle parameter. Default=4.5
:type m: float
:param q: Quantile to use for negative values. Default=0.05
:type q: float
"""
assert isinstance(adata, ad.AnnData), "Please provide an AnnData object"
assert isinstance(channels, list), "Please provide a list of channels"
channels = list(get_markers(adata, channels).keys())
assert all(i in adata.var_names for i in channels), "Channels should be in the AnnData object"
neg_marker_quantiles = [
np.quantile(adata[:, channel].X[adata[:, channel].X < 0], q) if (adata[:, channel].X < 0).any() else 0.5
for channel in channels
]
neg_marker_quantiles = pd.Series(neg_marker_quantiles, index=channels, dtype=float)
max_range = adata.var["$PnR"][channels].astype(float)
w = (m - np.log10(max_range / np.abs(neg_marker_quantiles))) / 2
for channel in channels:
adata[:, channel].X = pm.tools.normalize_logicle(
adata[:, channel], t=max_range[channel], m=m, a=0, w=w[channel], inplace=False
).X
return adata

0 comments on commit fa09653

Please sign in to comment.