diff --git a/src/LockIn-Stanford_SR830/license.txt b/src/LockIn-Stanford_SR830/license.txt
index 1e6e48bd..e13722a3 100644
--- a/src/LockIn-Stanford_SR830/license.txt
+++ b/src/LockIn-Stanford_SR830/license.txt
@@ -5,7 +5,7 @@ find those in the corresponding folders or contact the maintainer.
MIT License
-Copyright (c) 2021-2023 SweepMe! GmbH (sweep-me.net)
+Copyright (c) 2021-2024 SweepMe! GmbH (sweep-me.net)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -25,5 +25,5 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-We like to thank Jakob Wolansky/TU Dresden for contributing to the improvement
-of the driver.
\ No newline at end of file
+Contribution: We like to thank Jakob Wolansky/TU Dresden for contributing
+to the improvement of the driver.
\ No newline at end of file
diff --git a/src/LockIn-Stanford_SR830/main.py b/src/LockIn-Stanford_SR830/main.py
index 8556a50b..baca9d1b 100644
--- a/src/LockIn-Stanford_SR830/main.py
+++ b/src/LockIn-Stanford_SR830/main.py
@@ -5,7 +5,7 @@
#
# MIT License
#
-# Copyright (c) 2021-2023 SweepMe! GmbH (sweep-me.net)
+# Copyright (c) 2021-2024 SweepMe! GmbH (sweep-me.net)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -25,15 +25,15 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
-# We like to thank Jakob Wolansky/TU Dresden for contributing to the improvement
-# of the driver.
+# Contribution: We like to thank Jakob Wolansky/TU Dresden for contributing
+# to the improvement of the driver.
-# SweepMe! device class
-# Type: LockIn
-# Device: SR830
+# SweepMe! driver
+# * Module: LockIn
+# * Instrument: SR830
-from EmptyDeviceClass import EmptyDevice
+from pysweepme.EmptyDeviceClass import EmptyDevice
import time
from collections import OrderedDict
@@ -47,7 +47,8 @@ def __init__(self):
# self.variables = ["Magnitude", "Phase", "Frequency", "X", "Y", "Channel 1", "Channel 2", "TimeConstant" ]
# self.units = ["a.u.", "deg", "Hz", "a.u.", "a.u.", "V/sqrt(Hz)", "V/sqrt(Hz)", "s"]
-
+
+
# here the port handling is done
# the MeasClass automatically creates the PortObject during in the connect function of the MeasClass
self.port_manager = True
@@ -276,37 +277,35 @@ def __init__(self):
def set_GUIparameter(self):
gui_parameter = {
- "SweepMode": ["None", "Frequency in Hz", "Time constant in s", "Sensitivity in V", "Sensitivity in A"],
- "Source": ["Internal", "External (Sine)", "External (TTL Rising)", "External (TTL Falling)"],
- "Input": ["A", "A-B", "I@10^6", "I@10^8"],
- "Reserve": ["Low Noise", "Normal", "High Reserve"],
- "Filter1": ["No Filter", "Line", "2xLine", "Line + 2xLine"],
- "Filter2": ["No Sync Filter", "Sync Filter"],
- "Channel1": ["None", "X", "R", "X noise", "AUX IN 1", "AUX IN 2"],
- "Channel2": ["None", "Y", "Phi", "Y noise", "AUX IN 3", "AUX IN 4"],
- "TimeConstant": list(self.timeconstants.keys()), # ["Auto time", "As is"] +
- # "Gain": ["Auto gain", "As is"] + list(self.sensitivities.keys()),
- "Sensitivity": ["Auto", "As is"] + list(self.sensitivities_voltages.keys()) + list(self.sensitivities_currents.keys()),
- "Slope": ["6dB", "12dB", "18dB", "24dB"],
- "Coupling": ["AC", "DC"],
- "Ground": ["Float", "Ground"],
- "WaitTimeConstants": 4.0,
- }
+ "SweepMode": ["None", "Frequency in Hz", "Time constant in s", "Sensitivity in V", "Sensitivity in A"],
+ "Source": ["Internal", "External (Sine)", "External (TTL Rising)", "External (TTL Falling)"],
+ "Input": ["A", "A-B", "I@10^6", "I@10^8"],
+ "Reserve": ["Low Noise", "Normal", "High Reserve"],
+ "Filter1": ["No Filter", "Line", "2xLine", "Line + 2xLine"],
+ "Filter2": ["No Sync Filter", "Sync Filter"],
+ "Channel1": ["None", "X", "R", "X noise", "AUX IN 1", "AUX IN 2"],
+ "Channel2": ["None", "Y", "Phi", "Y noise", "AUX IN 3", "AUX IN 4"],
+ "TimeConstant": list(self.timeconstants.keys()), # ["Auto time", "As is"] +
+ "Sensitivity": ["Auto", "As is"] + list(self.sensitivities_voltages.keys()) + list(self.sensitivities_currents.keys()),
+ "Slope": ["6dB", "12dB", "18dB", "24dB"],
+ "Coupling": ["AC", "DC"],
+ "Ground": ["Float", "Ground"],
+ "WaitTimeConstants": 4.0,
+ }
return gui_parameter
def get_GUIparameter(self, parameter={}):
self.sweepmode = parameter["SweepMode"]
- self.source = parameter["Source"]
- self.input = parameter["Input"]
- self.coupling = parameter["Coupling"]
- self.slope = parameter["Slope"]
+ self.source = parameter["Source"]
+ self.input = parameter["Input"]
+ self.coupling = parameter["Coupling"]
+ self.slope = parameter["Slope"]
self.ground = parameter["Ground"]
self.reserve = parameter["Reserve"]
self.filter1 = parameter["Filter1"]
self.filter2 = parameter["Filter2"]
- self.gain = parameter["Gain"]
self.sensitivity = parameter["Sensitivity"]
self.timeconstant = parameter["TimeConstant"]
self.channel1 = parameter["Channel1"]
@@ -414,9 +413,7 @@ def configure(self):
self.port.write(self.commands[self.filter1])
self.port.write(self.commands[self.filter2])
- if self.sensitivity == "Auto":
- pass
- elif self.sensitivity == "As is":
+ if self.sensitivity == "Auto" or self.sensitivity == "As is":
pass
else:
if (self.input_quantity == "Current") and "A" in self.sensitivity:
@@ -429,33 +426,52 @@ def configure(self):
if self.timeconstant not in ["Auto time", "As is"] and self.timeconstant in self.timeconstants:
self.port.write(self.timeconstants[self.timeconstant])
- def reconfigure(self, parameters={}, keys=[]):
+ def reconfigure(self, parameter={}, keys=[]):
"""
function to be overloaded if needed
- if a GUI parameter changes after replacement with global parameters, the device needs to be reconfigure.
+ if a GUI parameter changes after replacement with global parameters, the device needs to be reconfigured.
Default behavior is that all parameters are set again and 'configure' is called.
The device class maintainer can redefine/overwrite 'reconfigure' with a more individual procedure.
"""
-
- # print()
- # print("reconfigure")
- # print(keys) # the ones that have changed
- if "Sensitivity" in keys:
- if self.sensitivity == "Auto":
+
+ """
+ if self.sweepmode == "Time constant in s":
+ try:
+ if self.value == "None":
+ time_constant = self.timeconstants_values[self.timeconstant]
+ if time_constant <= 1:
+ pass
+ else:
+ if self.value <= 1:
+ pass
+ except:
+ time_constant = self.timeconstants_values[self.timeconstant]
+ if time_constant <= 1:
+ pass
+ else:
+ time_constant = self.timeconstants_values[self.timeconstant]
+ if time_constant <= 1:
pass
- elif self.sensitivity == "As is":
+ """
+
+ self.sensitivity = parameter["Sensitivity"]
+ if "Sensitivity" in keys:
+ if self.sensitivity == "Auto" or self.sensitivity == "As is":
pass
else:
- if (self.input_quantity == "Current") and "A" in self.sensitivity:
- self.port.write(self.sensitivities_all[self.sensitivity])
- elif (self.input_quantity == "Voltage") and "V" in self.sensitivity:
- self.port.write(self.sensitivities_all[self.sensitivity])
- else:
- raise Exception('The input mode and sensitivity should match.')
+ try:
+ sensitivity = float(self.sensitivity)
+ self.set_sensitivity(sensitivity)
+ except:
+ if (self.input_quantity == "Current") and "A" in self.sensitivity:
+ self.set_sensitivity(self.sensitivity)
+ elif (self.input_quantity == "Voltage") and "V" in self.sensitivity:
+ self.set_sensitivity(self.sensitivity)
+ else:
+ raise Exception('The input mode and sensitivity should match.')
- def apply(self):
-
+ def apply(self):
if self.sweepmode.startswith("Frequency"):
self.port.write("FREQ %s" % self.value)
@@ -473,8 +489,7 @@ def apply(self):
if self.value >= 0.65*exp_step:
number = round(self.value/exp_step, 0)
- # print(number)
-
+
for multiplicator in [1, 10, 100]:
if number <= 2 * multiplicator:
@@ -487,27 +502,27 @@ def apply(self):
break
self.timeconstant = str(number) + " " + conversion[exp_step]
- # print("Time constant:", self.timeconstant)
self.port.write(self.timeconstants[self.timeconstant])
elif self.sweepmode.startswith("Sensitivity"):
-
+ self.set_sensitivity(self.value)
+
+ """
sensitivity_unit = self.sweepmode[-1]
- # TODO: distinguish between V or A -> see update sweep modes "Sensitivity in V" and "Sensitivity in A"
conversion = {
- 1e0: ("V or ", "muA"),
+ 1e0 : ("V or ", "muA"),
1e-3: ("mV or ", "nA"),
1e-6: ("muV or ", "pA"),
1e-9: ("nV or ", "fA"),
}
-
for exp_step in list(conversion.keys()):
- # print("self.value", self.value)
+ #print("self.value", self.value)
if self.value >= 0.75*exp_step:
- number = round(self.value/exp_step, 0)
- # print(number)
+ number = round(self.value/exp_step,0)
+
+ #print(number)
for multiplicator in [1, 10, 100]:
@@ -522,12 +537,13 @@ def apply(self):
elif number <= 7.5 * multiplicator:
number = 5 * multiplicator
break
-
+
break
self.sensitivity = str(number) + " " + conversion[exp_step][0] + str(number) + " " + conversion[exp_step][1]
- # print(self.sensitivity)
+ #print(self.sensitivity)
self.port.write(self.sensitivities_all[self.sensitivity])
+ """
def adapt(self):
@@ -546,10 +562,10 @@ def adapt_ready(self):
self.time_ref = time.perf_counter()
def trigger_ready(self):
- # make sure that at least several timeconstants have passed since 'Auto sensitivity' was called
+ # make sure that at least several time constants have passed since 'Auto sensitivity' was called
delta_time = (self.waittimeconstants * self.unit_to_float(self.timeconstant)) - (time.perf_counter()-self.time_ref)
if delta_time > 0.0:
- # wait several timeconstants to allow for a renewal of the result
+ # wait several time constants to allow for a renewal of the result
time.sleep(delta_time)
def measure(self):
@@ -570,27 +586,26 @@ def read_result(self):
self.Ch1 = float(self.port.read())
if self.channel2 != "None":
self.Ch2 = float(self.port.read())
- self.sens = self.read_sensitivity()
- self.timeconstant = self.read_timeconstant()
-
+ self.sens = self.get_sensitivity()
+ self.time_constant = self.get_timeconstant()
+
def call(self):
results = [self.R, self.Phi, self.F, self.X, self.Y]
if self.channel1 != "None":
results += [self.Ch1]
if self.channel2 != "None":
results += [self.Ch2]
- time_constant = self.timeconstants_values[self.timeconstant]
- results += [time_constant]
+ results += [self.time_constant]
results += [self.sens]
- return results
- # here convenience functions starts
+ return results
@staticmethod
def unit_to_float(unit):
"""Takes a string representing a sensitivity or time constant and gives back a corresponding float"""
chars = OrderedDict([
("V", ""),
+ ("A", ""),
("s", ""),
(" ", ""),
("p", "e-12"),
@@ -610,40 +625,104 @@ def get_identification(self):
self.port.write("*IDN?")
return self.port.read()
- def read_sensitivity(self):
- tempSensDev = (self.port.read())
+ def set_sensitivity(self, sensitivity):
+
+ if self.input_quantity == "Voltage": # if sensitivity is already at max limit
+ if float(sensitivity) > 1:
+ self.sensitivity = str(1) + " V"
+ self.port.write(self.sensitivities_voltages[self.sensitivity])
+ return
+ else:
+ conversion = {
+ 1e0 : "V",
+ 1e-3: "mV",
+ 1e-6: "muV",
+ 1e-9: "nV",
+ }
+ else:
+ if float(sensitivity) > 1e-6: # if sensitivity is already at max limit
+ self.sensitivity = str(1) + " muA"
+ self.port.write(self.sensitivities_currents[self.sensitivity])
+ return
+ else:
+ conversion = {
+ 1e0 : "muA",
+ 1e-3: "nA",
+ 1e-6: "pA",
+ 1e-9: "fA",
+ }
+ for exp_step in list(conversion.keys()):
+ if sensitivity >= 0.75*exp_step:
+
+ number = round(sensitivity/exp_step,0)
+
+ for multiplicator in [1, 10, 100]:
+
+ if number <= 1.5 * multiplicator:
+ number = 1 * multiplicator
+ break
+ elif number <= 3.5 * multiplicator:
+ number = 2 * multiplicator
+ break
+ elif number <= 7.5 * multiplicator:
+ number = 5 * multiplicator
+ break
+
+ break
+
+ self.sensitivity = str(number) + " " + conversion[exp_step]
+ if self.input_quantity == "Voltage":
+ self.port.write(self.sensitivities_voltages[self.sensitivity])
+ else:
+ self.port.write(self.sensitivities_currents[self.sensitivity])
+
+ def get_sensitivity(self):
+ temp_sens_dev = self.port.read()
if self.input_quantity == "Current":
- # tempSensSet is then a python set
- tempSensSet = {s for s in self.sensitivities_currents if self.sensitivities_currents[s] == ("SENS " + tempSensDev)}
+ # temp_sens_set is then a python set
+ temp_sens_set = {s for s in self.sensitivities_currents if self.sensitivities_currents[s] == ("SENS " + temp_sens_dev)}
if self.input_quantity == "Voltage":
- # tempSensSet is then a python set
- tempSensSet = {s for s in self.sensitivities_voltages if self.sensitivities_voltages[s] == ("SENS " + tempSensDev)}
- # print(tempSensSet)
- tempSens = self.sensString_to_float(tempSensSet)
-
- return tempSens
-
- def read_timeconstant(self):
- tempTimeConstantDev = (self.port.read())
- # tempTimeConstantSet is then a python set
- tempTimeConstantSet = {s for s in self.timeconstants if self.timeconstants[s] == ("OFLT " + tempTimeConstantDev)}
- tempTimeConstant = self.timeConstantString_to_float(tempTimeConstantSet)
- return tempTimeConstant
-
- def sensString_to_float(self, sensSet):
- """Takes a sensitivitiy string and extracts the float number"""
+ # temp_sens_set is then a python set
+ temp_sens_set = {s for s in self.sensitivities_voltages if self.sensitivities_voltages[s] == ("SENS " + temp_sens_dev)}
+
+ temp_sens = self.sens_string_to_float(temp_sens_set)
+
+ return temp_sens
+
+ def get_timeconstant(self):
+ temp_time_constant_dev = (self.port.read())
+ # temp_time_constant_set is then a python set
+ temp_time_constant_set = {s for s in self.timeconstants if self.timeconstants[s] == ("OFLT " + temp_time_constant_dev)}
+ temp_time_constant = self.time_constant_string_to_float(temp_time_constant_set)
+
+ return temp_time_constant
+
+ def sens_string_to_float(self, sensSet):
+ """Takes a sensitivity string and extracts the float number"""
sensString = sensSet.pop()
- if self.input_quantity == "Voltage":
- tempCorrectSensitivityUnit = sensString[sensString.find("V")-1: sensString.find("V")]
- else:
- tempCorrectSensitivityUnit = sensString[sensString.find("A")-1: sensString.find("A")]
- tempCorrectSensitivityValue = self.unit_to_float(sensString)
- return tempCorrectSensitivityValue
+ temp_correct_sensitivity_value = self.unit_to_float(sensString)
+
+ return temp_correct_sensitivity_value
- def timeConstantString_to_float(self, timeConstantSet):
+ def time_constant_string_to_float(self, time_constant_set):
"""Takes a time constant string and extracts the float number"""
- timeConstantString = timeConstantSet.pop()
- # tempCorrectTimeConstantUnit = timeConstantString[timeConstantString.find("s")-1: timeConstantString.find("s")]
- # tempCorrectTimeConstantValue = self.unit_to_float(timeConstantString)
- return timeConstantString
+ time_constant_string = time_constant_set.pop()
+ time_constant = self.timeconstants_values[time_constant_string]
+
+ return time_constant
+
+ def sens_string_to_float_old(self, sens_set):
+ """Takes a sensitivity string and extracts the float number"""
+
+ sens_string = sens_set.pop()
+ if self.units[0] == "V":
+ index = sens_string.find("or")
+ temp_correct_sensitivity_str = sens_string[:index]
+ temp_correct_sensitivity_value = self.unit_to_float(temp_correct_sensitivity_str)
+ else:
+ index = sens_string.find("or") + len("or")
+ temp_correct_sensitivity_str = sens_string[index:]
+ temp_correct_sensitivity_value = self.unit_to_float(temp_correct_sensitivity_str)
+
+ return temp_correct_sensitivity_value
diff --git a/src/Monochromator-QuantumDesign_MSH-300/license.txt b/src/Monochromator-QuantumDesign_MSH-300/license.txt
index 944ea14e..d7f2c813 100644
--- a/src/Monochromator-QuantumDesign_MSH-300/license.txt
+++ b/src/Monochromator-QuantumDesign_MSH-300/license.txt
@@ -5,7 +5,7 @@ find those in the corresponding folders or contact the maintainer.
MIT License
-Copyright (c) 2022 SweepMe! GmbH (sweep-me.net)
+Copyright (c) 2024 SweepMe! GmbH (sweep-me.net)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -25,4 +25,5 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-Contribution: We like to thank TU Dresden (Toni Bärschneider and Jakob Wolansky) for providing the initial version of this driver.
\ No newline at end of file
+Contribution: We like to thank TU Dresden (Toni Bärschneider and Jakob Wolansky)
+for providing the initial version of this driver.
\ No newline at end of file
diff --git a/src/Monochromator-QuantumDesign_MSH-300/main.py b/src/Monochromator-QuantumDesign_MSH-300/main.py
index e3a3f16a..63210626 100644
--- a/src/Monochromator-QuantumDesign_MSH-300/main.py
+++ b/src/Monochromator-QuantumDesign_MSH-300/main.py
@@ -5,7 +5,7 @@
# MIT License
-# Copyright (c) 2022 SweepMe! GmbH (sweep-me.net)
+# Copyright (c) 2024 SweepMe! GmbH (sweep-me.net)
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -29,9 +29,9 @@
# Contribution: We like to thank TU Dresden (Toni Bärschneider and Jakob Wolansky) for
# providing the initial version of this driver.
-# SweepMe! device class
-# Type: Monochromator
-# Device: Quantum Design MSH-300
+# SweepMe! driver
+# * Module: Monochromator
+# * Instrument: Quantum Design MSH-300
import time
import ctypes
@@ -44,7 +44,7 @@
from collections import OrderedDict
-import FolderManager
+from pysweepme import FolderManager
FoMa = FolderManager.FolderManager()
FolderManager.addFolderToPATH()
@@ -142,10 +142,10 @@ def __init__(self):
def set_GUIparameter(self):
gui_parameter = {
- "SweepMode": ["Wavelength in nm", "None"], # "Reflection (zero order)", "Slitwidth [µm]" needs additional fix wavelength option
+ "SweepMode": ["Wavelength in nm", "Energy in eV", "None"],
"EndPosition": "",
- "Input": list(self.slitinputs.keys()), # TODO: Is this self.inport?
- "Output": list(self.slitoutputs.keys()), # TODO: Is this self.outport?
+ "Input": list(self.slitinputs.keys()),
+ "Output": list(self.slitoutputs.keys()),
"Filter": ["Auto"] + self.filters,
"Grating": ["Auto"] + self.gratings,
# "SlitOutput": ["2000 (max)", "1500", "6 (min)"],
@@ -308,8 +308,21 @@ def unconfigure(self):
def apply(self):
if self.sweep_mode.startswith("Wavelength"):
+ # if self.value is below than 10, it's probably an energy and not a wavelength
+ if float(self.value) < 10:
+ raise Exception("Check sweepmode. Wavelength expected, but probably energy received.")
# Based on the wavelength the grating and the filter will be chosen automatically
self.set_wavelength(self.value)
+
+ elif self.sweep_mode.startswith("Energy"):
+ if float(self.value)>100:
+ self.set_wavelength(self.value)
+ else:
+ # conversion from eV to nm
+ c = 2.99792e8 # speed of light in m/s
+ p = 4.135667e-15 # Planck constant in eV·s
+ wavelength_to_set = round(float(p*c/(float(self.value)))*1e9, 3)
+ self.set_wavelength(wavelength_to_set)
def measure(self):
diff --git a/src/Switch-Acton_FA-448/license.txt b/src/Switch-Acton_FA-448/license.txt
index 74b6c4a2..128b5216 100644
--- a/src/Switch-Acton_FA-448/license.txt
+++ b/src/Switch-Acton_FA-448/license.txt
@@ -5,7 +5,7 @@ find those in the corresponding folders or contact the maintainer.
MIT License
-Copyright (c) 2021 SweepMe! GmbH
+Copyright (c) 2024 SweepMe! GmbH (sweep-me.net)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/src/Switch-Acton_FA-448/main.py b/src/Switch-Acton_FA-448/main.py
index 2c9cf346..f7b0943d 100644
--- a/src/Switch-Acton_FA-448/main.py
+++ b/src/Switch-Acton_FA-448/main.py
@@ -5,7 +5,7 @@
# MIT License
-# Copyright (c) 2021 SweepMe! GmbH
+# Copyright (c) 2024 SweepMe! GmbH (sweep-me.net)
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -27,11 +27,11 @@
# Contribution: We like to thank TU Dresden/Jakob Wolansky for providing the initial version of this driver.
-# SweepMe! device class
-# Type: Switch
-# Device: Acton FA-448
+# SweepMe! driver
+# * Module: Switch
+# * Instrument: Acton FA-448
-from EmptyDeviceClass import EmptyDevice #sweepMe base class
+from pysweepme.EmptyDeviceClass import EmptyDevice
import numpy as np
import time
@@ -39,18 +39,18 @@
class Device(EmptyDevice):
description = """
-
Usage:
-
- - If Sweep mode == "Position", the selected Sweep value is used.
- - If Sweep mode == "Wavelength in nm", the filter is selected in accordance to the 'Filter position'.
- - If Sweep mode == "Energy in eV", the filter is selected in accordance to the 'Filter position'.
- To define custom filter and grating ranges, copy the template file Switch-Acton_FA-448.ini inside this driver folder to the "CustomFiles" folder of your public SweepMe! folder.
- Define your own filter-wavelength dependencies using the format:
- wl -> filter slot <- wl -> filter slot <- wl
- - If Sweep mode == "None", the position given in the field 'Value' is used, if button apply is pressed. It can be used as convenience setting for when no sweep is made (equivalent to one value sweep)
- - If button "Apply" is pressed, the position given in the field 'Value' is set except for Sweep Mode "Energy in eV"
- - Home position: position to return to at end of program ("None" = stay) or after pressing "Stop"
- """
+ Usage:
+
+ - If Sweep mode == "Position", the selected Sweep value is used.
+ - If Sweep mode == "Wavelength in nm", the filter is selected in accordance to the 'Filter position'.
+ - If Sweep mode == "Energy in eV", the filter is selected in accordance to the 'Filter position'.
+ To define custom filter and grating ranges, copy the template file Switch-Acton_FA-448.ini inside this driver folder to the "CustomFiles" folder of your public SweepMe! folder.
+ Define your own filter-wavelength dependencies using the format:
+ wl -> filter slot <- wl -> filter slot <- wl
+ - If Sweep mode == "None", the position given in the field 'Value' is used, if button apply is pressed. It can be used as convenience setting for when no sweep is made (equivalent to one value sweep)
+ - If button "Apply" is pressed, the position given in the field 'Value' is set except for Sweep Mode "Energy in eV"
+ - Home position: position to return to at end of program ("None" = stay) or after pressing "Stop"
+ """
def __init__(self):
@@ -61,14 +61,13 @@ def __init__(self):
self.variables = ["Position"]
self.units = ["#"]
- self.plottype = [True] # True to plot data
- self.savetype = [False] # True to save data
+ self.plottype = [True] # True to plot data
+ self.savetype = [True] # True to save data
# Filter positions
- self.positions = ["1","2","3","4","5","6"]
- # loads from further Filter configurations from Switch-Acton_FA-448.ini that is expected in public folder "CustomFiles"
- self.positions_to_add = list(self.get_configoptions("Filter").values())
-
+ self.positions = ["1", "2", "3", "4", "5", "6"]
+ # loads further filter options from Switch-Acton_FA-448.ini that is expected in public folder "CustomFiles"
+ self.positions_to_add = list(self.getConfigOptions("Filter").values())
self.port_manager = True
self.port_types = ["GPIB", "COM"]
@@ -80,14 +79,14 @@ def __init__(self):
def set_GUIparameter(self):
-
- GUIparameter = {
- "Filter position" : self.positions + self.positions_to_add,
- "Home position" : ["None"] + self.positions,
- "SweepMode": ["Position", "None", "Wavelength in nm", "Energy in eV"],
- }
+ gui_parameter = {
+ "Filter position" : self.positions + self.positions_to_add,
+ "Home position" : ["None"] + self.positions,
+ "SweepMode": ["Position", "None", "Wavelength in nm", "Energy in eV"],
+ "Configuration": "",
+ }
- return GUIparameter
+ return gui_parameter
def get_GUIparameter(self, parameter={}):
@@ -96,11 +95,12 @@ def get_GUIparameter(self, parameter={}):
self.pos = (parameter["Filter position"])
self.filter_readout = self.pos.replace("<", "").replace(">", "").replace("nm", "").replace(" ", "").split("-")
- self.pos_list = np.array(self.filter_readout[::2], dtype = int)
- self.filter_wavelengths = np.array(self.filter_readout[1::2], dtype = float)
+ self.pos_list = np.array(self.filter_readout[::2], dtype=int)
+ self.filter_wavelengths = np.array(self.filter_readout[1::2], dtype=float)
self.home = parameter["Home position"]
-
+
+ self.config = parameter["Configuration"]
def connect(self):
# figure out early whether a connection is established
@@ -111,11 +111,14 @@ def disconnect(self):
pass
def initialize(self):
- ''' set instrument at GUI selected state and ready for next commands'''
+ """Set instrument at GUI selected state and ready for next commands"""
+ if len(self.config) > 1:
+ msg = "Please use a single filter in field 'Configuration' if you choose Set value."
+ raise Exception(msg)
if self.sweepmode == "None":
if len(self.pos_list) > 1:
- self.stop_Measurement("Please use a single filter in field 'Filter position' if Sweep mode is None.")
- return False
+ msg = "Please use a single filter in field 'Filter position' if Sweep mode is None."
+ raise Exception(msg)
def deinitialize(self):
if self.home != "None":
@@ -131,6 +134,8 @@ def deinitialize(self):
"""
self.port.write("FHOME")
self.port.write("?Filter")
+ answer = self.port.read()
+
# set individual home position
self.port.write(str(int(self.home)) + " Filter")
self.port.write("?Filter")
@@ -155,6 +160,8 @@ def unconfigure(self):
"""
self.port.write("FHOME")
self.port.write("?Filter")
+ answer = self.port.read()
+
# set individual home position
self.port.write(str(int(self.home)) + " Filter")
self.port.write("?Filter")
@@ -162,57 +169,69 @@ def unconfigure(self):
def apply(self):
# if set value is not a filter position, return error
- if self.sweepmode != "Wavelength in nm" and self.sweepmode != "Energy in eV" and not str(int(self.value)) in self.positions:
- self.stop_Measurement("Filter position %s not in 1-6 range" % str(int(self.value)))
- return False
+ if (self.sweepmode != "Wavelength in nm" and self.sweepmode != "Energy in eV"
+ and not str(int(self.value)) in self.positions):
+ msg = "Filter position %s not in 1-6 range" % str(int(self.value))
+ raise Exception(msg)
if self.sweepmode == "Position":
self.port.write(str(int(self.value)) + " Filter")
- # for apply case: to confirm the latest command, send "?Filter" command
- self.port.write("?Filter")
- answer = (self.port.read())
+
elif self.sweepmode == "Wavelength in nm":
+ # if self.value is below than 10, it's probably an energy and not a wavelength
+ if self.value < 10:
+ msg = "Check sweepmode. Wavelength expected, but probably energy or position received."
+ raise Exception(msg)
+
# do not send more than three digits after decimal separator
self.wavelength_to_set = round(float(self.value),3)
# Based on the wavelength the filter will be chosen
# 1. step: find the index at which between two wavelengths, the filter has to be changed
# 2. step: find the filter slot based on that index
- filter_to_set = self.pos_list[np.sum(np.array(self.filter_wavelengths, dtype = float) < self.wavelength_to_set)]
- # if apply is pressed and not run, then value in "configuration box" is set, otherwise the filter in accordance to the "filter position box" is set
+ filter_to_set = self.pos_list[np.sum(np.array(self.filter_wavelengths, dtype=float) < self.wavelength_to_set)]
+ # if apply is pressed and not run, then value in "configuration box" is set,
+ # otherwise the filter in accordance to the "filter position box" is set
if self.value in self.positions:
self.port.write(str(int(self.value)) + " Filter")
- self.port.write("?Filter")
- self.port.write("?Filter")
- answer = (self.port.read())
else:
self.port.write(str(int(filter_to_set)) + " Filter")
+
elif self.sweepmode == "Energy in eV":
+ # if self.value is higher than 10, it's probably a wavelength and not an energy
+ if self.value > 10:
+ msg = "Check sweepmode. Energy expected, but probably wavelength received."
+ raise Exception(msg)
# if apply is pressed and not run, then value in "Values" is not set, if "Energy in eV" is selected
# do not send more than three digits after decimal separator
- # change eV into nm
- self.wavelength_to_set = round(float(4.135667e-15*2.99792e8/(float(self.value)*1e-9)),3)
+ # change eV into nm
+ c = 2.99792e8 # speed of light in m/s
+ p = 4.135667e-15 # Planck constant in eV·s
+ self.wavelength_to_set = round(float(p*c/(float(self.value)*1e-9)),3)
# Based on the wavelength the filter will be chosen
# 1. step: find the index at which between two wavelengths, the filter has to be changed
# 2. step: find the filter slot based on that index
filter_to_set = self.pos_list[np.sum(np.array(self.filter_wavelengths, dtype = float) < self.wavelength_to_set)]
self.port.write(str(int(filter_to_set)) + " Filter")
- elif self.sweepmode == "None": #case for set value
+
+ elif self.sweepmode == "None": # case for set value
self.port.write(str(self.value) + " Filter")
- # for apply case: to confirm the latest command, send "?Filter" command
- self.port.write("?Filter")
- answer = (self.port.read())
+
+ # for apply case: to confirm the latest command, send "?Filter" command
+ self.port.write("?Filter")
+ answer = self.port.read()
def reach(self):
# makes sure the new filter is reached before the next measurement is done
self.port.write("?Filter")
- answer = (self.port.read())
+ answer = self.port.read()
def measure(self):
- self.port.write("?Filter") # we ask for the filter in 'measure' and read the result in 'read_result', still necessary after each comment which was sent
+ # we ask for the filter in 'measure' and read the result in 'read_result'
+ self.port.write("?Filter")
def read_result(self):
- self.answer = (self.port.read())
+ self.answer = self.port.read()
def call(self):
return self.answer
diff --git a/src/Switch-Stanford_SR570/license.txt b/src/Switch-Stanford_SR570/license.txt
index bf3e44d6..f4fcdad8 100644
--- a/src/Switch-Stanford_SR570/license.txt
+++ b/src/Switch-Stanford_SR570/license.txt
@@ -5,7 +5,7 @@ find those in the corresponding folders or contact the maintainer.
MIT License
-Copyright (c) 2019-2023 SweepMe! GmbH (sweep-me.net)
+Copyright (c) 2024 SweepMe! GmbH (sweep-me.net)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/src/Switch-Stanford_SR570/main.py b/src/Switch-Stanford_SR570/main.py
index dad2b586..1de9acd6 100644
--- a/src/Switch-Stanford_SR570/main.py
+++ b/src/Switch-Stanford_SR570/main.py
@@ -5,7 +5,7 @@
#
# MIT License
#
-# Copyright (c) 2019-2023 SweepMe! GmbH (sweep-me.net)
+# Copyright (c) 2024 SweepMe! GmbH (sweep-me.net)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -28,19 +28,19 @@
# We like to thank Jakob Wolansky/TU Dresden for contributing to the improvement
# of the driver.
-# SweepMe! device class
-# Type: Switch
-# Device: Stanford SR570
+# SweepMe! driver
+# * Module: Switch
+# * Instrument: Stanford SR570
-from collections import OrderedDict
+from pysweepme.ErrorMessage import error
-from ErrorMessage import error
-
-from EmptyDeviceClass import EmptyDevice
+from pysweepme.EmptyDeviceClass import EmptyDevice
import numpy as np
+import time
+
class Device(EmptyDevice):
def __init__(self):
@@ -51,12 +51,13 @@ def __init__(self):
self.port_manager = True
self.port_types = ["COM"]
- self.port_properties = {"EOL" : "\r\n",
- "timeout": 3,
- "baudrate": 9600,
- "stopbits": 2,
- # "delay": 0.02,
- }
+ self.port_properties = {
+ "EOL": "\r\n",
+ "timeout": 3,
+ "baudrate": 9600,
+ "stopbits": 2,
+ # "delay": 0.02,
+ }
# Text from the manual about the RS-232 communication #
"""
@@ -82,217 +83,217 @@ def __init__(self):
self.savetype = [True, True]
self.sensitivities = {
- "1 pA/V": 0,
- "2 pA/V": 1,
- "5 pA/V": 2,
-
- "10 pA/V": 3,
- "20 pA/V": 4,
- "50 pA/V": 5,
-
- "100 pA/V": 6,
- "200 pA/V": 7,
- "500 pA/V": 8,
-
- "1 nA/V": 9,
- "2 nA/V": 10,
- "5 nA/V": 11,
-
- "10 nA/V": 12,
- "20 nA/V": 13,
- "50 nA/V": 14,
-
- "100 nA/V": 15,
- "200 nA/V": 16,
- "500 nA/V": 17,
-
- "1 µA/V": 18,
- "2 µA/V": 19,
- "5 µA/V": 20,
-
- "10 µA/V": 21,
- "20 µA/V": 22,
- "50 µA/V": 23,
-
- "100 µA/V": 24,
- "200 µA/V": 25,
- "500 µA/V": 26,
-
- "1 mA/V": 27,
- }
+ "1 pA/V": 0,
+ "2 pA/V": 1,
+ "5 pA/V": 2,
+
+ "10 pA/V": 3,
+ "20 pA/V": 4,
+ "50 pA/V": 5,
+
+ "100 pA/V": 6,
+ "200 pA/V": 7,
+ "500 pA/V": 8,
+
+ "1 nA/V": 9,
+ "2 nA/V": 10,
+ "5 nA/V": 11,
+
+ "10 nA/V": 12,
+ "20 nA/V": 13,
+ "50 nA/V": 14,
+
+ "100 nA/V": 15,
+ "200 nA/V": 16,
+ "500 nA/V": 17,
+
+ "1 µA/V": 18,
+ "2 µA/V": 19,
+ "5 µA/V": 20,
+
+ "10 µA/V": 21,
+ "20 µA/V": 22,
+ "50 µA/V": 23,
+
+ "100 µA/V": 24,
+ "200 µA/V": 25,
+ "500 µA/V": 26,
+
+ "1 mA/V": 27,
+ }
self.sentivities_value = {
- "1 pA/V": 1e-12,
- "2 pA/V": 2e-12,
- "5 pA/V": 5e-12,
-
- "10 pA/V": 10e-12,
- "20 pA/V": 20e-12,
- "50 pA/V": 50e-12,
-
- "100 pA/V": 100e-12,
- "200 pA/V": 200e-12,
- "500 pA/V": 500e-12,
-
- "1 nA/V": 1e-9,
- "2 nA/V": 2e-9,
- "5 nA/V": 5e-9,
-
- "10 nA/V": 10e-9,
- "20 nA/V": 20e-9,
- "50 nA/V": 50e-9,
-
- "100 nA/V": 100e-9,
- "200 nA/V": 200e-9,
- "500 nA/V": 500e-9,
-
- "1 µA/V": 1e-6,
- "2 µA/V": 2e-6,
- "5 µA/V": 5e-6,
-
- "10 µA/V": 10e-6,
- "20 µA/V": 20e-6,
- "50 µA/V": 50e-6,
-
- "100 µA/V": 100e-6,
- "200 µA/V": 200e-6,
- "500 µA/V": 500e-6,
-
- "1 mA/V": 1e-3,
- }
+ "1 pA/V": 1e-12,
+ "2 pA/V": 2e-12,
+ "5 pA/V": 5e-12,
+
+ "10 pA/V": 10e-12,
+ "20 pA/V": 20e-12,
+ "50 pA/V": 50e-12,
+
+ "100 pA/V": 100e-12,
+ "200 pA/V": 200e-12,
+ "500 pA/V": 500e-12,
+
+ "1 nA/V": 1e-9,
+ "2 nA/V": 2e-9,
+ "5 nA/V": 5e-9,
+
+ "10 nA/V": 10e-9,
+ "20 nA/V": 20e-9,
+ "50 nA/V": 50e-9,
+
+ "100 nA/V": 100e-9,
+ "200 nA/V": 200e-9,
+ "500 nA/V": 500e-9,
+
+ "1 µA/V": 1e-6,
+ "2 µA/V": 2e-6,
+ "5 µA/V": 5e-6,
+
+ "10 µA/V": 10e-6,
+ "20 µA/V": 20e-6,
+ "50 µA/V": 50e-6,
+
+ "100 µA/V": 100e-6,
+ "200 µA/V": 200e-6,
+ "500 µA/V": 500e-6,
+
+ "1 mA/V": 1e-3,
+ }
self.current_offset = {
- "1 pA": 0,
- "2 pA": 1,
- "5 pA": 2,
-
- "10 pA": 3,
- "20 pA": 4,
- "50 pA": 5,
-
- "100 pA": 6,
- "200 pA": 7,
- "500 pA": 8,
-
- "1 nA": 9,
- "2 nA": 10,
- "5 nA": 11,
-
- "10 nA": 12,
- "20 nA": 13,
- "50 nA": 14,
-
- "100 nA": 15,
- "200 nA": 16,
- "500 nA": 17,
-
- "1 µA": 18,
- "2 µA": 19,
- "5 µA": 20,
-
- "10 µA": 21,
- "20 µA": 22,
- "50 µA": 23,
-
- "100 µA": 24,
- "200 µA": 25,
- "500 µA": 26,
-
- "1 mA": 27,
- "1 mA": 28, # TODO: Is this correct?
- "1 mA": 29, # TODO: Is this correct?
- }
+ "1 pA": 0,
+ "2 pA": 1,
+ "5 pA": 2,
+
+ "10 pA": 3,
+ "20 pA": 4,
+ "50 pA": 5,
+
+ "100 pA": 6,
+ "200 pA": 7,
+ "500 pA": 8,
+
+ "1 nA": 9,
+ "2 nA": 10,
+ "5 nA": 11,
+
+ "10 nA": 12,
+ "20 nA": 13,
+ "50 nA": 14,
+
+ "100 nA": 15,
+ "200 nA": 16,
+ "500 nA": 17,
+
+ "1 µA": 18,
+ "2 µA": 19,
+ "5 µA": 20,
+
+ "10 µA": 21,
+ "20 µA": 22,
+ "50 µA": 23,
+
+ "100 µA": 24,
+ "200 µA": 25,
+ "500 µA": 26,
+
+ "1 mA": 27,
+ "2 mA": 28,
+ "5 mA": 29,
+ }
self.frequencies = {
- "0.03 Hz": 0,
-
- "0.1 Hz": 1,
- "0.3 Hz": 2,
-
- "1 Hz": 3,
- "3 Hz": 4,
-
- "10 Hz": 5,
- "30 Hz": 6,
-
- "100 Hz": 7,
- "300 Hz": 8,
-
- "1 kHz": 9,
- "3 kHz": 10,
-
- "10 kHz": 11,
- "30 kHz": 12,
-
- "100 kHz": 13,
- "300 kHz": 14,
-
- "1 MHz": 15,
- }
+ "0.03 Hz": 0,
+
+ "0.1 Hz": 1,
+ "0.3 Hz": 2,
+
+ "1 Hz": 3,
+ "3 Hz": 4,
+
+ "10 Hz": 5,
+ "30 Hz": 6,
+
+ "100 Hz": 7,
+ "300 Hz": 8,
+
+ "1 kHz": 9,
+ "3 kHz": 10,
+
+ "10 kHz": 11,
+ "30 kHz": 12,
+
+ "100 kHz": 13,
+ "300 kHz": 14,
+
+ "1 MHz": 15,
+ }
self.gain_modes = {
- "Low noise": 0,
- "High bandwidth": 1,
- "Low drift": 2,
- }
+ "Low noise": 0,
+ "High bandwidth": 1,
+ "Low drift": 2,
+ }
self.filters = {
- "6 db highpass": 0,
- "12 db highpass": 1,
- "6 db bandpass": 2,
- "6 db lowpass": 3,
- "12 db lowpass": 4,
- "None" : 5,
- }
+ "6 db highpass": 0,
+ "12 db highpass": 1,
+ "6 db bandpass": 2,
+ "6 db lowpass": 3,
+ "12 db lowpass": 4,
+ "None" : 5,
+ }
# defined but not used at the moment
unit_conversion = {
- " pA/V": "1e-12",
- " nA/V": "1e-9",
- " µA/V": "1e-6",
- " mA/V": "1e-3",
- }
+ " pA/V": "1e-12",
+ " nA/V": "1e-9",
+ " µA/V": "1e-6",
+ " mA/V": "1e-3",
+ }
self.commands = {
- "Negative": 0,
- "Positive": 1,
- }
+ "Negative": 0,
+ "Positive": 1,
+ }
def set_GUIparameter(self):
- gui_parameter = {
- "SweepMode" : ["None", "Sensitivity in A/V", "Voltage in V"],
-
- "Bias voltage:" : None,
- "Use bias voltage": False,
- "Bias voltage -5..+5 [V]": "0.0",
-
- "Input offset current:" : None,
- "Use input offset current" : False,
- "Input offset current sign": ["Negative", "Positive"],
- "Input offset current" : list(self.current_offset.keys()),
- "Input offset uncalibrated": False,
- "Uncalibrated input offset vernier -100..+100 [%]": 0.0,
-
- "Filter:" : None,
- "Filter": list(self.filters.keys()),
- "High pass filter": list(self.frequencies.keys())[0:-4], # only from 0.03 Hz to 10 kHz supported
- "Low pass filter": list(self.frequencies.keys())[::-1],
-
- "Sensitivity:" : None,
- "Sensitivity" : list(self.sensitivities.keys())[::-1],
- "Sensitivity uncalibrated": False,
- "Uncalibrated sensitivity vernier 0..100 [%]": 0,
-
- "Other:" : None,
- "Gain mode": list(self.gain_modes.keys()),
- "Invert signal": False,
- "Blank front-end output": False,
- }
+ gui_parameter = {
+ "SweepMode": ["None", "Sensitivity in A/V", "Voltage in V"],
+
+ "Bias voltage:": None,
+ "Use bias voltage": False,
+ "Bias voltage -5..+5 [V]": "0.0",
+
+ "Input offset current:" : None,
+ "Use input offset current" : False,
+ "Input offset current sign": ["Negative", "Positive"],
+ "Input offset current" : list(self.current_offset.keys()),
+ "Input offset uncalibrated": False,
+ "Uncalibrated input offset vernier -100..+100 [%]": 0.0,
+
+ "Filter:": None,
+ "Filter": list(self.filters.keys()),
+ "High pass filter": list(self.frequencies.keys())[0:-4], # only from 0.03 Hz to 10 kHz supported
+ "Low pass filter": list(self.frequencies.keys())[::-1],
+
+ "Sensitivity:": None,
+ "Sensitivity": list(self.sensitivities.keys())[::-1],
+ "Sensitivity uncalibrated": False,
+ "Uncalibrated sensitivity vernier 0..100 [%]": 0,
+
+ "Other:": None,
+ "Gain mode": list(self.gain_modes.keys()),
+ "Invert signal": False,
+ "Blank front-end output": False,
+ }
return gui_parameter
- def get_GUIparameter(self, parameter = {}):
+ def get_GUIparameter(self, parameter={}):
self.sensitivity = parameter["Sensitivity"]
@@ -340,7 +341,7 @@ def get_GUIparameter(self, parameter = {}):
# self.sweepvalue = parameter["SweepValue"]
def initialize(self):
- self.port.write("*RST") # reset to default settings
+ self.port.write("*RST") # reset to default settings
answer = self.port.read()
def connect(self):
@@ -360,63 +361,97 @@ def configure(self):
answer = self.port.read()
# Sensitivity calibration mode
- self.port.write("SUCM %i" % self.sensitivity_uncalibration) # The manual says: 0 = cal, 1 = uncal. but in reality it switches off with 0 ????
+ # The manual says: 0 = cal, 1 = uncal. but in reality it switches off with 0 ????
+ self.port.write("SUCM %i" % self.sensitivity_uncalibration)
answer = self.port.read()
# Uncalibrated sensitivity vernier
- self.port.write("SUCV %i" % self.uncalibrated_sensitivity_vernier) #[0 ≤ n ≤ 100] (percent of full scale).
+ # [0 ≤ n ≤ 100] (percent of full scale).
+ self.port.write("SUCV %i" % self.uncalibrated_sensitivity_vernier)
answer = self.port.read()
# Input offset current
- self.port.write("IOON %i" % self.use_input_offset_current) # IOON n Turn the input offset current on (n=1) or off (n=0).
+ # IOON n Turn the input offset current on (n=1) or off (n=0).
+ self.port.write("IOON %i" % self.use_input_offset_current)
answer = self.port.read()
# Input offset current
- self.port.write("IOLV %i" % self.current_offset[self.input_offset_current]) # IOLV n Sets the calibrated input offset current level
+ # IOLV n Sets the calibrated input offset current level
+ self.port.write("IOLV %i" % self.current_offset[self.input_offset_current])
answer = self.port.read()
# Uncalibrated input offset vernier
- self.port.write("IOUV %i" % int(round(self.uncalibrated_input_offset*10))) # IOUV n Sets the uncalibrated input offset vernier
+ # IOUV n Sets the uncalibrated input offset vernier
+ self.port.write("IOUV %i" % int(round(self.uncalibrated_input_offset*10)))
answer = self.port.read()
# Input offset current sign
- self.port.write("IOSN %i" % self.commands[self.input_offset_current_sign]) # IOSN n Sets the input offset current sign
+ # IOSN n Sets the input offset current sign
+ self.port.write("IOSN %i" % self.commands[self.input_offset_current_sign])
answer = self.port.read()
# Input offset calibration mode
- self.port.write("IOUC %i" % self.input_offset_uncalibration) # IOUC n Sets the input offset cal mode. 0 = cal, 1 = uncal.
+ # IOUC n Sets the input offset cal mode. 0 = cal, 1 = uncal.
+ self.port.write("IOUC %i" % self.input_offset_uncalibration)
answer = self.port.read()
# Gain mode
- self.port.write("GNMD %i" % self.gain_modes[self.ground_mode]) # Sets the gain mode of the amplifier.
+ # Sets the gain mode of the amplifier.
+ self.port.write("GNMD %i" % self.gain_modes[self.ground_mode])
answer = self.port.read()
# Signal inverted
- self.port.write("INVT %i" % self.signal_inverted) # Sets the signal invert sense. 0=noninverted, 1=inverted.
+ # Sets the signal invert sense. 0=noninverted, 1=inverted.
+ self.port.write("INVT %i" % self.signal_inverted)
answer = self.port.read()
-
+
# Use bias voltage
- self.port.write("BSON %i" % self.use_bias_voltage) # Turn the bias voltage on (n=1) or off (n=0).
+ # Turn the bias voltage on (n=1) or off (n=0).
+ self.port.write("BSON %i" % self.use_bias_voltage)
answer = self.port.read()
# Bias voltage
- self.port.write("BSLV %i" % int(round(self.bias_voltage * 1000))) # Sets the bias voltage level in the range. [-5000 ≤ n ≤ +5000] (-5.000 V to +5.000 V).
+ # Sets the bias voltage level in the range. [-5000 ≤ n ≤ +5000] (-5.000 V to +5.000 V).
+ self.port.write("BSLV %i" % int(round(self.bias_voltage * 1000)))
answer = self.port.read()
# Filter type
- self.port.write("FLTT %i" % self.filters[self.filter]) # FLTT n Sets the filter type
+ # FLTT n Sets the filter type
+ self.port.write("FLTT %i" % self.filters[self.filter])
answer = self.port.read()
# Low pass
- self.port.write("LFRQ %i" % self.frequencies[self.lowpass]) # Sets the value of the lowpass filter
+ # Sets the value of the lowpass filter
+ self.port.write("LFRQ %i" % self.frequencies[self.lowpass])
answer = self.port.read()
# High pass
- self.port.write("HFRQ %i" % self.frequencies[self.highpass]) # Sets the value of the lowpass filter
+ # Sets the value of the lowpass filter
+ self.port.write("HFRQ %i" % self.frequencies[self.highpass])
answer = self.port.read()
# Blank front-end output
- self.port.write("BLNK %i" % self.blank_frontend) # Blanks the front-end output of the amplifier.
+ # Blanks the front-end output of the amplifier.
+ self.port.write("BLNK %i" % self.blank_frontend)
+ answer = self.port.read()
+
+ def reconfigure(self, parameter = {}, keys = []):
+ """
+ function to be overloaded if needed
+
+ if a GUI parameter changes after replacement with global parameters, the device needs to be reconfigure.
+ Default behavior is that all parameters are set again and 'configure' is called.
+ The device class maintainer can redefine/overwrite 'reconfigure' with a more individual procedure.
+ """
+
+ if (parameter["Bias voltage -5..+5 [V]"]) == "":
+ self.bias_voltage = 0
+ else:
+ self.bias_voltage = float(parameter["Bias voltage -5..+5 [V]"])
+
+ # Bias voltage
+ # Sets the bias voltage level in the range. [-5000 ≤ n ≤ +5000] (-5.000 V to +5.000 V).
+ self.port.write("BSLV %i" % int(round(self.bias_voltage * 1000)))
answer = self.port.read()
def apply(self):
@@ -424,13 +459,12 @@ def apply(self):
if self.sweepmode.startswith("Sensitivity"):
conversion = {
- 1e-3: "mA/V",
- 1e-6: "µA/V",
- 1e-9: "nA/V",
- 1e-12: "pA/V",
- }
-
- # print(self.value)
+ 1e-3: "mA/V",
+ 1e-6: "µA/V",
+ 1e-9: "nA/V",
+ 1e-12: "pA/V",
+ }
+
self.value = float(self.value)
for exp_step in list(conversion.keys()):
@@ -457,7 +491,7 @@ def apply(self):
break
self.sensitivity = str(number) + " " + conversion[exp_step]
- # print(sensitivity)
+
self.port.write("SENS %i" % self.sensitivities[self.sensitivity])
answer = self.port.read()
@@ -474,10 +508,10 @@ def apply(self):
self.bias_voltage = self.value
def unconfigure(self):
- self.port.write("ROLD") # Resets the filter capacitors to clear an overload condition.
+ self.port.write("ROLD") # Resets the filter capacitors to clear an overload condition.
answer = self.port.read()
# Turn bias voltage off
- self.port.write("BSON 0") # Turn the bias voltage on (n=1) or off (n=0).
+ self.port.write("BSON 0") # Turn the bias voltage on (n=1) or off (n=0).
def call(self):
if not self.use_bias_voltage: