Exemple #1
0
    def test_gating_strategy_repr(self):
        gs = fk.GatingStrategy()

        gs.add_comp_matrix(prog_test_data.comp_matrix_01)

        gs.add_transform(prog_test_data.logicle_xform1)
        gs.add_transform(prog_test_data.hyperlog_xform1)

        gs.add_gate(prog_test_data.poly1_gate)

        dim1 = fk.Dimension('PE', 'MySpill', 'Logicle_10000_0.5_4.5_0', range_min=0.31, range_max=0.69)
        dim2 = fk.Dimension('PerCP', 'MySpill', 'Logicle_10000_0.5_4.5_0', range_min=0.27, range_max=0.73)
        dims1 = [dim1, dim2]

        rect_gate1 = fk.gates.RectangleGate('ScaleRect1', None, dims1)
        gs.add_gate(rect_gate1)

        dim3 = fk.Dimension('FITC', 'MySpill', 'Hyperlog_10000_1_4.5_0', range_min=0.12, range_max=0.43)
        dims2 = [dim3]

        rect_gate2 = fk.gates.RectangleGate('ScalePar1', 'ScaleRect1', dims2)
        gs.add_gate(rect_gate2)

        gs_string = "GatingStrategy(3 gates, 2 transforms, 1 compensations)"

        self.assertEqual(repr(gs), gs_string)
Exemple #2
0
    def test_add_poly3_non_solid_gate():
        gs = fk.GatingStrategy()

        dim1 = fk.Dimension('SSC-H', compensation_ref='uncompensated')
        dim2 = fk.Dimension('FL3-H', compensation_ref='FCS')
        dims = [dim1, dim2]

        vertices = [
            fk.Vertex([10, 10]),
            fk.Vertex([500, 10]),
            fk.Vertex([500, 390]),
            fk.Vertex([100, 390]),
            fk.Vertex([100, 180]),
            fk.Vertex([200, 180]),
            fk.Vertex([200, 300]),
            fk.Vertex([10, 300])
        ]

        poly_gate = fk.gates.PolygonGate('Polygon3NS', None, dims, vertices)
        gs.add_gate(poly_gate)

        res_path = 'examples/data/gate_ref/truth/Results_Polygon3NS.txt'
        truth = pd.read_csv(res_path, header=None, squeeze=True,
                            dtype='bool').values

        result = gs.gate_sample(data1_sample)

        np.testing.assert_array_equal(truth,
                                      result.get_gate_membership('Polygon3NS'))
Exemple #3
0
    def test_add_matrix_rect5_gate():
        gs = fk.GatingStrategy()

        gs.add_comp_matrix(comp_matrix_01)

        dim1 = fk.Dimension('PerCP',
                            compensation_ref='MySpill',
                            range_min=7,
                            range_max=90)
        dim2 = fk.Dimension('FSC-H',
                            compensation_ref='uncompensated',
                            range_min=10)
        dims = [dim1, dim2]

        rect_gate = fk.gates.RectangleGate('Rectangle5', None, dims)
        gs.add_gate(rect_gate)

        res_path = 'examples/data/gate_ref/truth/Results_Rectangle5.txt'
        truth = pd.read_csv(res_path, header=None, squeeze=True,
                            dtype='bool').values

        result = gs.gate_sample(data1_sample)

        np.testing.assert_array_equal(truth,
                                      result.get_gate_membership('Rectangle5'))
Exemple #4
0
    def test_add_parent_quadrant_rect_gate():
        gs = fk.GatingStrategy()
        gs.add_gate(quad1_gate)

        dim1 = fk.Dimension('FL2-H',
                            'uncompensated',
                            None,
                            range_min=6,
                            range_max=14.4)
        dim2 = fk.Dimension('FL4-H',
                            'uncompensated',
                            None,
                            range_min=7,
                            range_max=16)
        dims1 = [dim1, dim2]

        rect_gate1 = fk.gates.RectangleGate('ParRectangle1', 'FL2P-FL4P',
                                            dims1)
        gs.add_gate(rect_gate1)

        res_path = 'examples/data/gate_ref/truth/Results_ParQuadRect.txt'
        truth = pd.read_csv(res_path, header=None, squeeze=True,
                            dtype='bool').values

        result = gs.gate_sample(data1_sample)

        np.testing.assert_array_equal(
            truth, result.get_gate_membership('ParRectangle1'))
Exemple #5
0
    def test_cache_preprocessed_events(self):
        gs = fk.GatingStrategy()

        gs.add_comp_matrix(comp_matrix_01)

        gs.add_transform(logicle_xform1)
        gs.add_transform(hyperlog_xform1)

        gs.add_gate(poly1_gate)

        dim1 = fk.Dimension('PE', 'MySpill', 'Logicle_10000_0.5_4.5_0', range_min=0.31, range_max=0.69)
        dim2 = fk.Dimension('PerCP', 'MySpill', 'Logicle_10000_0.5_4.5_0', range_min=0.27, range_max=0.73)
        dims1 = [dim1, dim2]

        rect_gate1 = fk.gates.RectangleGate('ScaleRect1', None, dims1)
        gs.add_gate(rect_gate1)

        dim3 = fk.Dimension('FITC', 'MySpill', 'Hyperlog_10000_1_4.5_0', range_min=0.12, range_max=0.43)
        dims2 = [dim3]

        rect_gate2 = fk.gates.RectangleGate('ScalePar1', 'ScaleRect1', dims2)
        gs.add_gate(rect_gate2)

        _ = gs.gate_sample(data1_sample, cache_events=True)

        pre_proc_events = gs._cached_preprocessed_events

        truth_key_set = {
            ('MySpill', None, None),
            ('MySpill', 'Logicle_10000_0.5_4.5_0', 3),
            ('MySpill', 'Logicle_10000_0.5_4.5_0', 4),
            ('MySpill', 'Hyperlog_10000_1_4.5_0', 2)
        }

        self.assertSetEqual(set(pre_proc_events['B07'].keys()), truth_key_set)
Exemple #6
0
    def test_add_matrix_transform_logicle_rect1_gate():
        gs = fk.GatingStrategy()

        gs.add_comp_matrix(comp_matrix_01)

        gs.add_transform(logicle_xform1)

        dim1 = fk.Dimension('PE',
                            'MySpill',
                            'Logicle_10000_0.5_4.5_0',
                            range_min=0.31,
                            range_max=0.69)
        dim2 = fk.Dimension('PerCP',
                            'MySpill',
                            'Logicle_10000_0.5_4.5_0',
                            range_min=0.27,
                            range_max=0.73)
        dims = [dim1, dim2]

        rect_gate = fk.gates.RectangleGate('ScaleRect1', None, dims)
        gs.add_gate(rect_gate)

        res_path = 'examples/data/gate_ref/truth/Results_ScaleRect1.txt'
        truth = pd.read_csv(res_path, header=None, squeeze=True,
                            dtype='bool').values

        result = gs.gate_sample(data1_sample)

        np.testing.assert_array_equal(truth,
                                      result.get_gate_membership('ScaleRect1'))
Exemple #7
0
    def test_add_matrix_transform_hyperlog_range7c_gate():
        gs = fk.GatingStrategy()

        gs.add_comp_matrix(comp_matrix_01)

        gs.add_transform(hyperlog_xform1)

        dim1 = fk.Dimension('PE',
                            'MySpill',
                            'Hyperlog_10000_1_4.5_0',
                            range_min=0.09,
                            range_max=0.36)
        dims = [dim1]

        rect_gate = fk.gates.RectangleGate('ScaleRange7c', None, dims)
        gs.add_gate(rect_gate)

        res_path = 'examples/data/gate_ref/truth/Results_ScaleRange7c.txt'
        truth = pd.read_csv(res_path, header=None, squeeze=True,
                            dtype='bool').values

        result = gs.gate_sample(data1_sample)

        np.testing.assert_array_equal(
            truth, result.get_gate_membership('ScaleRange7c'))
Exemple #8
0
    def test_add_transform_log_range6_gate():
        gs = fk.GatingStrategy()

        xform = fk.transforms.LogTransform('Logarithmic_10000_5',
                                           param_t=10000,
                                           param_m=5)
        gs.add_transform(xform)

        dim1 = fk.Dimension('FL1-H',
                            'uncompensated',
                            'Logarithmic_10000_5',
                            range_min=0.37,
                            range_max=0.63)
        dims = [dim1]

        rect_gate = fk.gates.RectangleGate('ScaleRange6', None, dims)
        gs.add_gate(rect_gate)

        res_path = 'examples/data/gate_ref/truth/Results_ScaleRange6.txt'
        truth = pd.read_csv(res_path, header=None, squeeze=True,
                            dtype='bool').values

        result = gs.gate_sample(data1_sample)

        np.testing.assert_array_equal(
            truth, result.get_gate_membership('ScaleRange6'))
Exemple #9
0
    def test_plot_gated_scatter(self):
        fks = fk.Session(fcs_path)
        fks.add_sample_group('my_group', gml_path)

        group_name = 'my_group'
        sample_name = 'B07'
        fks.assign_sample(sample_name, group_name)
        x_dim = fk.Dimension('FL2-H',
                             compensation_ref='MySpill',
                             transformation_ref='Logicle_10000_0.5_4.5_0')
        y_dim = fk.Dimension('FL3-H',
                             compensation_ref='MySpill',
                             transformation_ref='Logicle_10000_0.5_4.5_0')

        p = fks.plot_scatter(sample_name,
                             x_dim,
                             y_dim,
                             sample_group=group_name,
                             gate_id='ScaleRect1')

        self.assertIsInstance(p, Figure)
Exemple #10
0
    def test_add_matrix_poly4_gate():
        gs = fk.GatingStrategy()

        gs.add_comp_matrix(comp_matrix_01)

        dim1 = fk.Dimension('PE', compensation_ref='MySpill')
        dim2 = fk.Dimension('PerCP', compensation_ref='MySpill')
        dims = [dim1, dim2]

        poly_gate = fk.gates.PolygonGate('Polygon4', None, dims,
                                         poly1_vertices)
        gs.add_gate(poly_gate)

        res_path = 'examples/data/gate_ref/truth/Results_Polygon4.txt'
        truth = pd.read_csv(res_path, header=None, squeeze=True,
                            dtype='bool').values

        result = gs.gate_sample(data1_sample)

        np.testing.assert_array_equal(truth,
                                      result.get_gate_membership('Polygon4'))
Exemple #11
0
    def test_plot_gated_scatter(self):
        fks = fk.Session(copy.deepcopy(test_sample))
        fks.add_sample_group('my_group', copy.deepcopy(test_gating_strategy))

        group_name = 'my_group'
        sample_name = 'B07'
        fks.assign_samples(sample_name, group_name)
        fks.analyze_samples(group_name, sample_id=sample_name)

        x_dim = fk.Dimension('FL2-H', compensation_ref='MySpill', transformation_ref='Logicle_10000_0.5_4.5_0')
        y_dim = fk.Dimension('FL3-H', compensation_ref='MySpill', transformation_ref='Logicle_10000_0.5_4.5_0')

        p = fks.plot_scatter(
            sample_name,
            x_dim,
            y_dim,
            group_name=group_name,
            gate_name='ScaleRect1',
            subsample=True
        )

        self.assertIsInstance(p, bk_Figure)
Exemple #12
0
    def test_add_boolean_or2_complement_gate():
        gs = fk.GatingStrategy()

        dim1 = fk.Dimension('SSC-H',
                            compensation_ref='FCS',
                            range_min=20,
                            range_max=80)
        dim2 = fk.Dimension('FL1-H',
                            compensation_ref='FCS',
                            range_min=70,
                            range_max=200)
        rect_dims = [dim1, dim2]

        rect_gate = fk.gates.RectangleGate('Rectangle2', None, rect_dims)
        gs.add_gate(rect_gate)
        gs.add_gate(quad1_gate)

        gate1_refs = [{
            'ref': 'Rectangle2',
            'path': ('root', ),
            'complement': False
        }, {
            'ref': 'FL2N-FL4N',
            'path': ('root', 'Quadrant1'),
            'complement': True
        }]

        bool1_gate = fk.gates.BooleanGate('Or2', None, 'or', gate1_refs)
        gs.add_gate(bool1_gate)

        res_path = 'examples/data/gate_ref/truth/Results_Or2.txt'
        truth = pd.read_csv(res_path, header=None, squeeze=True,
                            dtype='bool').values

        result = gs.gate_sample(data1_sample)

        np.testing.assert_array_equal(truth, result.get_gate_membership('Or2'))
Exemple #13
0
    def test_add_parent_poly1_boolean_and2_gate():
        gs = fk.GatingStrategy()

        gs.add_gate(poly1_gate)

        dim3 = fk.Dimension('FL3-H', compensation_ref='FCS')
        dim4 = fk.Dimension('FL4-H', compensation_ref='FCS')
        dims2 = [dim3, dim4]

        ellipse_gate = fk.gates.EllipsoidGate('Ellipse1', None, dims2,
                                              ell1_coords, ell1_cov_mat,
                                              ell1_dist_square)
        gs.add_gate(ellipse_gate)
        gs.add_gate(range1_gate)

        gate_refs = [{
            'ref': 'Range1',
            'path': ('root', ),
            'complement': False
        }, {
            'ref': 'Ellipse1',
            'path': ('root', ),
            'complement': False
        }]

        bool_gate = fk.gates.BooleanGate('ParAnd2', 'Polygon1', 'and',
                                         gate_refs)
        gs.add_gate(bool_gate)

        res_path = 'examples/data/gate_ref/truth/Results_ParAnd2.txt'
        truth = pd.read_csv(res_path, header=None, squeeze=True,
                            dtype='bool').values

        result = gs.gate_sample(data1_sample)

        np.testing.assert_array_equal(truth,
                                      result.get_gate_membership('ParAnd2'))
Exemple #14
0
    def test_absolute_percent(self):
        gs = fk.GatingStrategy()

        gs.add_comp_matrix(comp_matrix_01)

        gs.add_transform(logicle_xform1)
        gs.add_transform(hyperlog_xform1)

        gs.add_gate(poly1_gate)

        dim1 = fk.Dimension('PE', 'MySpill', 'Logicle_10000_0.5_4.5_0', range_min=0.31, range_max=0.69)
        dim2 = fk.Dimension('PerCP', 'MySpill', 'Logicle_10000_0.5_4.5_0', range_min=0.27, range_max=0.73)
        dims1 = [dim1, dim2]

        rect_gate1 = fk.gates.RectangleGate('ScaleRect1', None, dims1)
        gs.add_gate(rect_gate1)

        dim3 = fk.Dimension('FITC', 'MySpill', 'Hyperlog_10000_1_4.5_0', range_min=0.12, range_max=0.43)
        dims2 = [dim3]

        rect_gate2 = fk.gates.RectangleGate('ScalePar1', 'ScaleRect1', dims2)
        gs.add_gate(rect_gate2)

        result = gs.gate_sample(data1_sample)
        parent_gate = gs.get_parent_gate(rect_gate2.gate_name)
        parent_gate_count = result.get_gate_count(parent_gate.gate_name)
        gate_count = result.get_gate_count(rect_gate2.gate_name)
        gate_abs_pct = result.get_gate_absolute_percent(rect_gate2.gate_name)
        gate_rel_pct = result.get_gate_relative_percent(rect_gate2.gate_name)

        true_count = 558
        true_abs_pct = (558 / data1_sample.event_count) * 100
        true_rel_pct = (558 / float(parent_gate_count)) * 100

        self.assertEqual(true_count, gate_count)
        self.assertEqual(true_abs_pct, gate_abs_pct)
        self.assertEqual(true_rel_pct, gate_rel_pct)
Exemple #15
0
    def test_add_rect2_gate():
        gs = fk.GatingStrategy()

        dim1 = fk.Dimension('SSC-H',
                            compensation_ref='FCS',
                            range_min=20,
                            range_max=80)
        dim2 = fk.Dimension('FL1-H',
                            compensation_ref='FCS',
                            range_min=70,
                            range_max=200)
        dims = [dim1, dim2]

        rect_gate = fk.gates.RectangleGate('Rectangle2', None, dims)
        gs.add_gate(rect_gate)

        res_path = 'examples/data/gate_ref/truth/Results_Rectangle2.txt'
        truth = pd.read_csv(res_path, header=None, squeeze=True,
                            dtype='bool').values

        result = gs.gate_sample(data1_sample)

        np.testing.assert_array_equal(truth,
                                      result.get_gate_membership('Rectangle2'))
Exemple #16
0
    def test_add_ellipsoid_3d_gate():
        gs = fk.GatingStrategy()

        dim1 = fk.Dimension('FL3-H', compensation_ref='FCS')
        dim2 = fk.Dimension('FL4-H', compensation_ref='FCS')
        dim3 = fk.Dimension('FL1-H', compensation_ref='FCS')
        dims = [dim1, dim2, dim3]

        coords = [40.3, 30.6, 20.8]
        cov_mat = [[2.5, 7.5, 17.5], [7.5, 7.0, 13.5], [15.5, 13.5, 4.3]]
        dist_square = 1

        poly_gate = fk.gates.EllipsoidGate('Ellipsoid3D', None, dims, coords,
                                           cov_mat, dist_square)
        gs.add_gate(poly_gate)

        res_path = 'examples/data/gate_ref/truth/Results_Ellipsoid3D.txt'
        truth = pd.read_csv(res_path, header=None, squeeze=True,
                            dtype='bool').values

        result = gs.gate_sample(data1_sample)

        np.testing.assert_array_equal(
            truth, result.get_gate_membership('Ellipsoid3D'))
Exemple #17
0
    def test_add_transform_logicle_range5_gate():
        gs = fk.GatingStrategy()

        gs.add_transform(logicle_xform3)

        dim1 = fk.Dimension('FL1-H',
                            'uncompensated',
                            'Logicle_10000_1_4_0.5',
                            range_min=0.37,
                            range_max=0.63)
        dims = [dim1]

        rect_gate = fk.gates.RectangleGate('ScaleRange5', None, dims)
        gs.add_gate(rect_gate)

        res_path = 'examples/data/gate_ref/truth/Results_ScaleRange5.txt'
        truth = pd.read_csv(res_path, header=None, squeeze=True,
                            dtype='bool').values

        result = gs.gate_sample(data1_sample)

        np.testing.assert_array_equal(
            truth, result.get_gate_membership('ScaleRange5'))
Exemple #18
0
    def setUp(self):
        """
        This TestCase tests more complex GatingStrategy use cases, particularly
        the re-use of a gate in 2 different branches where the parent of each
        gate is also re-used. For example:

        root
        ╰── Gate_A
            ├── Gate_B
            │   ╰── ReusedParent
            │       ╰── ReusedChild
            ╰── Gate_C
                ╰── ReusedParent
                    ╰── ReusedChild

        :return: None
        """
        self.gs = fk.GatingStrategy()

        time_dim = fk.Dimension('Gate_A', range_min=0.1, range_max=0.9)
        dim_fsc_w = fk.Dimension('FSC-W')
        dim_fsc_h = fk.Dimension('FSC-H')
        dim_ssc_a = fk.Dimension('SSC-A')
        dim_amine_a = fk.Dimension('Aqua Amine FLR-A')
        dim_cd3_a = fk.Dimension('CD3 APC-H7 FLR-A')

        gate_a = fk.gates.RectangleGate('Gate_A', None, [time_dim])
        self.gs.add_gate(gate_a)

        gate_b_vertices = [
            fk.Vertex([0.328125, 0.1640625]),
            fk.Vertex([0.296875, 0.1484375]),
            fk.Vertex([0.30859375, 0.8515625]),
            fk.Vertex([0.34765625, 0.3984375]),
            fk.Vertex([0.3359375, 0.1875])
        ]
        gate_b = fk.gates.PolygonGate(
            'Gate_B', parent_gate_name=gate_a.gate_name, dimensions=[dim_fsc_w, dim_fsc_h], vertices=gate_b_vertices
        )
        self.gs.add_gate(gate_b)

        gate_c_vertices = [
            fk.Vertex([0.328125, 0.1640625]),
            fk.Vertex([0.296875, 0.1484375]),
            fk.Vertex([0.30859375, 0.8515625]),
            fk.Vertex([0.34765625, 0.3984375]),
            fk.Vertex([0.3359375, 0.1875])
        ]
        gate_c = fk.gates.PolygonGate(
            'Gate_C', parent_gate_name=gate_a.gate_name, dimensions=[dim_fsc_h, dim_fsc_w], vertices=gate_c_vertices
        )
        self.gs.add_gate(gate_c)

        reused_parent_vertices = [
            fk.Vertex([0.2629268137285685, 0.0625]),
            fk.Vertex([0.24318837264468562, 0.03515625]),
            fk.Vertex([0.21573453285608676, 0.0390625]),
            fk.Vertex([0.29042797365869377, 0.24609375]),
            fk.Vertex([0.29042797365869377, 0.1484375])
        ]

        reused_parent_gate_1 = fk.gates.PolygonGate(
            'ReusedParent', gate_b.gate_name, [dim_amine_a, dim_ssc_a], reused_parent_vertices
        )
        reused_parent_gate_2 = fk.gates.PolygonGate(
            'ReusedParent', gate_c.gate_name, [dim_amine_a, dim_ssc_a], reused_parent_vertices
        )
        self.gs.add_gate(reused_parent_gate_1)
        self.gs.add_gate(reused_parent_gate_2)

        reused_child_vertices = [
            fk.Vertex([0.28415161867527605, 0.11328125]),
            fk.Vertex([0.3132637699981912, 0.203125]),
            fk.Vertex([0.6896802981119161, 0.05078125]),
            fk.Vertex([0.5692952580886116, 0.01953125]),
            fk.Vertex([0.3192472844795108, 0.01953125])
        ]

        reused_child_gate = fk.gates.PolygonGate(
            'ReusedChild', 'ReusedParent', [dim_cd3_a, dim_ssc_a], reused_child_vertices
        )

        gate_path_1 = ('root', 'Gate_A', 'Gate_B', 'ReusedParent')
        gate_path_2 = ('root', 'Gate_A', 'Gate_C', 'ReusedParent')
        self.gs.add_gate(reused_child_gate, gate_path=gate_path_1)
        self.gs.add_gate(reused_child_gate, gate_path=gate_path_2)

        self.all_gate_ids = [
            ('Gate_A', ('root',)),
            ('Gate_B', ('root', 'Gate_A')),
            ('ReusedParent', ('root', 'Gate_A', 'Gate_B')),
            ('ReusedChild', ('root', 'Gate_A', 'Gate_B', 'ReusedParent')),
            ('Gate_C', ('root', 'Gate_A')),
            ('ReusedParent', ('root', 'Gate_A', 'Gate_C')),
            ('ReusedChild', ('root', 'Gate_A', 'Gate_C', 'ReusedParent'))
        ]
Exemple #19
0
import unittest
import numpy as np
import flowkit as fk


data1_fcs_path = 'examples/data/gate_ref/data1.fcs'
data1_sample = fk.Sample(data1_fcs_path)

poly1_vertices = [
    fk.Vertex([5, 5]),
    fk.Vertex([500, 5]),
    fk.Vertex([500, 500])
]
poly1_dim1 = fk.Dimension('FL2-H', compensation_ref='FCS')
poly1_dim2 = fk.Dimension('FL3-H', compensation_ref='FCS')
poly1_dims1 = [poly1_dim1, poly1_dim2]
poly1_gate = fk.gates.PolygonGate('Polygon1', None, poly1_dims1, poly1_vertices)

hyperlog_xform1 = fk.transforms.HyperlogTransform(
    'Hyperlog_10000_1_4.5_0',
    param_t=10000,
    param_w=1,
    param_m=4.5,
    param_a=0
)

logicle_xform1 = fk.transforms.LogicleTransform(
    'Logicle_10000_0.5_4.5_0',
    param_t=10000,
    param_w=0.5,
    param_m=4.5,
Exemple #20
0
    def test_dim_repr(self):
        poly1_dim1 = fk.Dimension('FL2-H', compensation_ref='FCS')
        dim_string = "Dimension(id: FL2-H)"

        self.assertEqual(repr(poly1_dim1), dim_string)
Exemple #21
0
import numpy as np
import pandas as pd

sys.path.append(os.path.abspath('../..'))

import flowkit as fk

data1_fcs_path = 'examples/data/gate_ref/data1.fcs'
data1_sample = fk.Sample(data1_fcs_path)

poly1_vertices = [
    fk.Vertex([5, 5]),
    fk.Vertex([500, 5]),
    fk.Vertex([500, 500])
]
poly1_dim1 = fk.Dimension('FL2-H', compensation_ref='FCS')
poly1_dim2 = fk.Dimension('FL3-H', compensation_ref='FCS')
poly1_dims1 = [poly1_dim1, poly1_dim2]
poly1_gate = fk.gates.PolygonGate('Polygon1', None, poly1_dims1,
                                  poly1_vertices)

quad1_div1 = fk.QuadrantDivider('FL2', 'FL2-H', 'FCS', [12.14748])
quad1_div2 = fk.QuadrantDivider('FL4', 'FL4-H', 'FCS', [14.22417])
quad1_divs = [quad1_div1, quad1_div2]

quad_1 = fk.gates.Quadrant(quadrant_id='FL2P-FL4P',
                           divider_refs=['FL2', 'FL4'],
                           divider_ranges=[(12.14748, None), (14.22417, None)])
quad_2 = fk.gates.Quadrant(quadrant_id='FL2N-FL4P',
                           divider_refs=['FL2', 'FL4'],
                           divider_ranges=[(None, 12.14748), (14.22417, None)])