Skip to content

Commit 7da9416

Browse files
committed
Merge branch 'develop'
2 parents 67ed33d + d41b71e commit 7da9416

File tree

14 files changed

+1137
-276
lines changed

14 files changed

+1137
-276
lines changed

examples/data/8_color_data_set/reused_quad_gate_with_child.wsp

Lines changed: 862 additions & 0 deletions
Large diffs are not rendered by default.

examples/flowkit-session-replicate-flowjo-wsp.ipynb

Lines changed: 116 additions & 124 deletions
Large diffs are not rendered by default.

flowkit/_models/gating_results.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ def _process_results(self):
7575

7676
self.report = df.sort_values(['sample', 'level', 'gate_name'])
7777

78+
def _filter_gate_report(self, gate_name, gate_path=None):
79+
results = self.report[(self.report['sample'] == self.sample_id) & (self.report['gate_name'] == gate_name)]
80+
81+
if gate_path is not None:
82+
results = results[results.gate_path == gate_path]
83+
elif len(results) > 1:
84+
raise ValueError("Gate name %s is ambiguous, specify the full gate path")
85+
86+
return results
87+
7888
def get_gate_membership(self, gate_name, gate_path=None):
7989
"""
8090
Retrieve a boolean array indicating gate membership for the events in the GatingResults sample.
@@ -108,45 +118,39 @@ def get_gate_membership(self, gate_name, gate_path=None):
108118
else:
109119
raise ValueError("Report as bug: The gate %s appears to have multiple quadrant parents." % gate_name)
110120

111-
def get_gate_count(self, gate_name):
121+
def get_gate_count(self, gate_name, gate_path=None):
112122
"""
113123
Retrieve event count for the specified gate ID for the gating results sample
114124
115125
:param gate_name: text string of a gate name
126+
:param gate_path: tuple of ancestor gate names
116127
:return: integer count of events in gate ID
117128
"""
118-
results = self.report[(self.report['sample'] == self.sample_id) & (self.report['gate_name'] == gate_name)]
119-
120-
if len(results) > 1:
121-
raise NotImplementedError("Gate ID %s is ambiguous and gate_path is not yet implemented for this method")
129+
results = self._filter_gate_report(gate_name, gate_path=gate_path)
122130

123131
return results['count'].values[0]
124132

125-
def get_gate_absolute_percent(self, gate_name):
133+
def get_gate_absolute_percent(self, gate_name, gate_path=None):
126134
"""
127135
Retrieve percent of events, relative to the total sample events, of the specified gate ID for the
128136
gating results sample
129137
130138
:param gate_name: text string of a gate name
139+
:param gate_path: tuple of ancestor gate names
131140
:return: floating point number of the absolute percent
132141
"""
133-
results = self.report[(self.report['sample'] == self.sample_id) & (self.report['gate_name'] == gate_name)]
134-
135-
if len(results) > 1:
136-
raise NotImplementedError("Gate ID %s is ambiguous and gate_path is not yet implemented for this method")
142+
results = self._filter_gate_report(gate_name, gate_path=gate_path)
137143

138144
return results['absolute_percent'].values[0]
139145

140-
def get_gate_relative_percent(self, gate_name):
146+
def get_gate_relative_percent(self, gate_name, gate_path=None):
141147
"""
142148
Retrieve percent of events, relative to parent gate, of the specified gate ID for the gating results sample
143149
144150
:param gate_name: text string of a gate name
151+
:param gate_path: tuple of ancestor gate names
145152
:return: floating point number of the relative percent
146153
"""
147-
results = self.report[(self.report['sample'] == self.sample_id) & (self.report['gate_name'] == gate_name)]
148-
149-
if len(results) > 1:
150-
raise NotImplementedError("Gate ID %s is ambiguous and gate_path is not yet implemented for this method")
154+
results = self._filter_gate_report(gate_name, gate_path=gate_path)
151155

152156
return results['relative_percent'].values[0]

flowkit/_models/sample.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -426,12 +426,10 @@ def _get_orig_events(self, subsample=False):
426426
:return: NumPy array of original events
427427
"""
428428
if self._orig_events is None:
429-
warnings.warn(
429+
raise ValueError(
430430
"Original events were not cached, to retrieve them create a "
431-
"Sample instance with cache_original_events=True",
432-
UserWarning
431+
"Sample instance with cache_original_events=True"
433432
)
434-
return None
435433

436434
if subsample:
437435
return self._orig_events[self.subsample_indices]

flowkit/_models/session.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def _gate_samples(gating_strategies, samples, cache_events, verbose, use_mp=Fals
8484
proc_count = sample_count
8585

8686
with mp.get_context(mp_context).Pool(processes=proc_count, maxtasksperchild=1) as pool:
87-
if True:
87+
if verbose:
8888
print(
8989
'#### Processing gates for %d samples (multiprocessing is enabled - %d cpus) ####'
9090
% (sample_count, proc_count)

flowkit/_utils/wsp_utils.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,9 @@ def _recurse_wsp_sub_populations(sub_pop_el, gate_path, gating_ns, data_type_ns)
282282
ns_map = sub_pop_el.nsmap
283283

284284
if gate_path is None:
285-
gate_path = []
285+
# here we'll create the gate path as a list b/c we will append to it for recursion
286+
# however, when it is finally stored in the list of gate dicts we will convert to tuple
287+
gate_path = ['root']
286288
parent_id = None
287289
else:
288290
parent_id = gate_path[-1]
@@ -324,7 +326,7 @@ def _recurse_wsp_sub_populations(sub_pop_el, gate_path, gating_ns, data_type_ns)
324326
{
325327
'owning_group': owning_group,
326328
'gate': g,
327-
'gate_path': gate_path
329+
'gate_path': tuple(gate_path) # converting to tuple!
328330
}
329331
)
330332

flowkit/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.8.0"
1+
__version__ = "0.8.1"

flowkit/tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from .gating_strategy_tests import GatingStrategyTestCase, GatingStrategyReusedGatesTestCase
1212
from .session_tests import SessionTestCase
1313
from .flowjo_wsp_tests import FlowJoWSPTestCase
14+
from .gating_results_tests import GatingResultsTestCase
1415
from .matrix_tests import MatrixTestCase
1516
from .transform_tests import TransformsTestCase
1617
from .gate_tests import GateTestCase

flowkit/tests/flowjo_wsp_tests.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,22 @@ def test_get_ambiguous_gate_objects(self):
196196
self.assertIsInstance(gate_indices, np.ndarray)
197197
self.assertEqual(np.sum(gate_indices), 21)
198198

199+
def test_parse_wsp_reused_gate_with_child(self):
200+
wsp_path = "examples/data/8_color_data_set/reused_quad_gate_with_child.wsp"
201+
202+
fks = Session(copy.deepcopy(test_samples_8c_full_set))
203+
fks.import_flowjo_workspace(wsp_path, ignore_missing_files=True)
204+
group_name = 'All Samples'
205+
gate_name = 'some_child_gate'
206+
207+
gate_ids = fks.get_gate_ids(group_name)
208+
209+
gate_id_1 = (gate_name, ('root', 'good cells', 'cd4+', 'Q2: CD107a+, IL2+'))
210+
gate_id_2 = (gate_name, ('root', 'good cells', 'cd8+', 'Q2: CD107a+, IL2+'))
211+
212+
self.assertIn(gate_id_1, gate_ids)
213+
self.assertIn(gate_id_2, gate_ids)
214+
199215
def test_analyze_single_sample(self):
200216
wsp_path = "examples/data/8_color_data_set/8_color_ICS_simple.wsp"
201217
sample_id = '101_DEN084Y5_15_E01_008_clean.fcs'

flowkit/tests/gate_tests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import unittest
55
import numpy as np
66

7-
from flowkit import gates, Dimension
7+
from flowkit import Dimension
88
from .gating_strategy_tests import poly1_gate
99

1010
test_data_range1 = np.linspace(0.0, 10.0, 101)

0 commit comments

Comments
 (0)