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)
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"
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"]
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
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)
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"]
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()
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)
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
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"]
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)
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()
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"
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
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]
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)
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__
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"
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()
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)
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()
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
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)
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"
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
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
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
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)
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"]
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)