Skip to content

Commit 7209121

Browse files
committed
PR fixups
1 parent 1e73fe3 commit 7209121

File tree

6 files changed

+184
-60
lines changed

6 files changed

+184
-60
lines changed

cellengine/compensation.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ def __repr__(self):
1616

1717
_properties = attr.ib(default={}, repr=False)
1818

19-
_id = _helpers.GetSet("_id", read_only=True)
19+
_id = helpers.GetSet("_id", read_only=True)
2020

21-
name = _helpers.GetSet("name")
21+
name = helpers.GetSet("name")
2222

23-
experiment_id = _helpers.GetSet("experimentId")
23+
experiment_id = helpers.GetSet("experimentId")
2424

25-
channels = _helpers.GetSet("channels")
25+
channels = helpers.GetSet("channels")
2626

2727
@property
2828
def N(self):

cellengine/complex_population_creator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
cellengine = __import__(__name__.split(".")[0])
22
import attr
3-
from . import _helpers
3+
from . import helpers
44
from .population import Population
55

66

77
def create_complex_population(experiment_id, base_gate, name, gates):
88
body = {"name": name, "gates": base_gate}
99
body.update(gates)
10-
res = _helpers.base_create(
10+
res = helpers.base_create(
1111
classname=Population,
1212
url="experiments/{0}/populations".format(experiment_id),
1313
json=body,

cellengine/experiment.py

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
import attr
22
from custom_inherit import doc_inherit
3-
4-
cellengine = __import__(__name__.split(".")[0])
53
from . import helpers
64
from . import loader
75
from .population import Population
86
from .fcsfile import FcsFile
97
from .compensation import Compensation
108
from .gate import Gate
119
from . import Gates
12-
13-
# from .complex_population_creator import ComplexPopulationRequest
1410
from .complex_population_creator import create_complex_population
1511

12+
cellengine = __import__(__name__.split(".")[0])
13+
1614

1715
@attr.s(repr=False)
1816
class Experiment(object):
@@ -161,16 +159,6 @@ def create_split_gate(self, *args, **kwargs):
161159
def create_quadrant_gate(self, *args, **kwargs):
162160
return getattr(Gates, "create_quadrant_gate")(self._id, *args, **kwargs)
163161

164-
def create_complex_population(
165-
self,
166-
name,
167-
base_gate,
168-
and_gates=None,
169-
or_gates=None,
170-
not_gates=None,
171-
xor_gates=None,
172-
):
162+
def create_complex_population(self, name, base_gate, gates):
173163
"""Create a complex population. Pass Gate objects to the logical args."""
174-
return Complex_Population_Request().create_complex_population(
175-
self._id, name, base_gate, and_gates, or_gates, not_gates, xor_gates
176-
)
164+
return create_complex_population(self._id, name, base_gate, gates)

cellengine/fcsfile.py

Lines changed: 14 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,50 +15,27 @@ def __repr__(self):
1515

1616
_events = attr.ib(default=None)
1717

18-
name = helpers.GetSet('filename')
18+
name = helpers.GetSet("filename")
1919

20-
_id = _helpers.GetSet("_id", read_only=True)
20+
_id = helpers.GetSet("_id", read_only=True)
2121

22-
experiment_id = _helpers.GetSet("experimentId", read_only=True)
22+
experiment_id = helpers.GetSet("experimentId", read_only=True)
2323

24-
panel_name = _helpers.GetSet("panelName")
24+
panel_name = helpers.GetSet("panelName")
2525

26-
event_count = _helpers.GetSet("eventCount")
26+
event_count = helpers.GetSet("eventCount")
2727

28-
has_file_internal_comp = _helpers.GetSet("hasFileInternalComp")
28+
has_file_internal_comp = helpers.GetSet("hasFileInternalComp")
2929

30-
size = _helpers.GetSet("size")
30+
size = helpers.GetSet("size")
3131

32-
md5 = _helpers.GetSet("md5")
32+
md5 = helpers.GetSet("md5")
3333

34-
filename = _helpers.GetSet("filename")
34+
filename = helpers.GetSet("filename")
3535

36-
panel = _helpers.GetSet("panel")
36+
panel = helpers.GetSet("panel")
3737

38-
compensation = _helpers.GetSet("compensation")
39-
=======
40-
name = helpers.GetSet('filename')
41-
42-
_id = helpers.GetSet('_id', read_only=True)
43-
44-
experiment_id = helpers.GetSet('experimentId', read_only=True)
45-
46-
panel_name = helpers.GetSet('panelName')
47-
48-
event_count = helpers.GetSet('eventCount')
49-
50-
has_file_internal_comp = helpers.GetSet('hasFileInternalComp')
51-
52-
size = helpers.GetSet('size')
53-
54-
md5 = helpers.GetSet('md5')
55-
56-
filename = helpers.GetSet('filename')
57-
58-
panel = helpers.GetSet('panel')
59-
60-
compensation = helpers.GetSet('compensation')
61-
>>>>>>> a55497c... changed _helpers to helpers
38+
compensation = helpers.GetSet("compensation")
6239

6340
@property
6441
def annotations(self):
@@ -85,8 +62,9 @@ def events(self):
8562
from the server on-demand the first time that this property is accessed.
8663
"""
8764
if self._events is None:
88-
fresp = helpers.base_get("experiments/{0}/fcsfiles/{1}.fcs".format(self.experiment_id,
89-
self._id))
65+
fresp = helpers.base_get(
66+
"experiments/{0}/fcsfiles/{1}.fcs".format(self.experiment_id, self._id)
67+
)
9068
parser = fcsparser.api.FCSParser.from_data(fresp.content)
9169
self._events = pandas.DataFrame(parser.data, columns=parser.channel_names_n)
9270
return self._events

cellengine/gate.py.orig

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import attr
2+
import munch
3+
<<<<<<< HEAD
4+
from . import helpers
5+
from .Gates import (
6+
create_rectangle_gate,
7+
create_ellipse_gate,
8+
create_polygon_gate,
9+
create_range_gate,
10+
create_split_gate,
11+
create_quadrant_gate,
12+
)
13+
=======
14+
from . import helpers
15+
from .Gates import (create_rectangle_gate, create_ellipse_gate,
16+
create_polygon_gate, create_range_gate, create_split_gate,
17+
create_quadrant_gate)
18+
>>>>>>> a55497c... changed helpers to helpers
19+
from .Gates.gate_util import create_gates
20+
21+
22+
@attr.s(repr=False)
23+
class Gate(object):
24+
"""A class representing a CellEngine gate.
25+
26+
Gates are geometric shapes that define boundaries within which events
27+
(cells) must be contained to be considered part of a population.
28+
29+
Gates may be any one of RectangleGate, PolygonGate, EllipseGate, RangeGate,
30+
QuadrantGate or SplitGate. See ``help(cellengine.Gate.<Gate Type>)`` for
31+
specific args.
32+
33+
When tailoring a gate to a file, a new gate is created with the same GID as
34+
the original gate, but with an fcs_file_id property set to the file to which
35+
the gate is tailored. To create a tailored gate, first create a global
36+
tailored gate by passing ``tailored_per_file=True`` and
37+
``fcs_file_id=None`` to a gate creation method. Subsequent tailored gates
38+
may be created with ``tailored_per_file=True`` and ``gid=<global gate
39+
gid>``.
40+
41+
The update and delete API endpoints accept requests by GID to make
42+
for efficient updates to families of tailored gates.
43+
44+
Compound gates (quadrant and split) are made up of "sectors." Quadrant
45+
gates have four sectors (upper-right, upper-left, lower-left, lower-right)
46+
and split gates have two sectors (left and right). In addition to the
47+
top-level GID (like simple gates), these gates have model.gids and names
48+
lists that specify the GID and name for each sector, in the order shown
49+
above. Populations using compound gates must reference these sector GIDs;
50+
referencing the top-level GID of a compound gate is meaningless.
51+
"""
52+
53+
def __repr__(self):
54+
return "Gate(_id='{0}', name='{1}', type={2})".format(
55+
self._id, self.name, self.type
56+
)
57+
58+
_properties = attr.ib(default={}, repr=False)
59+
60+
<<<<<<< HEAD
61+
_id = helpers.GetSet("_id", read_only=True)
62+
63+
name = helpers.GetSet("name")
64+
65+
# TODO: bad usage of a Python builtin; can we change this? (is functional)
66+
type = helpers.GetSet("type")
67+
68+
experiment_id = helpers.GetSet("experimentId", read_only=True)
69+
70+
gid = helpers.GetSet("gid")
71+
72+
x_channel = helpers.GetSet("xChannel")
73+
74+
y_channel = helpers.GetSet("yChannel")
75+
76+
tailored_per_file = helpers.GetSet("tailoredPerFile")
77+
78+
fcs_file_id = helpers.GetSet("fcsFileId")
79+
80+
parent_population_id = helpers.GetSet("parentPopulationId")
81+
82+
names = helpers.GetSet("names")
83+
=======
84+
_id = helpers.GetSet('_id', read_only=True)
85+
86+
name = helpers.GetSet('name')
87+
88+
# TODO: bad usage of a Python builtin; can we change this? (is functional)
89+
type = helpers.GetSet('type')
90+
91+
experiment_id = helpers.GetSet('experimentId', read_only=True)
92+
93+
gid = helpers.GetSet('gid')
94+
95+
x_channel = helpers.GetSet('xChannel')
96+
97+
y_channel = helpers.GetSet('yChannel')
98+
99+
tailored_per_file = helpers.GetSet('tailoredPerFile')
100+
101+
fcs_file_id = helpers.GetSet('fcsFileId')
102+
103+
parent_population_id = helpers.GetSet('parentPopulationId')
104+
105+
names = helpers.GetSet('names')
106+
>>>>>>> a55497c... changed helpers to helpers
107+
108+
@property
109+
def model(self):
110+
"""Return an attribute-style dict of the model.
111+
112+
NOTE: This approach does allow users to change the model properties to
113+
invalid values (i.e. 'rectangle' to a str from a dict). We could
114+
prevent this by making Gate.model return a __slot__ class "Model", where each
115+
attr of Model was built dynamically. I wrote it this way at first, but
116+
couldn't figure out a way to write both get and set attribute-style accessors
117+
for the class. Munch does this really nicely.
118+
119+
As it is, this relies on the API to validate the model. If necessary, I
120+
can write validators in here as well.
121+
"""
122+
model = self._properties["model"]
123+
if type(model) is not Gate._Munch:
124+
self._properties["model"] = munch.munchify(model, factory=self._Munch)
125+
return model
126+
127+
@model.setter
128+
def model(self, val):
129+
model = self._properties["model"]
130+
model.update(val)
131+
132+
class _Munch(munch.Munch):
133+
"""Extend the Munch class for a dict-like __repr__"""
134+
135+
def __repr__(self):
136+
return "{0}".format(dict.__repr__(self))
137+
138+
# gate creation methods
139+
140+
create_gates = staticmethod(create_gates)
141+
142+
create_rectangle_gate = staticmethod(create_rectangle_gate)
143+
144+
create_polygon_gate = staticmethod(create_polygon_gate)
145+
146+
create_ellipse_gate = staticmethod(create_ellipse_gate)
147+
148+
create_range_gate = staticmethod(create_range_gate)
149+
150+
create_split_gate = staticmethod(create_split_gate)
151+
152+
create_quadrant_gate = staticmethod(create_quadrant_gate)

tests/unit/test_complex_population.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,14 @@
3636
# test_all_population_properties(complex_pop)
3737

3838

39-
# @responses.activate
40-
def test_create_complex_population_basic(experiment, gates):
39+
@responses.activate
40+
def test_create_complex_population_basic(experiment, gates, populations):
41+
responses.add(
42+
responses.POST,
43+
base_url + "experiments/5d38a6f79fae87499999a74b/populations",
44+
json=populations[0],
45+
status=201,
46+
)
4147
complex_pop = experiment.create_complex_population(
4248
base_gate=gates[0]["_id"],
4349
name="complex",

0 commit comments

Comments
 (0)