Ejemplo n.º 1
0
    def __init__(self):

        resource_manager = ResourceManager('@py')

        try:
            self.inst = resource_manager.open_resource(
                resource_manager.list_resources()[0])
        except:
            print("Could not find")
            self.test = True
            return

        if "ok" in self.inst.query("$BD:0,CMD:MON,PAR:BDNAME").lower():
            print("Successfully connected to CAEN psu")
        else:
            sys.exit(ERROR_BOARD_NOT_FOUND)
Ejemplo n.º 2
0
def find_visa():
    # Return the first VISA address which maps to a Rigol DS1000Z.

    RIGOL_IDN_REGEX = "^RIGOL TECHNOLOGIES,DS1[01][057]4Z(-S)?( Plus)?,.+$"

    visa_manager = ResourceManager()

    for visa_name in visa_manager.list_resources():
        try:
            visa_resource = visa_manager.open_resource(visa_name)
            match = search(RIGOL_IDN_REGEX, visa_resource.query("*IDN?"))
            if match:
                return visa_name
        except VisaIOError:
            pass
        finally:
            visa_resource.close()
Ejemplo n.º 3
0
class TestFilter2(BaseTestCase):
    def setUp(self):
        """Create a ResourceManager with the default backend library.

        """
        self.rm = ResourceManager()

    def tearDown(self):
        """Close the ResourceManager.

        """
        self.rm.close()

    def _test_filter2(self, expr, *correct):

        resources = self.rm.list_resources(expr.split("{")[0])
        ok = tuple(resources[n] for n in correct)
        filtered = rname.filter2(
            resources, expr, lambda rsc: self.rm.open_resource(rsc)
        )
        self.assertSequenceEqual(filtered, ok)

    def test_filter2_optional_clause_with_connection(self):
        self._test_filter2(
            "?*::INSTR{VI_ATTR_TERMCHAR_EN == 1 && VI_ATTR_TERMCHAR == 0}"
        )
        # Linefeed \n is 10
        self._test_filter2("TCPIP::?*::INSTR{VI_ATTR_TERMCHAR == 10}")

        # test handling error in the evaluation of the attribute
        def broken_get_visa_attribute(self, name):
            raise Exception()

        old = Resource.get_visa_attribute
        Resource.get_visa_attribute = broken_get_visa_attribute

        # Using any other log level will cause the test to fail for no apparent
        # good reason
        with self.assertLogs(level=logging.DEBUG, logger=logger):
            try:
                self._test_filter2("TCPIP::?*::INSTR{VI_ATTR_TERMCHAR == 10}")
            finally:
                Resource.get_visa_attribute = old
Ejemplo n.º 4
0
class TestFilter2(BaseTestCase):
    def setup_method(self):
        """Create a ResourceManager with the default backend library."""
        self.rm = ResourceManager()

    def teardown_method(self):
        """Close the ResourceManager."""
        self.rm.close()

    def _test_filter2(self, expr, *correct):

        resources = self.rm.list_resources(expr.split("{")[0])
        ok = tuple(resources[n] for n in correct)
        filtered = rname.filter2(resources, expr,
                                 lambda rsc: self.rm.open_resource(rsc))
        assert filtered == ok

    def test_filter2_optional_clause_with_connection(self, caplog,
                                                     monkeypatch):
        self._test_filter2(
            "?*::INSTR{VI_ATTR_TERMCHAR_EN == 1 && VI_ATTR_TERMCHAR == 0}")
        # Linefeed \n is 10
        self._test_filter2("TCPIP::?*::INSTR{VI_ATTR_TERMCHAR == 10}")

        # test handling error in the evaluation of the attribute
        def broken_get_visa_attribute(self, name):
            raise Exception()

        monkeypatch.setattr(Resource, "get_visa_attribute",
                            broken_get_visa_attribute)

        # Using any other log level will cause the test to fail for no apparent
        # good reason
        caplog.clear()
        with caplog.at_level(logging.DEBUG, logger="pyvisa"):
            self._test_filter2("TCPIP::?*::INSTR{VI_ATTR_TERMCHAR == 10}")

        assert caplog.records
Ejemplo n.º 5
0
class TestResourceManager(unittest.TestCase):
    """Test the pyvisa ResourceManager.

    """
    def setUp(self):
        """Create a ResourceManager with the default backend library.

        """
        self.rm = ResourceManager()

    def tearDown(self):
        """Close the ResourceManager.

        """
        self.rm.close()
        del rm
        gc.collect()

    def test_lifecycle(self):
        """Test creation and closing of the resource manager.

        """
        self.assertIsNotNone(self.rm.session)
        self.assertIsNotNone(self.rm.visalib)
        self.assertIs(self.rm, self.rm.visalib.resource_manager)
        self.assertFalse(self.rm.list_opened_resources())

        self.assertIs(self.rm.visalib,
                      ResourceManager(self.rm.visalib).visalib)

        self.rm.close()

        with self.assertRaises(InvalidSession):
            self.rm.session
        self.assertIsNone(self.rm.visalib.resource_manager)

    def test_cleanup_on_del(self):
        """Test that deleting the rm does clean the VISA session

        """
        # The test seems to assert what it should even though the coverage report
        # seems wrong
        rm = highlevel.ResourceManager()
        with self.assertLogs(level=logging.DEBUG) as log:
            del rm
            gc.collect()

        self.assertIn('Closing ResourceManager', log.output)

    def test_resource_manager_unicity(self):
        """Test the resource manager is unique per backend as expected.

        """
        new_rm = ResourceManager()
        self.assertIs(self.rm, new_rm)
        self.assertEqual(self.rm.session, new_rm.session)

    def test_str(self):
        """Test computing the string representation of the resource manager

        """
        self.assertRegex(str(self.rm), r"Resource Manager of .*")
        self.rm.close()
        self.assertRegex(str(self.rm), r"Resource Manager of .*")

    def test_repr(self):
        """Test computing the repr of the resource manager

        """
        self.assertRegex(repr(self.rm), r"<ResourceManager\(<.*>\)>")
        self.rm.close()
        self.assertRegex(repr(self.rm), r"<ResourceManager\(<.*>\)>")

    def test_last_status(self):
        """Test accessing the status of the last operation.

        """
        self.assertEqual(self.rm.last_status, StatusCode.success)

        # Access the generic last status through the visalib
        self.assertEqual(self.rm.last_status, self.rm.visalib.last_status)

        # Test accessing the status for an invalid session
        with self.assertRaises(errors.Error) as cm:
            self.rm.visalib.get_last_status_in_session("_nonexisting_")
        self.assertIn("The session", cm.exception.args[0])

    def test_list_resource(self):
        """Test listing the available resources.

        """
        # Default settings
        self.assertSequenceEqual(
            sorted(self.rm.list_resources()),
            sorted([
                str(ResourceName.from_string(v))
                for v in RESOURCE_ADDRESSES.values() if v.endswith("INSTR")
            ]))

        # All resources
        self.assertSequenceEqual(
            sorted(self.rm.list_resources("?*")),
            sorted([
                str(ResourceName.from_string(v))
                for v in RESOURCE_ADDRESSES.values()
            ]))

    def test_accessing_resource_infos(self):
        """Test accessing resource infos.

        """
        rname = list(RESOURCE_ADDRESSES.values())[0]
        rinfo_ext = self.rm.resource_info(rname)
        rinfo = self.rm.resource_info(rname, extended=False)

        rname = ResourceName().from_string(rname)
        self.assertEqual(rinfo_ext.interface_type,
                         getattr(InterfaceType, rname.interface_type.lower()))
        self.assertEqual(rinfo_ext.interface_board_number, int(rname.board))
        self.assertEqual(rinfo_ext.resource_class, rname.resource_class)
        self.assertEqual(rinfo_ext.resource_name, str(rname))

        self.assertEqual(rinfo.interface_type,
                         getattr(InterfaceType, rname.interface_type.lower()))
        self.assertEqual(rinfo.interface_board_number, int(rname.board))

    def test_listing_resource_infos(self):
        """Test listing resource infos.

        """
        infos = self.rm.list_resources_info()

        for rname, rinfo_ext in infos.items():
            rname = ResourceName().from_string(rname)
            self.assertEqual(
                rinfo_ext.interface_type,
                getattr(InterfaceType, rname.interface_type.lower()))
            self.assertEqual(rinfo_ext.interface_board_number,
                             int(rname.board))
            self.assertEqual(rinfo_ext.resource_class, rname.resource_class)
            self.assertEqual(rinfo_ext.resource_name, str(rname))

    def test_opening_resource(self):
        """Test opening and closing resources.

        """
        rname = list(RESOURCE_ADDRESSES.values())[0]
        rsc = self.rm.open_resource(rname, timeout=1234)

        # Check the resource is listed as opened and the attributes are right.
        self.assertIn(rsc, self.rm.list_opened_resources())
        self.assertEqual(rsc.timeout, 1234)

        # Close the rm to check that we close all resources.
        self.rm.close()

        self.assertFalse(self.rm.list_opened_resources())
        with self.assertRaises(InvalidSession):
            rsc.session

    def test_opening_resource_bad_open_timeout(self):
        """Test opening a resource with a non integer open_timeout.

        """
        rname = list(RESOURCE_ADDRESSES.values())[0]

        with self.assertRaises(ValueError) as cm:
            rsc = self.rm.open_resource(rname, open_timeout="")

        self.assertIn("integer (or compatible type)", str(cm.exception))

    def test_opening_resource_with_lock(self):
        """Test opening a locked resource

        """
        rname = list(RESOURCE_ADDRESSES.values())[0]
        rsc = self.rm.open_resource(rname,
                                    access_mode=AccessModes.exclusive_lock)
        self.assertEqual(len(self.rm.list_opened_resources()), 1)

        # Timeout when accessing a locked resource
        with self.assertRaises(VisaIOError):
            self.rm.open_resource(rname,
                                  access_mode=AccessModes.exclusive_lock)
        self.assertEqual(len(self.rm.list_opened_resources()), 1)

        # Success to access an unlocked resource.
        rsc.unlock()
        rsc2 = self.rm.open_resource(rname,
                                     access_mode=AccessModes.exclusive_lock)
        self.assertEqual(len(self.rm.list_opened_resources()), 2)

    def test_opening_resource_specific_class(self):
        """Test opening a resource requesting a specific class.

        """
        rname = list(RESOURCE_ADDRESSES.values())[0]
        with self.assertRaises(TypeError):
            rsc = self.rm.open_resource(rname, resource_pyclass=object)

        self.assertEqual(len(self.rm.list_opened_resources()), 0)

    def test_open_resource_unknown_resource_type(self):
        """Test opening a resource for which no registered class exist.

        """
        rc = highlevel.ResourceManager._resource_classes
        old = rc.copy()

        class FakeResource:
            def __init__(self, *args):
                raise RuntimeError()

        rc[(constants.InterfaceType.unknown, "")] = FakeResource

        rm = highlevel.ResourceManager()
        try:
            with self.assertLogs(level=logging.WARNING):
                highlevel.ResourceManager.open_resource(
                    "TCPIP::192.168.0.1::INSTR")
            self.assertIs(
                highlevel.ResourceManager._resource_classes[(
                    constants.InterfaceType.tcpip, "INSTR")], object)
        finally:
            highlevel.ResourceManager._resource_classes = old

    def test_opening_resource_unknown_attribute(self):
        """Test opening a resource and attempting to set an unknown attr.

        """
        rname = list(RESOURCE_ADDRESSES.values())[0]
        with self.assertRaises(ValueError):
            rsc = self.rm.open_resource(rname, unknown_attribute=None)

        self.assertEqual(len(self.rm.list_opened_resources()), 0)

    def test_get_instrument(self):
        """Check that we get the expected deprecation warning.

        """
        rname = list(RESOURCE_ADDRESSES.values())[0]
        with self.assertWarns(FutureWarning):
            rsc = self.rm.get_instrument(rname)
Ejemplo n.º 6
0
import pyvisa
from pyvisa import ResourceManager
m = ResourceManager()
resources_list = m.list_resources()
print(resources_list)
inst = m.open_resource(resources_list[1])

print("eae")
a = inst.write_raw(b"*IDN?")
f = inst.read_raw()
print(a)
inst.close()
Ejemplo n.º 7
0
class TestResourceManager:
    """Test the pyvisa ResourceManager."""
    def setup_method(self):
        """Create a ResourceManager with the default backend library."""
        self.rm = ResourceManager()

    def teardown_method(self):
        """Close the ResourceManager."""
        if self.rm is not None:
            self.rm.close()
            del self.rm
            gc.collect()

    def test_lifecycle(self, caplog):
        """Test creation and closing of the resource manager."""
        assert self.rm.session is not None
        assert self.rm.visalib is not None
        assert self.rm is self.rm.visalib.resource_manager
        assert not self.rm.list_opened_resources()

        assert self.rm.visalib is ResourceManager(self.rm.visalib).visalib

        with caplog.at_level(level=logging.DEBUG, logger="pyvisa"):
            self.rm.close()

        assert caplog.records

        with pytest.raises(InvalidSession):
            self.rm.session
        assert self.rm.visalib.resource_manager is None

    def test_cleanup_on_del(self, caplog):
        """Test that deleting the rm does clean the VISA session"""
        # The test seems to assert what it should even though the coverage report
        # seems wrong
        rm = self.rm
        self.rm = None
        with caplog.at_level(logging.DEBUG, logger="pyvisa"):
            del rm
            gc.collect()

        assert "Closing ResourceManager" in caplog.records[0].message

    def test_resource_manager_unicity(self):
        """Test the resource manager is unique per backend as expected."""
        new_rm = ResourceManager()
        assert self.rm is new_rm
        assert self.rm.session == new_rm.session

    def test_str(self):
        """Test computing the string representation of the resource manager"""
        assert re.match(r"Resource Manager of .*", str(self.rm))
        self.rm.close()
        assert re.match(r"Resource Manager of .*", str(self.rm))

    def test_repr(self):
        """Test computing the repr of the resource manager"""
        assert re.match(r"<ResourceManager\(<.*>\)>", repr(self.rm))
        self.rm.close()
        assert re.match(r"<ResourceManager\(<.*>\)>", repr(self.rm))

    def test_last_status(self):
        """Test accessing the status of the last operation."""
        assert self.rm.last_status == StatusCode.success

        # Access the generic last status through the visalib
        assert self.rm.last_status == self.rm.visalib.last_status

        # Test accessing the status for an invalid session
        with pytest.raises(errors.Error) as cm:
            self.rm.visalib.get_last_status_in_session("_nonexisting_")
        assert "The session" in cm.exconly()

    def test_list_resource(self):
        """Test listing the available resources."""
        # Default settings
        resources = self.rm.list_resources()
        for v in (v for v in RESOURCE_ADDRESSES.values()
                  if v.endswith("INSTR")):
            assert str(ResourceName.from_string(v)) in resources

        # All resources
        resources = self.rm.list_resources("?*")
        for v in RESOURCE_ADDRESSES.values():
            assert str(ResourceName.from_string(v)) in resources

    def test_accessing_resource_infos(self):
        """Test accessing resource infos."""
        rname = list(RESOURCE_ADDRESSES.values())[0]
        rinfo_ext = self.rm.resource_info(rname)
        rinfo = self.rm.resource_info(rname, extended=False)

        rname = ResourceName().from_string(rname)
        assert rinfo_ext.interface_type == getattr(
            InterfaceType, rname.interface_type.lower())
        assert rinfo_ext.interface_board_number == int(rname.board)
        assert rinfo_ext.resource_class == rname.resource_class
        assert rinfo_ext.resource_name == str(rname)

        assert rinfo.interface_type == getattr(InterfaceType,
                                               rname.interface_type.lower())
        assert rinfo.interface_board_number == int(rname.board)

    def test_listing_resource_infos(self):
        """Test listing resource infos."""
        infos = self.rm.list_resources_info()

        for rname, rinfo_ext in infos.items():
            rname = ResourceName().from_string(rname)
            assert rinfo_ext.interface_type == getattr(
                InterfaceType, rname.interface_type.lower())
            assert rinfo_ext.interface_board_number == int(rname.board)
            assert rinfo_ext.resource_class == rname.resource_class
            assert rinfo_ext.resource_name == str(rname)

    def test_opening_resource(self):
        """Test opening and closing resources."""
        rname = list(RESOURCE_ADDRESSES.values())[0]
        rsc = self.rm.open_resource(rname, timeout=1234)

        # Check the resource is listed as opened and the attributes are right.
        assert rsc in self.rm.list_opened_resources()
        assert rsc.timeout == 1234

        # Close the rm to check that we close all resources.
        self.rm.close()

        assert not self.rm.list_opened_resources()
        with pytest.raises(InvalidSession):
            rsc.session

    def test_opening_resource_bad_open_timeout(self):
        """Test opening a resource with a non integer open_timeout."""
        rname = list(RESOURCE_ADDRESSES.values())[0]

        with pytest.raises(ValueError) as cm:
            self.rm.open_resource(rname, open_timeout="")

        assert "integer (or compatible type)" in str(cm.exconly())

    def test_opening_resource_with_lock(self):
        """Test opening a locked resource"""
        rname = list(RESOURCE_ADDRESSES.values())[0]
        rsc = self.rm.open_resource(rname,
                                    access_mode=AccessModes.exclusive_lock)
        assert len(self.rm.list_opened_resources()) == 1

        # Timeout when accessing a locked resource
        with pytest.raises(VisaIOError):
            self.rm.open_resource(rname,
                                  access_mode=AccessModes.exclusive_lock)
        assert len(self.rm.list_opened_resources()) == 1

        # Success to access an unlocked resource.
        rsc.unlock()
        with self.rm.open_resource(
                rname, access_mode=AccessModes.exclusive_lock) as rsc2:
            assert rsc.session != rsc2.session
            assert len(self.rm.list_opened_resources()) == 2

    def test_opening_resource_specific_class(self):
        """Test opening a resource requesting a specific class."""
        rname = list(RESOURCE_ADDRESSES.values())[0]
        with pytest.raises(TypeError):
            self.rm.open_resource(rname, resource_pyclass=object)

        assert len(self.rm.list_opened_resources()) == 0

    def test_open_resource_unknown_resource_type(self, caplog):
        """Test opening a resource for which no registered class exist."""
        rc = ResourceManager._resource_classes
        old = rc.copy()

        class FakeResource:
            def __init__(self, *args):
                raise RuntimeError()

        rc[(InterfaceType.unknown, "")] = FakeResource
        del rc[(InterfaceType.tcpip, "INSTR")]

        rm = ResourceManager()
        try:
            caplog.clear()
            with caplog.at_level(level=logging.DEBUG, logger="pyvisa"):
                with pytest.raises(RuntimeError):
                    rm.open_resource("TCPIP::192.168.0.1::INSTR")
            assert caplog.records
        finally:
            ResourceManager._resource_classes = old

    def test_opening_resource_unknown_attribute(self):
        """Test opening a resource and attempting to set an unknown attr."""
        rname = list(RESOURCE_ADDRESSES.values())[0]
        with pytest.raises(ValueError):
            self.rm.open_resource(rname, unknown_attribute=None)

        assert len(self.rm.list_opened_resources()) == 0

    def test_get_instrument(self):
        """Check that we get the expected deprecation warning."""
        rname = list(RESOURCE_ADDRESSES.values())[0]
        with pytest.warns(FutureWarning):
            self.rm.get_instrument(rname)
Ejemplo n.º 8
0
class InputParameter(object):
    def __init__(self):
        self.measurement_strategy = None
        self.len_total = None
        self.len_step = None
        self.num_of_mea = None
        self.time_step = None
        self.frequency = None
        self.temperature = None
        self.humidity = None
        self.access_sensor_times = None
        self.directory = None
        self.sensor_comp = None
        self.motor_comp = None
        self.network_analysis_resource = None
        self.auto_find_comp = True
        self.sensor_ser = None
        self.motor_ser = None
        self.visa_rm = ResourceManager()
        self.motor = None
        self.sensor = None
        self.NA = None
        self.NA_identifier = None
        self.na_state = None
        self.na_average_factor = None
        self.multi_measure = None

    def check_data(self):
        """check input parameters, and open serials, remember to close ser!!!"""

        if self.directory is None:
            raise InputError('请选择数据保存位置')
        try:
            self.measurement_strategy = int(self.measurement_strategy)
        except Exception:
            raise InputError('须指定测量方案')
        if self.measurement_strategy == 0:
            try:
                self.len_total = float(self.len_total)
            except Exception:
                raise InputError('缺少腔体长度')
            try:
                self.len_step = float(self.len_step)
            except Exception:
                raise InputError('缺少运动步长')
            if self.len_step * self.len_total <= 0:
                raise InputError('总长度和步长符号须一致,负号表示反向')
        elif self.measurement_strategy == 1:
            try:
                self.num_of_mea = float(self.num_of_mea)
            except Exception:
                raise InputError('请指定一周测量次数')
        try:
            self.time_step = float(self.time_step)
        except Exception:
            raise InputError('缺少等待时间')
        if self.time_step < 1:
            raise InputError('至少等1s')
        try:
            self.multi_measure = int(self.multi_measure)
        except Exception:
            raise InputError('指定测量次数')
        try:
            self.frequency = float(self.frequency)
        except Exception:
            raise InputError('缺少真空频率')
        if self.access_sensor_times is None:
            self.access_sensor_times = 0
        try:
            self.access_sensor_times = int(self.access_sensor_times)
        except Exception:
            raise InputError('设置温湿度')
        if self.access_sensor_times == 0:
            try:
                self.temperature = float(self.temperature)
            except Exception:
                raise InputError('缺少温度数据')
            try:
                self.humidity = float(self.humidity)
            except Exception:
                raise InputError('缺少湿度数据')
        else:
            if self.access_sensor_times == 2 and self.time_step < 2.5:
                raise InputError('使用传感器,需要更多等待时间')
            if self.sensor_comp is None:
                try:
                    port_list = list(list_ports.comports())
                    self.sensor_comp = port_list[1][0]
                except IndexError:
                    raise InputError('检查串口连接情况')
            try:
                self.sensor_ser = Serial(self.sensor_comp, 9600, timeout=2)
                self.sensor = Sensor(self.sensor_ser)
                [self.temperature, self.humidity] = self.sensor.current_t_rh
            except Exception as e:
                raise InputError(f'串口错误:\n{e}')
        # Step Motor
        if self.motor_comp is None:
            try:
                self.motor_comp = list(list_ports.comports())[0][0]
            except Exception as e:
                raise InputError('检查串口连接情况\n' + str(e))
        try:
            self.motor_ser = Serial(self.motor_comp, 9600, timeout=0.2)
            self.motor = StepMotor(self.motor_ser)
        except Exception as e:
            raise InputError('检查串口连接情况\n' + str(e))
        # Network Analyzer
        try:
            self.na_average_factor = int(self.na_average_factor)
        except ValueError or TypeError:
            raise InputError('网分平均因子出错')
        if self.NA_identifier is None:
            try:
                self.NA_identifier = self.visa_rm.list_resources()[0]
            except Exception as e:
                raise InputError('检查网分连接情况\n' + str(e))
        try:
            self.network_analysis_resource = self.visa_rm.open_resource(
                self.NA_identifier)
            self.NA = NetworkAnalyzer(self.network_analysis_resource,
                                      self.na_state, self.na_average_factor)
        except Exception as e:
            raise InputError('检查网分连接情况\n' + str(e))

    def pass_parameters(self, measurement_object):
        """pass input parameters to measurement object"""
        measurement_object.len_total = self.len_total
        measurement_object.f0 = self.frequency * 1e6
        measurement_object.num_of_measurements = self.num_of_mea
        measurement_object.len_step = self.len_step
        measurement_object.time_step = self.time_step
        measurement_object.na_average_factor = self.na_average_factor
        measurement_object.multi_measure = self.multi_measure
        measurement_object.temperature = self.temperature
        measurement_object.humidity = self.humidity / 100
        measurement_object.access_sensor_times = self.access_sensor_times
        measurement_object.motor = self.motor
        measurement_object.sensor = self.sensor
        measurement_object.network_analyzer = self.NA
        measurement_object.cal_cavity_frequency()

    def access_sensor_once(self):
        self.access_sensor_times = 1

    def access_sensor_repeat(self):
        self.access_sensor_times = 2

    def manual_measure_temperature_humidity(self):
        self.access_sensor_times = 0

    def set_auto_find_comp(self):
        self.sensor_comp = None
        self.motor_comp = None
        self.network_analysis_resource = None

    def close_ser(self):
        if isinstance(self.sensor_ser, Serial):
            self.sensor_ser.close()
        if isinstance(self.motor_ser, Serial):
            self.motor_ser.close()
        try:
            self.network_analysis_resource.close()
        except Exception:
            return

    def generate_measurement(self):
        """generate different measurement according to different strategy"""
        if self.measurement_strategy == 0:
            m1 = LongitudinalMeasurement()
            self.motor.set_distance(distance_mm=self.len_step)
            self.pass_parameters(m1)
            return m1
        elif self.measurement_strategy == 1:
            m1 = AngularMeasurement()
            self.motor.set_distance(distance=20000 / self.num_of_mea)
            self.pass_parameters(m1)
            return m1

    def save_input_file(self, file_name):
        file1 = open(file_name, 'w')
        file1.write(
            '& input parameters for field distribution measurement program\n')
        file1.write(
            '& lines begin with \'&\' will be ignored, \n'
            '& you don\'t have to write these lines in your input file.\n&\n&----------------------------\n&\n'
        )
        file1.write(
            '& measurement strategy (0 for longitudinal measurement, 1 for angular measurement)\n'
        )
        file1.write(f'    {self.measurement_strategy}\n')
        if self.measurement_strategy == 0:
            file1.write('& total length         movement step\n')
            file1.write(f'    {self.len_total}        {self.len_step}\n')
        elif self.measurement_strategy == 1:
            file1.write('& number of measurement\n')
            file1.write(f'    {self.num_of_mea}\n')
        file1.write(
            '& waiting time              multiple measurement time at each position (optional, default 1)\n'
        )
        file1.write(f'    {self.time_step} {self.multi_measure}\n')
        file1.write('& vacuum frequency\n')
        file1.write(f'    {self.frequency}\n')
        file1.write('& temperature and humidity\n')
        if self.access_sensor_times == 0:
            file1.write(f'    0    {self.temperature}    {self.humidity}\n')
        else:
            file1.write(f'    {int(self.access_sensor_times)}\n')
        file1.write('& data storage directory\n')
        file1.write(f'    {self.directory}\n')
        file1.write('& sensor (0 for auto find)\n')
        if self.sensor_comp is None:
            file1.write(f'    0\n')
        else:
            file1.write(f'    {self.sensor_comp}\n')
        file1.write('& motor (0 for auto find)\n')
        if self.motor_comp is None:
            file1.write(f'    0\n')
        else:
            file1.write(f'    {self.motor_comp}\n')
        file1.write('& network analyzer (0 for auto find)\n')
        if self.NA_identifier is None:
            file1.write(f'    0\n')
        else:
            file1.write(f'    {self.NA_identifier}\n')
        file1.write('& network analyzer average factor\n')
        file1.write(f'    {self.na_average_factor}\n')
        file1.write('& network analyzer state (optional)\n')
        if self.na_state is not None:
            file1.write(f'    {self.na_state}\n')
        file1.close()

    def __str__(self):
        text = ''
        if self.measurement_strategy == 0:
            text += f'\n{"腔体长度":4} = {self.len_total:8f} mm'
            text += f"\n{'运动步长':4} = {self.len_step:8f} mm"
        elif self.measurement_strategy == 1:
            text += f"\n{'测量次数':4} = {self.num_of_mea:4f}"
        text += f"\n{'等待时间':4} = {self.time_step:8f} s"
        text += f"\n{'真空频率':4} = {self.frequency:8f} MHz"
        if self.access_sensor_times == 1 or self.access_sensor_times == 2:
            text += "\n温湿度数据由传感器提供\n"
        text += f"\n{'温度':4} = {self.temperature:8f} ℃"
        text += f"\n{'湿度':4} = {self.humidity:8f} %\n"
        return text
Ejemplo n.º 9
0
class lifetimeMeasurement(QWidget):
    def __init__(self):
        super(lifetimeMeasurement, self).__init__()
        self.load_ui()
        self.connectAll()

        self.rm = ResourceManager()
        self.listResources()
        # self.laser_controller = self.rm.open_resource(self.comboBox_laserController.currentText())
        # self.oscilloscope = self.rm.open_resource(self.comboBox_oscilloscope.currentText())

        # self.laserController = None
        # self.oscilloscope = None
        self.widget_currentDecay.setBackground('w')
        self.widget_averagedDecay.setBackground('w')
        self.widget_fitting.setBackground('w')
        self.widget_currentDecay.setFrameShape(QFrame.Box)
        self.widget_averagedDecay.setFrameShape(QFrame.Box)
        self.widget_fitting.setFrameShape(QFrame.Box)

        self.on_list = []
        self.off_list = []
        self.averagedDecay = []
        self.xaxis = []
        self.current_list = []
        self.power_list = []
        self.timerCountdown = None
        self.timeLeft = None
        self.dataLoadedX = None
        self.dataLoadedY = None
        self.yFitted = None
        self.xFitReal = None
        self.scanCurrent = 0.

    def connectAll(self):
        # self.comboBox_laserController.currentTextChanged.connect(self.selectResources)
        self.pushButton_refresh.clicked.connect(self.refreshResources)
        self.pushButton_powerMeter.clicked.connect(
            self.refreshResourcesPowerMeter)
        self.pushButton_selectFolder.clicked.connect(self.selectFolder)
        self.pushButton_start.clicked.connect(self.startMeasure)
        self.pushButton_tmp.clicked.connect(self.clickTmp)
        # without singleShot, weird error occurs for pyvisa self.rm.open_resource for oscilloscope
        self.comboBox_laserController.currentIndexChanged.connect(
            lambda: QTimer.singleShot(0, self.updateResources))
        # without singleShot, weird error occurs for pyvisa self.rm.open_resource for oscilloscope
        self.comboBox_oscilloscope.currentIndexChanged.connect(
            lambda: QTimer.singleShot(0, self.updateResources))
        self.comboBox_powerMeter.currentIndexChanged.connect(
            lambda: QTimer.singleShot(0, self.updateResourcesPowerMeter))
        self.pushButton_laserOn.clicked.connect(
            lambda: self.laser_controller.write("OUTP ON"))
        self.pushButton_laserOff.clicked.connect(
            lambda: self.laser_controller.write("OUTP OFF"))
        self.lineEdit_setpoint.editingFinished.connect(self.currentSetpoint)
        self.pushButton_selectFileFit.clicked.connect(self.selectFileFit)
        self.pushButton_fromFile.clicked.connect(self.loadDataFromCsv)
        self.pushButton_fromMeasurement.clicked.connect(
            self.loadDataFromMeasurement)
        self.pushButton_fitDecay.clicked.connect(self.fitDecay)
        self.pushButton_saveFittedCurve.clicked.connect(self.saveFittedCurve)
        self.pushButton_startScanning.clicked.connect(self.startScanning)
        self.pushButton_scanFromMeasure.clicked.connect(
            self.loadScanDataFromMeasurement)
        self.pushButton_scanSave.clicked.connect(self.saveScanData)
        self.pushButton_scanFromFile.clicked.connect(self.loadScanDataFromFile)
        self.pushButton_scanFromMeasure_2.clicked.connect(
            self.loadScanDataFromMeasurement2)
        self.pushButton_scanFromFile_2.clicked.connect(
            self.loadScanDataFromFile2)

    # def selectResources(self):
    #     self.laserController = self.comboBox_laserController.currentText()
    #     self.oscilloscope = self.comboBox_oscilloscope.currentText()

    def clickTmp(self):
        print('on: ', np.shape(self.on_list))
        print('off: ', np.shape(self.off_list))

    def load_ui(self):
        path = os.path.join(os.path.dirname(__file__), "form.ui")
        uic.loadUi(path, self)

    def listResources(self):

        usb_list = self.rm.list_resources()
        print(usb_list)
        for item in usb_list:
            self.comboBox_laserController.addItem(item)
            self.comboBox_oscilloscope.addItem(item)
            self.comboBox_powerMeter.addItem(item)
            if "DS6D150100004" in item:
                self.comboBox_oscilloscope.setCurrentText(
                    item)  # find and define oscilloscope USB port
            elif "M00460823" in item:
                self.comboBox_laserController.setCurrentText(
                    item)  # find and define laser controller USB port
            elif "P0016683" in item:
                self.comboBox_powerMeter.setCurrentText(
                    item)  # find and define laser controller USB port

        # print(__file__)
    def refreshResources(self):
        self.comboBox_laserController.clear()
        self.comboBox_oscilloscope.clear()
        self.listResources()

    def refreshResourcesPowerMeter(self):
        self.comboBox_powerMeter.clear()
        self.listResources()

    def selectFolder(self):
        filename = QFileDialog.getExistingDirectory(self, 'select directory')
        self.lineEdit_folder.setText(filename)

    # def abort(self):
    #     pass

    def updateResources(self):
        # self.rm.close()
        # self.rm = ResourceManager()
        # print(self.comboBox_laserController.currentText())

        self.laser_controller = self.rm.open_resource(
            self.comboBox_laserController.currentText())
        # print(self.comboBox_oscilloscope.currentText())
        self.oscilloscope = self.rm.open_resource(
            self.comboBox_oscilloscope.currentText())
        print('update resources: laser_controller:',
              self.comboBox_laserController.currentText(), ' oscilloscope:',
              self.comboBox_oscilloscope.currentText())

    def updateResourcesPowerMeter(self):
        self.powerMeter = self.rm.open_resource(
            self.comboBox_powerMeter.currentText())
        print('update resources: powerMeter:',
              self.comboBox_powerMeter.currentText())

    def currentSetpoint(self):
        currSetpoint = self.lineEdit_setpoint.text()
        try:
            currSetpointValue = int(currSetpoint)
            print(currSetpointValue)
            self.laser_controller.write("SOUR:CURR {}".format(
                currSetpointValue / 1e4))
        except:
            self.lineEdit_setpoint.editingFinished.disconnect()
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Information)

            msg.setText("Laser Current Setpoint must be integers")
            # msg.setInformativeText("This is additional information")
            msg.setWindowTitle("Warning")
            # msg.setDetailedText("The details are as follows:")
            # msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
            # msg.buttonClicked.connect(msgbtn)
            msg.exec_()
            self.lineEdit_setpoint.editingFinished.connect(
                self.currentSetpoint)
            # print
            # "value of pressed message box button:", retval

    def startMeasure(self):
        # self.rm.close()
        # self.rm = ResourceManager()
        self.laser_controller = self.rm.open_resource(
            self.comboBox_laserController.currentText())
        self.oscilloscope = self.rm.open_resource(
            self.comboBox_oscilloscope.currentText())
        self.steps = self.spinBox_turns.value()
        self.stepsDouble = self.steps * 2
        waiting_time = self.spinBox_acquiringTime.value()
        timeBetweenTurns = self.spinBox_timeBetweenTurns.value()

        self.spinBox_turns.setEnabled(False)
        self.spinBox_acquiringTime.setEnabled(False)
        self.spinBox_timeBetweenTurns.setEnabled(False)
        self.spinBox_xaxis.setEnabled(False)
        # self.pushButton_start.setText('Abort')

        # self.process = QProcess(self)
        # # QProcess emits `readyRead` when there is data to be read
        # self.process.readyRead.connect(self.dataReady)
        # self.runButton1.clicked.connect(self.process.kill)

        print(self.steps, waiting_time, timeBetweenTurns)

        self.label_turnsLeft.setText('Turns Finished: 0/' + str(self.steps))

        self.totalTime = int(
            (self.stepsDouble) *
            (waiting_time + timeBetweenTurns)) - timeBetweenTurns + 1
        self.timeLeft = self.totalTime
        print(self.timeLeft)
        self.countdown(intervalSecond=1)
        self.progressBar.setValue(0)
        self.on_list = []
        self.off_list = []

        # self.measureEachTurn(-1,laser_controller,oscilloscope,stepsDouble,waiting_time=waiting_time,timeBetweenTurns=timeBetweenTurns)

        self.timerLaserControl = QTimer()
        self.timerOscilloscopeRun = QTimer()
        self.timerOscilloscopeStop = QTimer()
        #
        self.currTurn = 0
        #
        self.timerLaserControl.timeout.connect(
            lambda: self.laserControl(self.laser_controller))
        self.timerOscilloscopeRun.timeout.connect(
            lambda: self.oscilloscopeRun(self.oscilloscope))
        self.timerOscilloscopeStop.timeout.connect(
            lambda: self.oscilloscopeStop(self.oscilloscope))

        self.laserControl(self.laser_controller)
        self.oscilloscopeRun(self.oscilloscope)
        QTimer.singleShot(int(waiting_time * 1e3),
                          lambda: self.oscilloscopeStop(self.oscilloscope))

        self.timerLaserControl.start(
            int((waiting_time + timeBetweenTurns) * 1e3))
        self.timerOscilloscopeRun.start(
            int((waiting_time + timeBetweenTurns) * 1e3))
        QTimer.singleShot(
            int(waiting_time * 1e3), lambda: self.timerOscilloscopeStop.start(
                int((waiting_time + timeBetweenTurns) * 1e3)))

        QTimer.singleShot(int((self.totalTime) * 1e3), self.restartSpinBoxes)

    def restartSpinBoxes(self):
        self.spinBox_turns.setEnabled(True)
        self.spinBox_acquiringTime.setEnabled(True)
        self.spinBox_timeBetweenTurns.setEnabled(True)
        self.spinBox_xaxis.setEnabled(True)

    def laserControl(self, laser_controller):
        # print(self.currTurn)
        if self.currTurn % 2 == 0:
            laser_controller.write("OUTP ON")
            print('laser on')
        else:
            laser_controller.write("OUTP OFF")
            print('laser off')

    def oscilloscopeRun(self, oscilloscope):
        oscilloscope.write(":RUN")
        print('oscilloscopeRun')

    def oscilloscopeStop(
        self,
        oscilloscope,
        start=1,
        points=70000000,
    ):
        if self.currTurn == self.stepsDouble - 1:
            print('stop properly')
            self.timerLaserControl.stop()
            self.timerOscilloscopeRun.stop()
            self.timerOscilloscopeStop.stop()

        wt = 0
        oscilloscope.write(":STOP")
        oscilloscope.write(
            ":WAV:MODE NORM"
        )  # RAW means deeper raw data. NORM means displayed data
        time.sleep(wt)
        oscilloscope.write(":WAV:STAR " + str(start))
        time.sleep(wt)
        oscilloscope.write(":WAV:STOP " + str(points + start))
        time.sleep(wt)
        oscilloscope.write(":WAV:POIN " + str(points))
        time.sleep(wt)
        oscilloscope.write(":WAV:SOUR CHAN1")
        time.sleep(wt)
        oscilloscope.write(":WAV:RES")
        time.sleep(wt)
        oscilloscope.write(":WAV:BEG")
        time.sleep(wt)
        rawdata = oscilloscope.query_binary_values(':WAV:DATA?',
                                                   datatype='B',
                                                   is_big_endian=False)
        if self.currTurn % 2 == 0:
            self.on_list.append(rawdata)
            print('onlist append')
        else:
            self.off_list.append(rawdata)
            print('offlist append')
            self.label_turnsLeft.setText(
                'Turns Finished: ' +
                str(int(np.floor((self.currTurn + 1) / 2))) + '/' +
                str(int(self.steps)))
            QTimer.singleShot(500, self.plotDecay)
            QTimer.singleShot(500, lambda: print('plotDecay'))
        self.currTurn += 1

        print('oscilloscopeStop')

    def countdown(self, intervalSecond):

        self.timerCountdown = QTimer()
        # print(123)
        self.timerCountdown.timeout.connect(
            lambda: self.updateCountdown(intervalSecond))
        self.timerCountdown.start(int(intervalSecond * 1e3))
        # print(456)

    def updateCountdown(self, intervalSecond):
        self.timeLeft -= intervalSecond
        self.progressBar.setValue(
            int((self.totalTime - self.timeLeft) / self.totalTime * 100))
        newtime = time.strftime('%H : %M : %S', time.gmtime(self.timeLeft))
        self.label_countdown.setText("Time Left:    " + newtime +
                                     " (hh : mm : ss)")
        print(newtime)
        if self.timeLeft == 0:
            self.timerCountdown.stop()
        # "Time Left:    00 : 00 : 00 (hh : mm : ss)"

    def plotDecay(self):
        unitTime = int(self.spinBox_xaxis.value())
        currentDecay = np.asarray([
            item1 - item2
            for item1, item2 in zip(self.on_list[-1], self.off_list[-1])
        ])
        self.widget_currentDecay.clear()
        self.xaxis = unitTime * 14 / len(currentDecay) * np.asarray(
            range(len(currentDecay)))
        self.widget_currentDecay.plot(self.xaxis, currentDecay)

        on_mean = np.mean(self.on_list, axis=0)
        off_mean = np.mean(self.off_list, axis=0)
        self.averagedDecay = np.array(
            [item1 - item2 for item1, item2 in zip(on_mean, off_mean)])
        self.widget_averagedDecay.clear()
        self.widget_averagedDecay.plot(self.xaxis, self.averagedDecay)

        path = self.lineEdit_folder.text()
        filename = self.lineEdit_file.text()
        self.saveFiles(path, filename, self.on_list, self.off_list,
                       self.averagedDecay, self.xaxis)

    def saveFiles(self, path, filename, rawdata_on, rawdata_off, averaged,
                  xaxis):

        df1 = DataFrame(rawdata_on).T
        df2 = DataFrame(rawdata_off).T
        df3 = DataFrame(averaged)
        df1 = df1.rename(columns={0: 'signal'})
        df2 = df2.rename(columns={0: 'signal'})
        df3 = df3.rename(columns={0: 'signal'})
        df1.index = xaxis
        df2.index = xaxis
        df3.index = xaxis
        df1.index.name = 'Time(ns)'
        df2.index.name = 'Time(ns)'
        df3.index.name = 'Time(ns)'

        df1.to_csv(path + '/' + filename + '_on.csv')
        df2.to_csv(path + '/' + filename + '_off.csv')
        df3.to_csv(path + '/' + filename + '_averaged.csv')

    def selectFileFit(self):
        filename, _ = QFileDialog.getOpenFileName(
            self, 'select *_averaged.csv file')
        self.lineEdit_selectFileFit.setText(filename)

    def loadDataFromCsv(self):
        self.widget_fitting.clear()
        dataLoaded = read_csv(self.lineEdit_selectFileFit.text(), index_col=0)
        self.dataLoadedX = np.asarray(dataLoaded.index)
        if self.checkBox_inversed.isChecked():
            self.dataLoadedY = -np.asarray(dataLoaded['signal'])
        else:
            self.dataLoadedY = np.asarray(dataLoaded['signal'])
        # print(self.dataLoaded)
        self.widget_fitting.plot(self.dataLoadedX, self.dataLoadedY)

    def loadDataFromMeasurement(self):
        self.widget_fitting.clear()
        self.dataLoadedX = self.xaxis
        if self.checkBox_inversed.isChecked():
            self.dataLoadedY = -self.averagedDecay
        else:
            self.dataLoadedY = self.averagedDecay
        self.widget_fitting.plot(self.dataLoadedX, self.dataLoadedY)

    def fitDecay(self):
        self.widget_fitting.clear()
        self.widget_fitting.plot(self.dataLoadedX, self.dataLoadedY)
        if self.radioButton_decay1.isChecked():
            decay = decay1
            bounds = [[0, 0, -np.inf], np.inf]
        elif self.radioButton_decay2.isChecked():
            decay = decay2
            bounds = [[0, 0, 0, 0, -np.inf], np.inf]
        elif self.radioButton_decay3.isChecked():
            decay = decay3
            bounds = [[0, 0, 0, 0, 0, 0, -np.inf], np.inf]
        starting = self.doubleSpinBox_starting.value()
        ending = self.doubleSpinBox_ending.value()
        selectedIndices = np.where(
            np.logical_and(self.dataLoadedX > starting,
                           self.dataLoadedX < ending))[0]
        xSelected = self.dataLoadedX[selectedIndices]
        ySelected = self.dataLoadedY[selectedIndices]
        xFit = normalize(xSelected)
        params, corrs = curve_fit(decay, xFit, ySelected, bounds=bounds)
        self.yFitted = decay(xFit, *params)
        self.xFitReal = np.round(denormalize(xFit, xSelected), 2)
        self.widget_fitting.plot(self.xFitReal,
                                 self.yFitted,
                                 pen=mkPen(color='r'))

        if decay == decay1:
            self.textBrowser_result.setText(
                'A=' + str(np.round(params[0], 5)) + ', t=' +
                str(np.round(denormalize(params[1], xSelected), 5)) + ', y0=' +
                str(np.round(params[2], 5)))
        elif decay == decay2:
            # paramIndices = np.argsort([params[1],params[2]])
            self.textBrowser_result.setText(
                'A1=' + str(np.round(params[0], 5)) + ', A2=' +
                str(np.round(params[1], 5)) + ', t1=' +
                str(np.round(denormalize(params[2], xSelected), 5)) + ', t2=' +
                str(np.round(denormalize(params[3], xSelected), 5)) + ', y0=' +
                str(np.round(params[4], 5)))
        elif decay == decay3:
            self.textBrowser_result.setText(
                'A1=' + str(np.round(params[0], 5)) + ', A2=' +
                str(np.round(params[1], 5)) + ', A3=' +
                str(np.round(params[2], 5)) + ', t1=' +
                str(np.round(denormalize(params[3], xSelected), 5)) + ', t2=' +
                str(np.round(denormalize(params[4], xSelected), 5)) + ', t3=' +
                str(np.round(denormalize(params[5], xSelected), 5)) + ', y0=' +
                str(np.round(params[6], 5)))

    def saveFittedCurve(self):
        path = QFileDialog.getSaveFileName(
            self, 'Save Fitted Curve with Data', './',
            "csv Files (*.csv);;All Files (*)")[0]
        df1 = DataFrame(self.dataLoadedY).rename(columns={0: 'signal'})
        df1.index = self.dataLoadedX
        df2 = DataFrame(self.yFitted).rename(columns={0: 'fitting'})
        df2.index = self.xFitReal
        df = df1.join(df2)
        df.index.name = 'Time(ns)'
        print(path)
        # print(df)
        df.to_csv(path)

    def startScanning(self):
        self.tableWidget_scanCurrent.setRowCount(0)
        self.progressBar_currentScan.setValue(0)
        self.current_list = []
        self.power_list = []
        self.laser_controller = self.rm.open_resource(
            self.comboBox_laserController.currentText())
        self.powerMeter = self.rm.open_resource(
            self.comboBox_powerMeter.currentText())

        starting = self.spinBox_currentStart.value() * 1e-4
        self.scanCurrent = np.round(starting, 6)
        ending = self.spinBox_currentEnd.value() * 1e-4
        steps = self.spinBox_currentSteps.value()
        currentDelta = float(ending - starting) / steps
        time = self.spinBox_currentTime.value()
        step_time = int(float(time) / steps * 1e3)
        self.tmpIndexScan = 0
        self.scanTimer = QTimer()
        self.scanTimer.timeout.connect(
            lambda: self.getPower(currentDelta, self.current_list, self.
                                  power_list, starting, ending, steps))
        self.scanTimer.start(step_time)
        print('scanning started', self.scanTimer)

    def getPower(self, currentDelta, current_list, power_list, starting,
                 ending, steps):
        flag = False
        if self.tmpIndexScan >= steps:  #self.scanCurrent>ending:
            self.scanTimer.stop()
            self.progressBar_currentScan.setValue(100)
            flag = True
            # del self.tmpIndexScan
        # current input
        self.laser_controller.write("SOUR:CURR {}".format(self.scanCurrent))
        power = self.powerMeter.query('Measure:Scalar:POWer?')
        self.tableWidget_scanCurrent.insertRow(
            self.tableWidget_scanCurrent.rowCount())
        self.tableWidget_scanCurrent.setItem(
            self.tmpIndexScan, 0,
            QTableWidgetItem(str(int(self.scanCurrent * 1e4))))
        self.tableWidget_scanCurrent.setItem(
            self.tmpIndexScan, 1, QTableWidgetItem(str(float(power) * 1e6)))
        current_list.append(np.float(self.scanCurrent))
        power_list.append(np.float(power))
        self.scanCurrent += currentDelta
        self.scanCurrent = np.round(self.scanCurrent, 6)
        self.tmpIndexScan += 1

        self.progressBar_currentScan.setValue(
            int((self.scanCurrent - starting) / (ending - starting) * 100))

        if flag == True:  #self.scanCurrent>ending:
            self.laser_controller.write("SOUR:CURR {}".format(0))
        print(self.scanCurrent, power)

    def fillScanTable(self, tableWidget, scan_current_list, scan_power_list):
        tableWidget.setRowCount(0)
        tableWidget.setRowCount(len(scan_current_list))
        for ind in range(len(scan_current_list)):
            tableWidget.setItem(
                ind, 0,
                QTableWidgetItem(str(int(scan_current_list[ind] * 1e4))))
            tableWidget.setItem(
                ind, 1,
                QTableWidgetItem(str(float(scan_power_list[ind]) * 1e6)))

    def loadScanDataFromMeasurement(self):
        self.fillScanTable(self.tableWidget_scanCurrent, self.current_list,
                           self.power_list)

    def loadScanDataFromMeasurement2(self):
        self.fillScanTable(self.tableWidget_scanCurrent_2, self.current_list,
                           self.power_list)

    def saveScanData(self):
        path = QFileDialog.getSaveFileName(
            self, 'Save Measured Powers with Currents', './',
            "csv Files (*.csv);;All Files (*)")[0]
        df = DataFrame({
            'Current (A)': self.current_list,
            'Power (W)': self.power_list
        })
        df.to_csv(path, index=False)

    def loadScanDataFromFile(self):
        path = QFileDialog.getOpenFileName(self, 'Selected Saved *csv File')[0]
        df = read_csv(path, index_col=None)
        file_current_list = df.iloc[:, 0].values
        file_power_list = df.iloc[:, 1].values
        self.fillScanTable(self.tableWidget_scanCurrent, file_current_list,
                           file_power_list)

    def loadScanDataFromFile2(self):
        path = QFileDialog.getOpenFileName(self, 'Selected Saved *csv File')[0]
        df = read_csv(path, index_col=None)
        file_current_list = df.iloc[:, 0].values
        file_power_list = df.iloc[:, 1].values
        self.fillScanTable(self.tableWidget_scanCurrent_2, file_current_list,
                           file_power_list)