-
Notifications
You must be signed in to change notification settings - Fork 7
/
pqdinstrument.py
142 lines (126 loc) · 6.09 KB
/
pqdinstrument.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
from .utils import connect_socket, ask_socket, create_instrument, _HOST, _PORT
import socket
class PPMS(object):
'''
Wrapper for talking to the C# library for controlling the Quantum Design PPMS.
Make sure to run QDInstrument_Server.exe on the control PC.
host, port = IP address and port of the control PC.
'''
def __init__(self, host=_HOST, port=_PORT):
super(PPMS, self).__init__()
self._temperature = 300
self._temperature_status = ''
self.temperature_rate = 10
self.temperature_approach = 'FastSettle'
self._field = 0
self._field_status = '' #Charging (6), CoolingSwitch (3), CurrentError (8), Discharging (7), Iterating (5), MagnetFailure (15), MagnetUnknown (0), StableDriven (4), StablePersistent (1), Unused10 (10), Unused11 (11), Unused12 (12), Unused13 (13), Unused14 (14), Unused9 (9), WarmingSwitch (2)
self.field_rate = 100
self.field_approach = 'Linear'
self.field_mode = 'Persistent'
self._position = 0
self.position_approach = 0 # 0 is go to setpoint
self.position_speed = 0 # 0 is fastest, 14 is slowest
self._chamber = ''
self.ins = create_instrument(host, port)
self._temperature_approach_dict = {'FastSettle': self.ins.TemperatureApproach.FastSettle, 'NoOvershoot': self.ins.TemperatureApproach.NoOvershoot}
self._field_approach_dict = {'Linear': self.ins.FieldApproach.Linear, 'NoOvershoot': self.ins.FieldApproach.NoOvershoot, 'Oscillate': self.ins.FieldApproach.Oscillate}
self._field_mode_dict = {'Driven': self.ins.FieldMode.Driven, 'Persistent': self.ins.FieldMode.Persistent}
# Generate getter properties for all the "map" items.
# There is more data accessible by the GetPPMSItem command, if that functionality is desired.
for i in range(20,30): # numbers 20-29
fget = eval('lambda self: self._get_map(%i)' %i)
setattr(PPMS, 'map%i' %i, property(fget=fget, fset=None))
def _get_map(self, map_number):
'''
Get the value of one of the PPMS map items.
Numbers 20-29 are map items.
For more information, see page 2-13 of QD PPMS Software Manual.
'''
ret = self.ins.GetPPMSItem(map_number,0,True)
setattr(self, '_map%i' %map_number, ret[1])
return getattr(self, '_map%i' %map_number)
@property
def temperature(self):
ret = self.ins.GetTemperature(0,0)
self._temperature = ret[1]
self._temperature_status = str(ret[2])
return self._temperature
@temperature.setter
def temperature(self, value):
self.ins.SetTemperature(value, self.temperature_rate, self._temperature_approach_dict[self.temperature_approach])
@property
def temperature_status(self):
self.temperature
return self._temperature_status
@property
def field(self):
ret = self.ins.GetField(0,0)
self._field = ret[1]
self._field_status = str(ret[2])
return self._field
@field.setter
def field(self, value):
self.ins.SetField(value, self.field_rate, self._field_approach_dict[self.field_approach], self._field_mode_dict[self.field_mode])
@property
def field_status(self):
self.field
return self._field_status
@property
def chamber(self):
self._chamber = str(self.ins.GetChamber(0)[1])
return self._chamber
@property
def position(self):
ret = self.ins.GetPPMSItem(3,0,True)
self._position = ret[1]
return self._position
@position.setter
def position(self,angle):
if self.position_speed>14 :
self.position_speed = 14
if self.position_speed < 0 :
self.position_speed = 0
commandstring = 'MOVE '+str(angle)+' 0 '+ str(self.position_speed)
self.ins.SendPPMSCommand(commandstring,"","",0,0)
class RemotePPMS(object):
'''
For remote operation of the Quantum Design PPMS.
Make sure to run PyQDInstrument.run_server() in an IronPython console on a machine that can connect to the PPMS control PC's QDInstrument_Server.exe program.
Attributes represent the system control parameters:
'temperature', 'temperature_rate', 'temperature_approach', 'field', 'field_rate', 'field_approach', 'field_mode', 'temperature_status', 'field_status', 'chamber',
'position', 'position_speed'
'''
def __init__(self, host, port, s=None, name='ppms'):
self._name = name
if s == None:
self._s = connect_socket(host, port)
else:
self._s = s
for param in ['temperature', 'temperature_rate', 'field', 'field_rate', 'temperature_approach', 'field_approach', 'field_mode', 'position', 'position_speed']:
setattr(RemotePPMS,param,property(fget=eval("lambda self: self._get_param('%s')" %param),
fset=eval("lambda self, value: self._set_param('%s',value)" %param)))
for param in ['temperature_status', 'field_status', 'chamber']:
setattr(RemotePPMS,param,property(fget=eval("lambda self: self._get_param('%s')" %param)))
self._params = ['temperature', 'temperature_rate', 'temperature_approach', 'field', 'field_rate', 'field_approach', 'field_mode', 'position', 'position_speed', 'temperature_status', 'field_status', 'chamber']
def _get_param(self, param):
return ask_socket(self._s, param)
def _set_param(self, param, value):
if type(value) == str:
cmd = "%s = '%s'" %(param, value)
else:
cmd = '%s = %s' %(param, value)
return ask_socket(self._s, cmd)
def _repr_html_(self):
'''
Show a pretty HTML representation of the object for ipynb.
'''
html = ["<b>",self._name,"</b> - "]
html.append(self.__doc__)
html.append("<table width=100%>")
for key in self._params:
html.append("<tr>")
html.append("<td>{0}</td>".format(key))
html.append("<td>{0}</td>".format(getattr(self,key)))
html.append("</tr>")
html.append("</table>")
return ''.join(html)