コード例 #1
0
def test_export_single_plot(qtbot, monkeypatch):
    """Export of single plots not possible up until version 2.1.4"""
    spath = datapath / "version_2_1_0_basic.so2"

    mw = ShapeOut2()
    qtbot.addWidget(mw)

    mw.on_action_open(spath)

    # perform the export
    tmpd = tempfile.mkdtemp(suffix="", prefix="shapeout2_test_plot_export_")

    tmpf = os.path.join(tmpd, "no_suffix")
    assert not pathlib.Path(tmpf).exists()
    monkeypatch.setattr(QtWidgets.QFileDialog, "getSaveFileName", lambda *args:
                        (tmpf, ""))

    # create export dialog manually
    dlg = export.ExportPlot(mw, pipeline=mw.pipeline)

    # select a single plot to export
    plot_id = mw.pipeline.plot_ids[0]
    assert isinstance(plot_id, str)
    plot_index = dlg.comboBox_plot.findData(plot_id)
    assert plot_index > 0
    dlg.comboBox_plot.setCurrentIndex(plot_index)
    assert dlg.comboBox_plot.currentData() == plot_id

    dlg.export_plots()
    assert pathlib.Path(tmpf).with_suffix(".png").exists()

    # cleanup
    shutil.rmtree(tmpd, ignore_errors=True)
コード例 #2
0
def test_matrix_slots_duplicate_issue_96(qtbot):
    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add a dataslot
    path = pathlib.Path(__file__).parent / "data" / "calibration_beads_47.rtdc"
    mw.add_dataslot(paths=[path])

    assert len(mw.pipeline.slot_ids) == 1, "we added that"
    assert len(mw.pipeline.filter_ids) == 1, "automatically added"

    # change the name of the dataset
    # go to analysis view
    qtbot.mouseClick(mw.toolButton_ana_view, QtCore.Qt.LeftButton)
    # go to the dataset tab
    av = mw.widget_ana_view
    qtbot.mouseClick(av.tab_slot, QtCore.Qt.LeftButton)
    # enter a name
    ws = av.widget_slot
    ws.lineEdit_name.setText("A Unique Name")
    qtbot.mouseClick(ws.pushButton_apply, QtCore.Qt.LeftButton)

    # See if that worked
    assert mw.pipeline.slots[0].name == "A Unique Name"

    # Now duplicate the dataset
    swid = mw.block_matrix.get_widget(slot_id=mw.pipeline.slots[0].identifier)
    swid.action_duplicate()

    assert len(mw.pipeline.slot_ids) == 2, "initial + duplicate"
    assert len(mw.pipeline.filter_ids) == 1, "automatically added"

    # make sure that slot name is the same
    assert mw.pipeline.slots[0].name == "A Unique Name"
    assert mw.pipeline.slots[1].name == "A Unique Name"
コード例 #3
0
def test_wrong_medium_viscosity(qtbot):
    """Deliberately set wrong visosity"""
    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add a dataslot
    path = datapath / "calibration_beads_47.rtdc"
    mw.add_dataslot(paths=[path])
    mw.add_dataslot(paths=[path])

    # create bulk action dialog manually
    dlg = bulk.BulkActionEmodulus(mw, pipeline=mw.pipeline)
    dlg.comboBox_medium.setCurrentIndex(dlg.comboBox_medium.findData("other"))
    dlg.doubleSpinBox_visc.setValue(1.0)  # random number

    dlg.on_ok()

    for slot in mw.pipeline.slots:
        ds = slot.get_dataset()
        assert "emodulus" not in ds, "because medium is fixed"
        assert ds.config["setup"]["medium"] == "CellCarrierB"
        assert ds.config["calculation"]["emodulus lut"] == "LE-2D-FEM-19"
        assert ds.config["calculation"]["emodulus medium"] == "CellCarrierB"
        assert "emodulus temperature" not in ds.config["calculation"]
        assert "emodulus viscosity" not in ds.config["calculation"]
コード例 #4
0
def test_allow_to_set_manual_temperature_for_known_medium(qtbot):
    """Fixes regression introduced in 2.4.0"""
    mw = ShapeOut2()
    qtbot.addWidget(mw)
    # add fake measurement
    path1 = make_dataset(medium=None, temp=23.5)
    mw.add_dataslot(paths=[path1])
    wsl = mw.widget_ana_view.widget_slot

    # 1. test whether we can actually select things in comboBox_temp
    ccidx = wsl.comboBox_medium.findData("CellCarrier")
    wsl.comboBox_medium.setCurrentIndex(ccidx)
    assert wsl.comboBox_temp.isEnabled()

    # 2. test whether we can select manual
    manidx = wsl.comboBox_temp.findData("manual")
    wsl.comboBox_temp.setCurrentIndex(manidx)
    assert wsl.doubleSpinBox_temp.isEnabled()
    assert not wsl.doubleSpinBox_temp.isReadOnly()

    # 3. test whether we can select config and the the temperature
    # should be 23.5
    conidx = wsl.comboBox_temp.findData("config")
    wsl.comboBox_temp.setCurrentIndex(conidx)
    assert wsl.doubleSpinBox_temp.isEnabled()
    assert wsl.doubleSpinBox_temp.isReadOnly()
    assert wsl.doubleSpinBox_temp.value() == 23.5
コード例 #5
0
def test_matrix_slots(qtbot):
    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add a dataslot
    path = pathlib.Path(__file__).parent / "data" / "calibration_beads_47.rtdc"
    mw.add_dataslot(paths=[path])
    # add another one
    mw.add_dataslot(paths=[path])

    assert len(mw.pipeline.slot_ids) == 2, "we added those"
    assert len(mw.pipeline.filter_ids) == 1, "automatically added"

    # activate a dataslot
    slot_id = mw.pipeline.slot_ids[0]
    filt_id = mw.pipeline.filter_ids[0]
    em = mw.block_matrix.get_widget(slot_id, filt_id)
    qtbot.mouseClick(em, QtCore.Qt.LeftButton)
    # did that work?
    assert mw.pipeline.is_element_active(slot_id, filt_id)
    slot_id2 = mw.pipeline.slot_ids[1]
    assert not mw.pipeline.is_element_active(slot_id2, filt_id)

    # remove a dataslot
    wd = mw.block_matrix.get_widget(slot_id=slot_id)
    wd.action_remove()
    assert not mw.pipeline.is_element_active(slot_id2, filt_id)
コード例 #6
0
def test_manual_basic(qtbot):
    """Most simple test"""
    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add a dataslot
    path = datapath / "calibration_beads_47.rtdc"
    mw.add_dataslot(paths=[path])
    mw.add_dataslot(paths=[path])

    # sanity check (no emodulus should be available)
    for slot in mw.pipeline.slots:
        ds = slot.get_dataset()
        assert "emodulus" not in ds
        assert ds.config["setup"]["medium"] == "CellCarrierB"

    # create bulk action dialog manually
    dlg = bulk.BulkActionEmodulus(mw, pipeline=mw.pipeline)
    dlg.comboBox_temp.setCurrentIndex(dlg.comboBox_temp.findData("manual"))
    dlg.doubleSpinBox_temp.setValue(29.5)
    dlg.on_ok()

    for slot in mw.pipeline.slots:
        ds = slot.get_dataset()
        assert "emodulus" in ds
        assert ds.config["setup"]["medium"] == "CellCarrierB"
        assert ds.config["calculation"]["emodulus lut"] == "LE-2D-FEM-19"
        assert ds.config["calculation"]["emodulus medium"] == "CellCarrierB"
        assert ds.config["calculation"]["emodulus temperature"] == 29.5
        assert "emodulus viscosity" not in ds.config["calculation"]
コード例 #7
0
def test_remove_plots_issue_36(qtbot):
    """Correctly handle empty plots

    https://github.com/ZELLMECHANIK-DRESDEN/ShapeOut2/issues/36

    Traceback (most recent call last):
      File "/home/paul/repos/ShapeOut2/shapeout2/gui/main.py",
        line 193, in adopt_pipeline
        lay = pipeline_state["plots"][plot_index]["layout"]
    IndexError: list index out of range
    """
    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add a dataslots
    path = datapath / "calibration_beads_47.rtdc"
    mw.add_dataslot(paths=[path, path, path])

    assert len(mw.pipeline.slot_ids) == 3, "we added those"
    assert len(mw.pipeline.filter_ids) == 1, "automatically added"

    # now create a plot window
    plot_id = mw.add_plot()
    # and another one
    mw.add_plot()

    # remove a plot
    pw = mw.block_matrix.get_widget(filt_plot_id=plot_id)
    pw.action_remove()
コード例 #8
0
def test_empty_plot_with_one_plot_per_dataset_issue_41(qtbot):
    """
    Setting "one plot per dataset" for an empty plot resulted in
    zero-division error when determining col/row numbers
    """
    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add a dataslot
    path = datapath / "calibration_beads_47.rtdc"
    mw.add_dataslot(paths=[path])

    # add a plot
    plot_id = mw.add_plot()

    # activate analysis view
    pe = mw.block_matrix.get_widget(filt_plot_id=plot_id)
    qtbot.mouseClick(pe.toolButton_modify, QtCore.Qt.LeftButton)

    pv = mw.widget_ana_view.widget_plot

    # Change to "each" and apply
    idx = pv.comboBox_division.findData("each")
    pv.comboBox_division.setCurrentIndex(idx)
    # Lead to zero-division error in "get_plot_col_row_count"
    qtbot.mouseClick(pv.pushButton_apply, QtCore.Qt.LeftButton)
コード例 #9
0
def test_simple(qtbot):
    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add fake measurement
    path = make_dataset(medium="CellCarrier", temp=22.5, temp_range=[22, 23])

    with dclab.new_dataset(path) as ds:
        # Youngs modulus can readily be computed
        # https://dclab.readthedocs.io/en/latest/sec_av_emodulus.html
        ds.config["calculation"]["emodulus medium"] = \
            ds.config["setup"]["medium"]
        ds.config["calculation"]["emodulus lut"] = "LE-2D-FEM-19"
        emodA = np.array(ds["emodulus"], copy=True)
        ds.config["calculation"]["emodulus temperature"] = \
            ds.config["setup"]["temperature"]
        emodC = np.array(ds["emodulus"], copy=True)
        assert not np.allclose(
            emodA, emodC, atol=0, rtol=1e-12, equal_nan=True), "sanity check"

    mw.add_dataslot(paths=[path])
    wsl = mw.widget_ana_view.widget_slot

    # default values
    assert wsl.comboBox_medium.currentData() == "CellCarrier"
    assert wsl.comboBox_temp.currentData() == "feature"

    # scenario A (this is already set by default)
    ds1 = mw.pipeline.slots[0].get_dataset()
    assert np.allclose(ds1["emodulus"],
                       emodA,
                       atol=0,
                       rtol=1e-12,
                       equal_nan=True)

    # scenario C (switch to config)
    wsl.comboBox_temp.setCurrentIndex(wsl.comboBox_temp.findData("config"))
    qtbot.mouseClick(wsl.pushButton_apply, QtCore.Qt.LeftButton)
    ds2 = mw.pipeline.slots[0].get_dataset()
    assert np.allclose(ds2["emodulus"],
                       emodC,
                       atol=0,
                       rtol=1e-12,
                       equal_nan=True)

    # scenario C (switch to manual)
    wsl.comboBox_temp.setCurrentIndex(wsl.comboBox_temp.findData("manual"))
    wsl.doubleSpinBox_temp.setValue(22.5)
    qtbot.mouseClick(wsl.pushButton_apply, QtCore.Qt.LeftButton)
    ds3 = mw.pipeline.slots[0].get_dataset()
    assert np.allclose(ds3["emodulus"],
                       emodC,
                       atol=0,
                       rtol=1e-12,
                       equal_nan=True)

    try:
        path.unlink()
    except BaseException:
        pass
コード例 #10
0
def test_manual_wrong_medium(qtbot):
    """Deliberately set wrong medium"""
    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add a dataslot
    path = datapath / "calibration_beads_47.rtdc"
    mw.add_dataslot(paths=[path])
    mw.add_dataslot(paths=[path])

    # create bulk action dialog manually
    dlg = bulk.BulkActionEmodulus(mw, pipeline=mw.pipeline)
    dlg.comboBox_temp.setCurrentIndex(dlg.comboBox_temp.findData("manual"))
    dlg.doubleSpinBox_temp.setValue(29.5)
    # Set medium to "water". This should not change the emodulus medium.
    dlg.comboBox_medium.setCurrentIndex(dlg.comboBox_medium.findData("water"))

    dlg.on_ok()

    for slot in mw.pipeline.slots:
        ds = slot.get_dataset()
        assert "emodulus" in ds
        assert ds.config["setup"]["medium"] == "CellCarrierB"
        assert ds.config["calculation"]["emodulus lut"] == "LE-2D-FEM-19"
        assert ds.config["calculation"]["emodulus medium"] == "CellCarrierB"
        assert ds.config["calculation"]["emodulus temperature"] == 29.5
        assert "emodulus viscosity" not in ds.config["calculation"]
コード例 #11
0
def test_filter_min_max_inf(qtbot):
    path = make_fake_dataset()

    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add the file
    mw.add_dataslot(paths=[path])

    assert len(mw.pipeline.slot_ids) == 1, "we added that"
    assert len(mw.pipeline.filter_ids) == 1, "automatically added"

    # open the filter edit in the Analysis View
    fe = mw.block_matrix.get_widget(filt_plot_id=mw.pipeline.filter_ids[0])
    qtbot.mouseClick(fe.toolButton_modify, QtCore.Qt.LeftButton)

    # box filtering
    wf = mw.widget_ana_view.widget_filter
    # enable selection
    qtbot.mouseClick(wf.toolButton_moreless, QtCore.Qt.LeftButton)
    # find the porosity item and click the checkbox
    rc = wf._box_range_controls["area_ratio"]
    qtbot.mouseClick(rc.checkBox, QtCore.Qt.LeftButton)
    # disable selection
    qtbot.mouseClick(wf.toolButton_moreless, QtCore.Qt.LeftButton)

    # check that the range control does not have all-zero values
    rcstate = rc.__getstate__()
    assert rcstate["start"] != 0
    assert rcstate["end"] != 0
    # only approximate (b/c they were converted on the range scale)
    ds = dclab.new_dataset(path)
    assert np.allclose(rcstate["start"], ds["area_ratio"][2], rtol=1e-4)
    assert np.allclose(rcstate["end"], 1.1, rtol=1e-4)
コード例 #12
0
def test_no_events_disable(qtbot):
    """When all events are removed, a message should be displayed"""
    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # This session also contains a plot, so this is essentially
    # also a test for empty plots.
    spath = datapath / "version_2_1_6_no_events.so2"
    mw.on_action_open(spath)

    # Matrix widgets
    slot_id1 = mw.pipeline.slot_ids[0]
    slot_id2 = mw.pipeline.slot_ids[1]
    filt_id = mw.pipeline.filter_ids[0]
    em1 = mw.block_matrix.get_widget(slot_id1, filt_id)
    em2 = mw.block_matrix.get_widget(slot_id2, filt_id)

    # Now activate Quick View
    qtbot.mouseClick(em1, QtCore.Qt.LeftButton, QtCore.Qt.ShiftModifier)

    # Get Quick View instance
    qv = mw.widget_quick_view

    # This will display the "Hoppla!" message
    assert qv.label_noevents.isVisible()

    # Check the reverse
    qtbot.mouseClick(em2, QtCore.Qt.LeftButton, QtCore.Qt.ShiftModifier)
    assert not qv.label_noevents.isVisible()
コード例 #13
0
def test_filter_min_max_inf(qtbot):
    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add 3 dataslots
    path = datapath / "calibration_beads_47.rtdc"
    mw.add_dataslot(paths=[path, path, path])

    # change the slot names
    for ii, slot in enumerate(mw.pipeline.slots):
        slot.name = "slot numero {}".format(ii)
        mw.adopt_slot(slot.__getstate__())

    # sanity checks
    assert mw.pipeline.slots[0].name == "slot numero 0"
    assert mw.pipeline.slots[1].name == "slot numero 1"
    assert mw.pipeline.slots[2].name == "slot numero 2"

    # create reorder dialog manually
    dlg = DlgSlotReorder(mw.pipeline, mw)
    dlg.pipeline_changed.connect(mw.adopt_pipeline)
    # reorder plots
    dlg.listWidget.setCurrentRow(0)
    dlg.toolButton_down.clicked.emit()
    dlg.on_ok()

    # now check that reordering happened
    assert mw.pipeline.slots[0].name == "slot numero 1"
    assert mw.pipeline.slots[1].name == "slot numero 0"
    assert mw.pipeline.slots[2].name == "slot numero 2"
コード例 #14
0
def test_polygon_filter_basic(qtbot):
    path = data_path / "calibration_beads_47.rtdc"

    with dclab.new_dataset(path) as ds:
        pf1 = dclab.PolygonFilter(
            axes=("deform", "area_um"),
            points=[
                [ds["deform"].min(), ds["area_um"].min()],
                [ds["deform"].min(), ds["area_um"].mean()],
                [ds["deform"].mean(), ds["area_um"].mean()],
            ],
            name="Triangle of Death",
        )

    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add the file
    mw.add_dataslot(paths=[path])

    # enable the filter
    slot_id = mw.pipeline.slot_ids[0]
    filt_id = mw.pipeline.filter_ids[0]
    em = mw.block_matrix.get_widget(slot_id, filt_id)
    qtbot.mouseClick(em, QtCore.Qt.LeftButton)
    # did that work?
    assert mw.pipeline.is_element_active(slot_id, filt_id)

    assert len(mw.pipeline.slot_ids) == 1, "we added that"
    assert len(mw.pipeline.filter_ids) == 1, "automatically added"

    # open the filter edit in the Analysis View
    fe = mw.block_matrix.get_widget(filt_plot_id=mw.pipeline.filter_ids[0])
    qtbot.mouseClick(fe.toolButton_modify, QtCore.Qt.LeftButton)

    # enable the polygon filter
    wf = mw.widget_ana_view.widget_filter
    filter_ids = list(wf._polygon_checkboxes.keys())
    # sanity check
    assert filter_ids == [pf1.unique_id]

    wf._polygon_checkboxes[pf1.unique_id].setChecked(True)
    assert wf._polygon_checkboxes[pf1.unique_id].isChecked()

    # click apply
    qtbot.mouseClick(wf.pushButton_apply, QtCore.Qt.LeftButton)

    # check the filter
    assert pf1.unique_id in mw.pipeline.filters[0].polylist

    # get the dataset
    assert len(mw.pipeline.slots) == 1
    assert len(mw.pipeline.filters) == 1
    ds_slot = mw.pipeline.slots[0].get_dataset()
    ds = mw.pipeline.get_dataset(0)
    assert ds_slot is not ds
    assert np.sum(ds.filter.all) == 5
    assert len(ds) == 47
コード例 #15
0
def test_on_action_about(qtbot):
    with mock.patch("PyQt5.QtWidgets.QMessageBox.about") as mock_about:
        mw = ShapeOut2()
        mw.on_action_about()
        mw.close()

        assert mock_about.call_args.args[1] == \
               f"Shape-Out {shapeout2.__version__}"
        assert "Shape-Out 2" in mock_about.call_args.args[2]
コード例 #16
0
def test_handle_nan_valued_feature_color(qtbot):
    """User wants to color scatter data points with feature containing nans"""
    spath = datapath / "version_2_1_2_plot_color_emodulus.so2"

    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # lead to:
    # OverflowError: argument 4 overflowed: value must be in the range
    # -2147483648 to 2147483647
    mw.on_action_open(spath)
コード例 #17
0
def test_init_print_version(qtbot):
    mock_stdout = io.StringIO()
    mock_exit = mock.Mock()

    with mock.patch("sys.exit", mock_exit):
        with mock.patch('sys.stdout', mock_stdout):
            mw = ShapeOut2("--version")
            mw.close()

    assert mock_exit.call_args.args[0] == 0
    assert mock_stdout.getvalue().strip() == shapeout2.__version__
コード例 #18
0
def test_other_medium_viscosity_editable_issue_49(qtbot):
    mw = ShapeOut2()
    qtbot.addWidget(mw)
    # add fake measurement
    path1 = make_dataset(medium=None)
    mw.add_dataslot(paths=[path1])
    wsl = mw.widget_ana_view.widget_slot
    ds = mw.pipeline.slots[0].get_dataset()
    assert "medium" not in ds.config["setup"], "sanity check (medium removed)"
    oidx = wsl.comboBox_medium.findData("other")
    wsl.comboBox_medium.setCurrentIndex(oidx)
    assert not wsl.doubleSpinBox_visc.isReadOnly(), "Should be editable"
    assert wsl.doubleSpinBox_visc.isEnabled(), "Should be editable"
コード例 #19
0
def test_no_events_issue_37(qtbot):
    """https://github.com/ZELLMECHANIK-DRESDEN/ShapeOut2/issues/37

    "ValueError: zero-size array to reduction operation minimum
    which has no identity" when all events are filtered out.
    """
    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add a dataslot
    path = datapath / "calibration_beads_47.rtdc"
    mw.add_dataslot(paths=[path, path])

    assert len(mw.pipeline.slot_ids) == 2, "we added those"
    assert len(mw.pipeline.filter_ids) == 1, "automatically added"

    # activate a dataslot
    slot_id = mw.pipeline.slot_ids[0]
    filt_id = mw.pipeline.filter_ids[0]
    em = mw.block_matrix.get_widget(slot_id, filt_id)
    qtbot.mouseClick(em, QtCore.Qt.LeftButton)  # activate
    # did that work?
    assert mw.pipeline.is_element_active(slot_id, filt_id)

    # filter away all events
    fe = mw.block_matrix.get_widget(filt_plot_id=filt_id)
    qtbot.mouseClick(fe.toolButton_modify, QtCore.Qt.LeftButton)
    fv = mw.widget_ana_view.widget_filter
    qtbot.mouseClick(fv.toolButton_moreless, QtCore.Qt.LeftButton)
    rc = fv._box_range_controls["area_um"]
    qtbot.mouseClick(rc.checkBox, QtCore.Qt.LeftButton)
    # did that work?
    assert rc.checkBox.isChecked()
    qtbot.mouseClick(fv.toolButton_moreless, QtCore.Qt.LeftButton)
    # set range
    rc.doubleSpinBox_min.setValue(0)
    rc.doubleSpinBox_max.setValue(1)
    qtbot.mouseClick(fv.pushButton_apply, QtCore.Qt.LeftButton)
    # did that work?
    ds = mw.pipeline.get_dataset(slot_index=0, filt_index=0, apply_filter=True)
    assert np.sum(ds.filter.all) == 0

    # open QuickView
    slot_id = mw.pipeline.slot_ids[0]
    filt_id = mw.pipeline.filter_ids[0]
    em = mw.block_matrix.get_widget(slot_id, filt_id)

    # this raised the error
    qtbot.mouseClick(em, QtCore.Qt.LeftButton, QtCore.Qt.ShiftModifier)
    mw.close()
コード例 #20
0
def test_handle_empty_plots_issue_27(qtbot):
    """Correctly handle empty plots

    https://github.com/ZELLMECHANIK-DRESDEN/ShapeOut2/issues/27
    """
    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add a dataslot
    path = datapath / "calibration_beads_47.rtdc"
    mw.add_dataslot(paths=[path])
    # add another one
    mw.add_dataslot(paths=[path])

    assert len(mw.pipeline.slot_ids) == 2, "we added those"
    assert len(mw.pipeline.filter_ids) == 1, "automatically added"

    # activate a dataslot
    slot_id = mw.pipeline.slot_ids[0]
    filt_id = mw.pipeline.filter_ids[0]
    em = mw.block_matrix.get_widget(slot_id, filt_id)
    qtbot.mouseClick(em, QtCore.Qt.LeftButton)  # activate
    # did that work?
    assert mw.pipeline.is_element_active(slot_id, filt_id)

    # filter away all events
    fe = mw.block_matrix.get_widget(filt_plot_id=filt_id)
    qtbot.mouseClick(fe.toolButton_modify, QtCore.Qt.LeftButton)
    fv = mw.widget_ana_view.widget_filter
    qtbot.mouseClick(fv.toolButton_moreless, QtCore.Qt.LeftButton)
    rc = fv._box_range_controls["area_um"]
    qtbot.mouseClick(rc.checkBox, QtCore.Qt.LeftButton)
    # did that work?
    assert rc.checkBox.isChecked()
    qtbot.mouseClick(fv.toolButton_moreless, QtCore.Qt.LeftButton)
    # set range
    rc.doubleSpinBox_min.setValue(0)
    rc.doubleSpinBox_max.setValue(1)
    qtbot.mouseClick(fv.pushButton_apply, QtCore.Qt.LeftButton)
    # did that work?
    ds = mw.pipeline.get_dataset(slot_index=0, filt_index=0, apply_filter=True)
    assert np.sum(ds.filter.all) == 0

    # now create a plot window
    plot_id = mw.add_plot()
    pe = mw.block_matrix.get_widget(slot_id, plot_id)
    with pytest.warns(pipeline.core.EmptyDatasetWarning):
        # this now only throws a warning
        qtbot.mouseClick(pe, QtCore.Qt.LeftButton)  # activate (raises #27)
コード例 #21
0
def test_remove_dataset_h5py_error(qtbot):
    """Removing an activated dataset and activating Quick View fails

    Unhandled exception in Shape-Out version 2.0.1.post2:
    Traceback (most recent call last):
      File "/home/paul/repos/ShapeOut2/shapeout2/gui/main.py", line 235,
        in adopt_pipeline
        self.widget_quick_view.update_feature_choices()
      File "/home/paul/repos/ShapeOut2/shapeout2/gui/quick_view/qv_main.py",
        line 635, in update_feature_choices
        ds_feats = [f for f in self.rtdc_ds.features if f in feats_scalar]
    [...]
      File "/home/paul/repos/dclab/dclab/rtdc_dataset/fmt_hdf5.py", line 101,
        in _is_defective_feature
        if attr in self._h5.attrs:
    [...]
      File "h5py/_objects.pyx", line 55, in h5py._objects.with_phil.wrapper
      File "h5py/h5o.pyx", line 190, in h5py.h5o.open
    ValueError: Not a location (invalid object ID)
    """
    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add a dataslot
    path = datapath / "calibration_beads_47.rtdc"
    mw.add_dataslot(paths=[path, path])

    assert len(mw.pipeline.slot_ids) == 2, "we added those"
    assert len(mw.pipeline.filter_ids) == 1, "automatically added"

    # activate a dataslot
    slot_id = mw.pipeline.slot_ids[0]
    filt_id = mw.pipeline.filter_ids[0]
    em = mw.block_matrix.get_widget(slot_id, filt_id)
    qtbot.mouseClick(em, QtCore.Qt.LeftButton)  # activate
    qtbot.mouseClick(em, QtCore.Qt.LeftButton, QtCore.Qt.ShiftModifier)
    # did that work?
    assert mw.pipeline.is_element_active(slot_id, filt_id)

    # close Quick View
    qtbot.mouseClick(mw.toolButton_quick_view, QtCore.Qt.LeftButton)

    # now remove the dataset
    pw = mw.block_matrix.get_widget(slot_id=slot_id)
    pw.action_remove()

    # open Quick View
    qtbot.mouseClick(mw.toolButton_quick_view, QtCore.Qt.LeftButton)
    mw.close()
コード例 #22
0
def test_empty_medium_string_should_offer_user_edit(qtbot):
    mw = ShapeOut2()
    qtbot.addWidget(mw)
    # add fake measurement
    path1 = make_dataset(medium=" ")
    mw.add_dataslot(paths=[path1])
    wsl = mw.widget_ana_view.widget_slot
    ds = mw.pipeline.slots[0].get_dataset()
    assert ds.config["setup"]["medium"] == " "
    assert wsl.comboBox_medium.currentData() == "other"
    assert not wsl.doubleSpinBox_visc.isReadOnly(), "Should be editable"
    assert wsl.doubleSpinBox_visc.isEnabled(), "Should be editable"
    assert np.isnan(wsl.__getstate__()["emodulus"]["emodulus temperature"])
    assert wsl.__getstate__()["emodulus"]["emodulus medium"] == "other"
    assert wsl.__getstate__()["emodulus"]["emodulus scenario"] is None
コード例 #23
0
def test_box_filter_selection_no_preselection_issue_67(qtbot):
    """
    The user creates a filter and selects a few features for box
    filtering. Then the user creates a new filter and tries to add
    new box filters. There should not be any preselected filters.
    """
    path = make_fake_dataset()

    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add the file
    mw.add_dataslot(paths=[path])

    # edit the initial filter in the Analysis View
    fe = mw.block_matrix.get_widget(filt_plot_id=mw.pipeline.filter_ids[0])
    qtbot.mouseClick(fe.toolButton_modify, QtCore.Qt.LeftButton)

    # box filtering
    wf = mw.widget_ana_view.widget_filter
    # enable selection
    qtbot.mouseClick(wf.toolButton_moreless, QtCore.Qt.LeftButton)
    # find the porosity item and click the checkbox
    rc = wf._box_range_controls["area_ratio"]
    qtbot.mouseClick(rc.checkBox, QtCore.Qt.LeftButton)
    # disable selection
    qtbot.mouseClick(wf.toolButton_moreless, QtCore.Qt.LeftButton)

    # now add second filter
    mw.add_filter()

    # edit the second filter in the Analysis View
    fe = mw.block_matrix.get_widget(filt_plot_id=mw.pipeline.filter_ids[1])
    qtbot.mouseClick(fe.toolButton_modify, QtCore.Qt.LeftButton)

    # make sure that "area_ratio" is not preselected
    wf = mw.widget_ana_view.widget_filter
    # enable selection
    qtbot.mouseClick(wf.toolButton_moreless, QtCore.Qt.LeftButton)
    # find the porosity item and click the checkbox
    rc = wf._box_range_controls["area_ratio"]
    assert not rc.checkBox.isChecked()
    # and a sanity check
    rc2 = wf._box_range_controls["deform"]
    assert not rc2.checkBox.isChecked()

    # cleanup: disable selection
    qtbot.mouseClick(wf.toolButton_moreless, QtCore.Qt.LeftButton)
コード例 #24
0
def test_lme4_with_dcor_session_differential(qtbot):
    """
    Perform differential deformation test
    """
    mw = ShapeOut2()
    qtbot.addWidget(mw)
    mw.on_action_open(data_path / "version_2_5_0_dcor_lme4_diff.so2")

    # create dialog manually
    dlg = ComputeSignificance(mw, pipeline=mw.pipeline)

    # set the variables
    # treatment rep 1
    dlg.datasets[0].comboBox_group.setCurrentIndex(1)
    # treatment rep 2
    dlg.datasets[1].comboBox_group.setCurrentIndex(1)
    dlg.datasets[1].spinBox_repeat.setValue(2)
    # res treatment rep 1
    dlg.datasets[2].comboBox_group.setCurrentIndex(1)
    # res treatment rep 2
    dlg.datasets[3].comboBox_group.setCurrentIndex(1)
    dlg.datasets[3].spinBox_repeat.setValue(2)
    # control rep 1
    pass
    # control rep 2
    dlg.datasets[5].spinBox_repeat.setValue(2)
    # control rep 3
    dlg.datasets[6].spinBox_repeat.setValue(3)
    # res control rep 1
    pass
    # res control rep 2
    dlg.datasets[8].spinBox_repeat.setValue(2)
    # res control rep 3
    dlg.datasets[9].spinBox_repeat.setValue(3)

    # set the feature
    feat_id = dlg.comboBox_feat.findData("deform")
    dlg.comboBox_feat.setCurrentIndex(feat_id)

    dlgr = dlg.on_lme4(ret_dlg=True)

    assert dlgr.label_model.text() == "lmer"
    assert dlgr.label_feature.text() == "Deformation"
    assert dlgr.label_differential.text() == "Yes"
    assert dlgr.lineEdit_pvalue.text() == "0.0000035055"
    assert dlgr.lineEdit_intercept.text() == "0.020509"
    assert dlgr.lineEdit_treatment.text() == "-0.0052991"
コード例 #25
0
def test_switch_and_update_chip_region(qtbot):
    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add fake measurement
    path1 = make_dataset(medium="CellCarrier",
                         temp=22.5,
                         temp_range=[22, 23],
                         chip_region="channel")
    path2 = make_dataset(medium="CellCarrier",
                         temp=22.5,
                         temp_range=[22, 23],
                         chip_region="reservoir")

    slot_id1, slot_id2 = mw.add_dataslot(paths=[path1, path2])
    wsl = mw.widget_ana_view.widget_slot

    # select the first slot
    em1 = mw.block_matrix.get_widget(slot_id=slot_id1)
    em2 = mw.block_matrix.get_widget(slot_id=slot_id2)
    qtbot.mouseClick(em1.toolButton_modify, QtCore.Qt.LeftButton)
    # set temperature manually
    idm = wsl.comboBox_temp.findData("manual")
    wsl.comboBox_temp.setCurrentIndex(idm)
    assert wsl.comboBox_temp.currentData() == "manual"
    wsl.doubleSpinBox_temp.setValue(20.0)
    assert wsl.doubleSpinBox_temp.value() == 20
    qtbot.mouseClick(wsl.pushButton_apply, QtCore.Qt.LeftButton)
    QtWidgets.QApplication.processEvents(QtCore.QEventLoop.AllEvents, 300)
    # check whether that worked
    assert wsl.get_dataset(
    ).config["calculation"]["emodulus temperature"] == 20

    # switch to the second (reservoir) measurement
    qtbot.mouseClick(em2.toolButton_modify, QtCore.Qt.LeftButton)
    assert not wsl.groupBox_emod.isVisible()
    # now switch back
    qtbot.mouseClick(em1.toolButton_modify, QtCore.Qt.LeftButton)

    # This is the actual test
    assert wsl.doubleSpinBox_temp.value() == 20

    try:
        path1.unlink()
        path2.unlink()
    except BaseException:
        pass
コード例 #26
0
def test_user_defined_medium_should_work(qtbot):
    mw = ShapeOut2()
    qtbot.addWidget(mw)
    # add fake measurement
    path1 = make_dataset(medium="MyMedium")
    mw.add_dataslot(paths=[path1])
    wsl = mw.widget_ana_view.widget_slot
    ds = mw.pipeline.slots[0].get_dataset()
    assert ds.config["setup"]["medium"] == "MyMedium", "sanity check"
    assert wsl.comboBox_medium.currentData() == "MyMedium"
    assert not wsl.doubleSpinBox_visc.isReadOnly(), "Should be editable"
    assert wsl.doubleSpinBox_visc.isEnabled(), "Should be editable"
    wsl.doubleSpinBox_visc.setValue(12.1)
    assert wsl.__getstate__()["emodulus"]["emodulus viscosity"] == 12.1
    assert np.isnan(wsl.__getstate__()["emodulus"]["emodulus temperature"])
    assert wsl.__getstate__()["emodulus"]["emodulus medium"] == "MyMedium"
    assert wsl.__getstate__()["emodulus"]["emodulus scenario"] is None
コード例 #27
0
def test_export_datasets_rtdc_emodulus_only_in_one_issue_80(qtbot):
    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add 3 dataslots
    path = data_path / "calibration_beads_47.rtdc"
    mw.add_dataslot(paths=[path, path, path])

    # set metadata for Young's modulus only in one slot
    wsl = mw.widget_ana_view.widget_slot
    wsl.doubleSpinBox_temp.setValue(23)
    qtbot.mouseClick(wsl.pushButton_apply, QtCore.Qt.LeftButton)
    # make sure that worked
    ds0 = mw.pipeline.slots[0].get_dataset()
    assert "emodulus" in ds0

    # perform the export
    tmpd = tempfile.mkdtemp(prefix="shapeout2_test_data_export_")
    with mock.patch.object(QtWidgets.QFileDialog,
                           "getExistingDirectory",
                           return_value=tmpd):
        with mock.patch.object(QtWidgets.QMessageBox, "warning") as mwarn:
            # create export dialog manually (asks user for directory)
            dlg = export.ExportData(mw, pipeline=mw.pipeline)

            # Everything is set-up already
            # (.rtdc export, all features selected).
            # Click OK.
            buttons = dlg.buttonBox.buttons()
            qtbot.mouseClick(buttons[0], QtCore.Qt.LeftButton)

            # make sure that we got two warning messages
            assert mwarn.call_count == 2

    # make sure we have three .rtdc files
    exported = sorted(list(pathlib.Path(tmpd).glob("*.rtdc")))
    assert len(exported) == 3
    # the first exported file should have Young's modulus
    with dclab.new_dataset(exported[0]) as ds:
        assert "emodulus" in ds
    with dclab.new_dataset(exported[1]) as ds:
        assert "emodulus" not in ds
    with dclab.new_dataset(exported[2]) as ds:
        assert "emodulus" not in ds
コード例 #28
0
def test_feature_bright_avg_not_present_issue_62(qtbot):
    """Plot a dataset that does not contain the "bright_avg" feature

    ...or any means of computing it (i.e. via "image")
    """
    # create fake dataset without bright_avg
    tmp = tempfile.mktemp(".rtdc", prefix="example_hue_")
    with dclab.new_dataset(datapath / "calibration_beads_47.rtdc") as ds:
        ds.export.hdf5(tmp, features=["area_um", "pos_x", "pos_y", "deform"])

    mw = ShapeOut2()
    qtbot.addWidget(mw)
    # add dataset
    slot_id = mw.add_dataslot([tmp])[0]
    # add plot
    plot_id = mw.add_plot()
    # and activate it
    pw = mw.block_matrix.get_widget(filt_plot_id=plot_id, slot_id=slot_id)
    # this raised "ValueError: 'bright_avg' is not in list" (issue #62)
    qtbot.mouseClick(pw, QtCore.Qt.LeftButton)
コード例 #29
0
def test_temperature_feature(qtbot):
    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add custom dataslot
    path = make_dataset(medium="CellCarrier", temp=22.5, temp_range=[22, 23])
    mw.add_dataslot(paths=[path])
    mw.add_dataslot(paths=[path])

    # create bulk action dialog manually
    dlg = bulk.BulkActionEmodulus(mw, pipeline=mw.pipeline)
    dlg.comboBox_temp.setCurrentIndex(dlg.comboBox_temp.findData("feature"))
    dlg.on_ok()

    for slot in mw.pipeline.slots:
        ds = slot.get_dataset()
        assert "emodulus" in ds
        assert ds.config["setup"]["medium"] == "CellCarrier"
        assert ds.config["calculation"]["emodulus lut"] == "LE-2D-FEM-19"
        assert ds.config["calculation"]["emodulus medium"] == "CellCarrier"
        assert "emodulus temperature" not in ds.config["calculation"]
        assert "emodulus viscosity" not in ds.config["calculation"]
コード例 #30
0
def test_clear_session_issue_25(qtbot):
    """https://github.com/ZELLMECHANIK-DRESDEN/ShapeOut2/issues/25"""
    mw = ShapeOut2()
    qtbot.addWidget(mw)

    # add a dataslot
    path = datapath / "calibration_beads_47.rtdc"
    mw.add_dataslot(paths=[path])

    assert len(mw.pipeline.slot_ids) == 1, "we added that"
    assert len(mw.pipeline.filter_ids) == 1, "automatically added"

    # activate a dataslot
    slot_id = mw.pipeline.slot_ids[0]
    filt_id = mw.pipeline.filter_ids[0]
    em = mw.block_matrix.get_widget(slot_id, filt_id)
    qtbot.mouseClick(em, QtCore.Qt.LeftButton, QtCore.Qt.ShiftModifier)
    # did that work?
    assert mw.toolButton_quick_view.isChecked()

    # now clear the session (this raised the errror in #25)
    mw.on_action_clear(assume_yes=True)