MultiPyVu 3.5.4__tar.gz → 3.6.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. {multipyvu-3.5.4/src/MultiPyVu.egg-info → multipyvu-3.6.1}/PKG-INFO +22 -28
  2. {multipyvu-3.5.4 → multipyvu-3.6.1}/README.md +19 -4
  3. {multipyvu-3.5.4 → multipyvu-3.6.1}/pyproject.toml +1 -2
  4. {multipyvu-3.5.4 → multipyvu-3.6.1}/setup.py +2 -2
  5. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/CommandChamber.py +9 -9
  6. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/CommandField.py +53 -43
  7. multipyvu-3.6.1/src/MultiPyVu/CommandFieldSetPoints.py +288 -0
  8. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/CommandRotator.py +15 -16
  9. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/CommandSdo.py +3 -3
  10. multipyvu-3.6.1/src/MultiPyVu/CommandTempSetPoints.py +248 -0
  11. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/CommandTemperature.py +26 -23
  12. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/CommandWaitFor.py +75 -9
  13. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/Command_factory.py +60 -1
  14. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/ICommand.py +33 -31
  15. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/MultiVuClient.py +51 -5
  16. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/MultiVuClient_base.py +11 -0
  17. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/SocketMessage.py +0 -1
  18. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/SocketMessageClient.py +7 -0
  19. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/SocketMessageServer.py +1 -1
  20. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/__version.py +1 -1
  21. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/exceptions.py +1 -1
  22. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/project_vars.py +2 -2
  23. {multipyvu-3.5.4 → multipyvu-3.6.1/src/MultiPyVu.egg-info}/PKG-INFO +22 -28
  24. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu.egg-info/SOURCES.txt +2 -0
  25. {multipyvu-3.5.4 → multipyvu-3.6.1}/LICENSE +0 -0
  26. {multipyvu-3.5.4 → multipyvu-3.6.1}/setup.cfg +0 -0
  27. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/BRT.py +0 -0
  28. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/CommandMultiVu.py +0 -0
  29. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/IEventManager.py +0 -0
  30. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/IServer.py +0 -0
  31. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/MultiVuDataFile/MultiVuDataFile.py +0 -0
  32. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/MultiVuDataFile/__init__.py +0 -0
  33. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/MultiVuDataFile/__version.py +0 -0
  34. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/MultiVuDataFile/is_pathname_valid.py +0 -0
  35. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/MultiVuServer.py +0 -0
  36. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/ParseInputs.py +0 -0
  37. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/__init__.py +0 -0
  38. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/__main__.py +0 -0
  39. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/check_windows_esc.py +0 -0
  40. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/font/Play-Bold.ttf +0 -0
  41. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/font/Play-Regular.ttf +0 -0
  42. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/font/__init__.py +0 -0
  43. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/generate_sdo_objects.py +0 -0
  44. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/gui/Controller.py +0 -0
  45. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/gui/IController.py +0 -0
  46. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/gui/IView.py +0 -0
  47. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/gui/ViewFactory.py +0 -0
  48. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/gui/ViewTk.py +0 -0
  49. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/gui/__init__.py +0 -0
  50. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/images/Q.png +0 -0
  51. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/images/QD_logo.jpg +0 -0
  52. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/images/__init__.py +0 -0
  53. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/instrument.py +0 -0
  54. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/logging_config.py +0 -0
  55. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/logging_config.yaml +0 -0
  56. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/scripts/__init__.py +0 -0
  57. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/scripts/helper_scripts.py +0 -0
  58. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/scripts/whats_my_ip_address.cmd +0 -0
  59. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu/sdo_object.py +0 -0
  60. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu.egg-info/dependency_links.txt +0 -0
  61. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu.egg-info/requires.txt +0 -0
  62. {multipyvu-3.5.4 → multipyvu-3.6.1}/src/MultiPyVu.egg-info/top_level.txt +0 -0
@@ -1,41 +1,20 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MultiPyVu
3
- Version: 3.5.4
3
+ Version: 3.6.1
4
4
  Summary: Control MultiVu using Python
5
5
  Author-email: Damon D Jackson <djackson@qdusa.com>
6
6
  Maintainer-email: "Quantum Design, Inc." <apps@qdusa.com>
7
- License: MIT License (MIT)
8
-
9
- Copyright (c) 2023 Quantum Design, Inc
10
-
11
- Permission is hereby granted, free of charge, to any person obtaining a copy
12
- of this software and associated documentation files (the "Software"), to deal
13
- in the Software without restriction, including without limitation the rights
14
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
- copies of the Software, and to permit persons to whom the Software is
16
- furnished to do so, subject to the following conditions:
17
-
18
- The above copyright notice and this permission notice shall be included in all
19
- copies or substantial portions of the Software.
20
-
21
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
- SOFTWARE.
7
+ License-Expression: MIT
28
8
  Project-URL: Quantum Design, https://qdusa.com
29
9
  Project-URL: Pharos, https://www.qdusa.com/register/account/login
30
10
  Keywords: Quantum Design,QD,MultiVu,PPMS,DynaCool,MPMS3,VersaLab,OptiCool
31
11
  Classifier: Programming Language :: Python :: 3
32
- Classifier: License :: OSI Approved :: MIT License
33
12
  Classifier: Operating System :: OS Independent
34
13
  Classifier: Intended Audience :: Science/Research
35
14
  Classifier: Topic :: Scientific/Engineering :: Physics
36
15
  Classifier: Topic :: Scientific/Engineering :: Chemistry
37
16
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
38
- Requires-Python: >=3.9
17
+ Requires-Python: >=3.7
39
18
  Description-Content-Type: text/markdown
40
19
  License-File: LICENSE
41
20
  Requires-Dist: pandas
@@ -82,13 +61,13 @@ The components of MultiPyVu enable access to the set and read the temperature, f
82
61
 
83
62
  ### Module Requirements<a class="anchor" id="requirements"></a>
84
63
  MultiPyVu uses the following modules:
85
- - python version 3.10 or higher
64
+ - python version 3.7 or higher
86
65
  - pywin32 - version 300 or higher.
87
66
  - pandas - data read back from a *.dat* file is a Pandas Dataframe
88
67
  - pillow - supports server gui
89
68
  - pyyaml - supports logging
90
69
 
91
- For the Python 3 distribution Quantum Design recommends [Anaconda](https://www.anaconda.com/products/individual) as it includes most modules needed for this server and other packages useful for scientific computing. This code was built and tested using Python 3.8. If you are not sure which version of Python you are using, from a command prompt type:
70
+ For the Python 3 distribution Quantum Design recommends [Anaconda](https://www.anaconda.com/products/individual) as it includes most modules needed for this server and other packages useful for scientific computing. To find which version of Python is used, from a command prompt type:
92
71
  ```
93
72
  python --version
94
73
  ```
@@ -109,7 +88,8 @@ Remote Connection\example_MVDataFile_VISA.py | Simple example showing how to rou
109
88
  Data Processing\example_save_open_dat.py | Script showing how to save and read a MultiVu *.dat* file into a Pandas DataFrame, then plot with matplotlib.
110
89
  Measuring\example_stabilize.py | Measures the temperature while stabilizing at each temperature.
111
90
  Measuring\example_sweep.py | Measures the temperature while sweeping the temperature.
112
- Options\example_aux_therm.py | Gets the temperature of the auxilary thermometer from the OptiCool.
91
+ Measuring\example_get_setpoints.py | Shows how to get the temperature and magnetic field setpoints.
92
+ Options\example_aux_therm.py | Gets the temperature of the auxiliary thermometer from the OptiCool.
113
93
  Options\example_resistivity_option.py | Demonstrates how to set up the BRT module bridges for resistivity measurements and how to save the data.
114
94
  Options\example_horizontal_rotator.py | Demonstrates how to move the horizontal rotator to a new position.
115
95
  UsefulBatchFiles\whats_my_ip_address.cmd | This batch file script prints out the IP address for the computer, providing an easy way to get the server IP address needed for remote operation. Alternatively, the gui can be used to get the IP address by calling ```python -m MultiPyVu```.
@@ -191,7 +171,7 @@ client.open()
191
171
  client.close_client()
192
172
  # do post-processing once the client has been closed
193
173
  ```
194
- Using the above method could end up with the server hung up because errors need to be correctly accounted for. It is safer to use the Client as a context manager using a with-block.
174
+ Using the above method could end up with the server hung up because errors need to be correctly accounted for. It is safer to use the Client as a context manager using a with-block. In addition, a client object can only connect to the server once. For a second connection, one must instantiate a new client instance.
195
175
 
196
176
  The client can also close the server directly using:
197
177
  ```python
@@ -239,6 +219,10 @@ The <enum_options> mode is set using the client.temperature.approach_mode enum,
239
219
  ```python
240
220
  temperature, status = client.get_temperature()
241
221
  ```
222
+ One can also retrieve the setpoint, rate, and approach mode:
223
+ ```python
224
+ temperature, rate, approach = client.get_temperature_setpoints()
225
+ ```
242
226
 
243
227
  **Field**<a class="anchor" id="field"></a>
244
228
  ```python
@@ -260,6 +244,10 @@ The field and status are read back using:
260
244
  ```python
261
245
  field, status = client.get_field()
262
246
  ```
247
+ One can also retrieve the setpoint, rate, and approach mode:
248
+ ```python
249
+ field, rate, approach, driven = client.get_field_setpoints()
250
+ ```
263
251
 
264
252
  **Chamber**<a class="anchor" id="chamber"></a>
265
253
  ```python
@@ -449,6 +437,12 @@ client = mpv.Client(port=6000)
449
437
  - A log file named QdMultiVu.log shows the traffic between the server and client which can also be useful during troubleshooting.
450
438
 
451
439
  ## Changelog<a class="anchor" id="changelog"></a>
440
+ **3.6.1**
441
+ - August 2025
442
+ - Add commands to get the temperature and field setpoints.
443
+ - Remove dependencies on the distutils module.
444
+ - Minimum python version 3.7
445
+
452
446
  **3.5.4**
453
447
  - June 2025
454
448
  - Add the horizontal rotator option for DynaCool, VersaLab, and PPMS.
@@ -33,13 +33,13 @@ The components of MultiPyVu enable access to the set and read the temperature, f
33
33
 
34
34
  ### Module Requirements<a class="anchor" id="requirements"></a>
35
35
  MultiPyVu uses the following modules:
36
- - python version 3.10 or higher
36
+ - python version 3.7 or higher
37
37
  - pywin32 - version 300 or higher.
38
38
  - pandas - data read back from a *.dat* file is a Pandas Dataframe
39
39
  - pillow - supports server gui
40
40
  - pyyaml - supports logging
41
41
 
42
- For the Python 3 distribution Quantum Design recommends [Anaconda](https://www.anaconda.com/products/individual) as it includes most modules needed for this server and other packages useful for scientific computing. This code was built and tested using Python 3.8. If you are not sure which version of Python you are using, from a command prompt type:
42
+ For the Python 3 distribution Quantum Design recommends [Anaconda](https://www.anaconda.com/products/individual) as it includes most modules needed for this server and other packages useful for scientific computing. To find which version of Python is used, from a command prompt type:
43
43
  ```
44
44
  python --version
45
45
  ```
@@ -60,7 +60,8 @@ Remote Connection\example_MVDataFile_VISA.py | Simple example showing how to rou
60
60
  Data Processing\example_save_open_dat.py | Script showing how to save and read a MultiVu *.dat* file into a Pandas DataFrame, then plot with matplotlib.
61
61
  Measuring\example_stabilize.py | Measures the temperature while stabilizing at each temperature.
62
62
  Measuring\example_sweep.py | Measures the temperature while sweeping the temperature.
63
- Options\example_aux_therm.py | Gets the temperature of the auxilary thermometer from the OptiCool.
63
+ Measuring\example_get_setpoints.py | Shows how to get the temperature and magnetic field setpoints.
64
+ Options\example_aux_therm.py | Gets the temperature of the auxiliary thermometer from the OptiCool.
64
65
  Options\example_resistivity_option.py | Demonstrates how to set up the BRT module bridges for resistivity measurements and how to save the data.
65
66
  Options\example_horizontal_rotator.py | Demonstrates how to move the horizontal rotator to a new position.
66
67
  UsefulBatchFiles\whats_my_ip_address.cmd | This batch file script prints out the IP address for the computer, providing an easy way to get the server IP address needed for remote operation. Alternatively, the gui can be used to get the IP address by calling ```python -m MultiPyVu```.
@@ -142,7 +143,7 @@ client.open()
142
143
  client.close_client()
143
144
  # do post-processing once the client has been closed
144
145
  ```
145
- Using the above method could end up with the server hung up because errors need to be correctly accounted for. It is safer to use the Client as a context manager using a with-block.
146
+ Using the above method could end up with the server hung up because errors need to be correctly accounted for. It is safer to use the Client as a context manager using a with-block. In addition, a client object can only connect to the server once. For a second connection, one must instantiate a new client instance.
146
147
 
147
148
  The client can also close the server directly using:
148
149
  ```python
@@ -190,6 +191,10 @@ The <enum_options> mode is set using the client.temperature.approach_mode enum,
190
191
  ```python
191
192
  temperature, status = client.get_temperature()
192
193
  ```
194
+ One can also retrieve the setpoint, rate, and approach mode:
195
+ ```python
196
+ temperature, rate, approach = client.get_temperature_setpoints()
197
+ ```
193
198
 
194
199
  **Field**<a class="anchor" id="field"></a>
195
200
  ```python
@@ -211,6 +216,10 @@ The field and status are read back using:
211
216
  ```python
212
217
  field, status = client.get_field()
213
218
  ```
219
+ One can also retrieve the setpoint, rate, and approach mode:
220
+ ```python
221
+ field, rate, approach, driven = client.get_field_setpoints()
222
+ ```
214
223
 
215
224
  **Chamber**<a class="anchor" id="chamber"></a>
216
225
  ```python
@@ -400,6 +409,12 @@ client = mpv.Client(port=6000)
400
409
  - A log file named QdMultiVu.log shows the traffic between the server and client which can also be useful during troubleshooting.
401
410
 
402
411
  ## Changelog<a class="anchor" id="changelog"></a>
412
+ **3.6.1**
413
+ - August 2025
414
+ - Add commands to get the temperature and field setpoints.
415
+ - Remove dependencies on the distutils module.
416
+ - Minimum python version 3.7
417
+
403
418
  **3.5.4**
404
419
  - June 2025
405
420
  - Add the horizontal rotator option for DynaCool, VersaLab, and PPMS.
@@ -15,10 +15,9 @@ maintainers = [
15
15
  { name = "Quantum Design, Inc.", email = "apps@qdusa.com" },
16
16
  ]
17
17
  readme = "README.md"
18
- license = {file = "LICENSE"}
18
+ license = "MIT"
19
19
  classifiers = [
20
20
  "Programming Language :: Python :: 3",
21
- "License :: OSI Approved :: MIT License",
22
21
  "Operating System :: OS Independent",
23
22
  "Intended Audience :: Science/Research",
24
23
  "Topic :: Scientific/Engineering :: Physics",
@@ -51,11 +51,11 @@ setup(
51
51
  "logging_config.yaml"
52
52
  ]
53
53
  },
54
- python_requires=">=3.9",
54
+ python_requires=">=3.7",
55
55
  install_requires=[
56
56
  "pandas",
57
57
  "pywin32>=300; platform_system=='Windows'",
58
58
  "pillow",
59
- "pyyaml",
59
+ "pyyaml"
60
60
  ],
61
61
  )
@@ -90,7 +90,7 @@ class CommandChamberBase(ICommand):
90
90
 
91
91
  def convert_result(self, response: Dict[str, str]) -> Tuple:
92
92
  """
93
- Converts the CommandMultiVu response from get_state()
93
+ Converts the CommandMultiVu response from get_state_server()
94
94
  to something usable for the user.
95
95
 
96
96
  Parameters:
@@ -131,7 +131,7 @@ class CommandChamberBase(ICommand):
131
131
  raise NotImplementedError
132
132
 
133
133
  @abstractmethod
134
- def _set_state_imp(self, mode: int) -> Union[str, int]:
134
+ def _set_state_imp(self, mode: modeEnum) -> Union[str, int]:
135
135
  raise NotImplementedError
136
136
 
137
137
  def set_state_server(self, arg_string) -> Union[str, int]:
@@ -148,8 +148,8 @@ class CommandChamberBase(ICommand):
148
148
  for m in modeEnum:
149
149
  err_msg += f'\n\t{m.value}: {m.name}'
150
150
  raise MultiPyVuError(err_msg)
151
- self.state = set_mode
152
- return self._set_state_imp(set_mode)
151
+ self.state = modeEnum(set_mode)
152
+ return self._set_state_imp(self.state)
153
153
 
154
154
  def state_code_dict(self):
155
155
  return STATE_DICT
@@ -195,7 +195,7 @@ class CommandChamberImp(ICommandImp, CommandChamberBase):
195
195
  if self.instrument_name == 'OPTICOOL':
196
196
  err_msg = 'get_chamber() is not available for the OptiCool'
197
197
  raise MultiPyVuError(err_msg)
198
- error = self._mvu.GetChamber(state_variant)
198
+ can_error = self._mvu.GetChamber(state_variant)
199
199
  # On 6/10/25, I found that the PPMS was returning something greater
200
200
  # than 1 with the GetTemperature() command. After talking with Mark,
201
201
  # I have decided to only check for a value greater than 1 for all
@@ -206,7 +206,7 @@ class CommandChamberImp(ICommandImp, CommandChamberBase):
206
206
 
207
207
  return 0.0, self.state
208
208
 
209
- def _set_state_imp(self, mode: int) -> Union[str, int]:
209
+ def _set_state_imp(self, mode: modeEnum) -> Union[str, int]:
210
210
  can_error = self._mvu.SetChamber(mode)
211
211
  self.set_point = mode
212
212
 
@@ -216,7 +216,7 @@ class CommandChamberImp(ICommandImp, CommandChamberBase):
216
216
  else:
217
217
  # returning this string makes CommandMultiVu_base happy
218
218
  return 'Call was successful'
219
- elif can_error > 0:
219
+ elif can_error > 1:
220
220
  raise MultiPyVuError('Error when calling SetChamber()')
221
221
  return can_error
222
222
 
@@ -401,8 +401,8 @@ class CommandChamberSim(CommandChamberBase,
401
401
  raise MultiPyVuError(err_msg)
402
402
  return 0.0, self.state
403
403
 
404
- def _set_state_imp(self, mode: int) -> Union[str, int]:
405
- self.change_thread = self.get_sim_instance()
404
+ def _set_state_imp(self, mode: modeEnum) -> Union[str, int]:
405
+ self.change_thread: SimulateChamberChange = self.get_sim_instance()
406
406
  state_string = STATE_DICT[self.state]
407
407
  self.change_thread.set_params('',
408
408
  mode,
@@ -15,7 +15,7 @@ from typing import Dict, List, Tuple, Union
15
15
  from .check_windows_esc import _check_windows_esc
16
16
  from .exceptions import MultiPyVuError
17
17
  from .ICommand import (ICommand, ICommandImp, ICommandObserverSim,
18
- ISimulateChange, catch_thread_error)
18
+ ISimulateChange, catch_thread_error, floats_equal)
19
19
  from .IEventManager import IObserver
20
20
  from .project_vars import CLOCK_TIME
21
21
 
@@ -72,12 +72,14 @@ class CommandFieldBase(ICommand):
72
72
  _current_val: float = 0.0
73
73
  _rate: float = 1
74
74
  _state: int = 1
75
- _approach: Union[ApproachEnum, int] = ApproachEnum.no_overshoot
76
- _driven = drivenEnum.driven
75
+ _approach: ApproachEnum = ApproachEnum.no_overshoot
76
+ _driven: drivenEnum = drivenEnum.driven
77
77
 
78
78
  def __init__(self, instrument_name: str):
79
79
  super().__init__()
80
80
  self.instrument_name = instrument_name
81
+ self.approach_mode = ApproachEnum
82
+ self.drive_mode = drivenEnum
81
83
 
82
84
  self.units = units
83
85
 
@@ -114,24 +116,24 @@ class CommandFieldBase(ICommand):
114
116
  CommandFieldBase._state = new
115
117
 
116
118
  @property
117
- def approach_mode(self):
119
+ def approach(self) -> ApproachEnum:
118
120
  return CommandFieldBase._approach
119
121
 
120
- @approach_mode.setter
121
- def approach_mode(self, new):
122
+ @approach.setter
123
+ def approach(self, new):
122
124
  CommandFieldBase._approach = new
123
125
 
124
126
  @property
125
- def driven_mode(self) -> drivenEnum:
127
+ def driven(self) -> drivenEnum:
126
128
  return CommandFieldBase._driven
127
129
 
128
- @driven_mode.setter
129
- def driven_mode(self, new: drivenEnum):
130
+ @driven.setter
131
+ def driven(self, new: drivenEnum):
130
132
  CommandFieldBase._driven = new
131
133
 
132
134
  def convert_result(self, response: Dict[str, str]) -> Tuple[float, str]:
133
135
  """
134
- Converts the CommandMultiVu response from get_state()
136
+ Converts the CommandMultiVu response from get_state_server()
135
137
  to something usable for the user.
136
138
 
137
139
  Parameters:
@@ -193,8 +195,8 @@ class CommandFieldBase(ICommand):
193
195
  def _set_state_imp(self,
194
196
  field: float,
195
197
  set_rate_per_sec: float,
196
- set_approach: int,
197
- set_driven: int,
198
+ set_approach: ApproachEnum,
199
+ set_driven: drivenEnum,
198
200
  ) -> Union[str, int]:
199
201
  raise NotImplementedError
200
202
 
@@ -211,26 +213,30 @@ class CommandFieldBase(ICommand):
211
213
  field = float(field)
212
214
  set_rate_per_sec = float(rate)
213
215
  set_approach = int(approach)
214
- set_driven = int(driven)
215
- if set_approach > len(ApproachEnum) - 1:
216
- err_msg = f'The approach, {approach}, is out of bounds. Must be '
217
- err_msg += 'one of the following:'
216
+ set_approach_number = int(approach)
217
+ if set_approach_number > len(ApproachEnum) - 1:
218
+ err_msg = f'The approach, {set_approach_number}, is out of bounds.'
219
+ err_msg += ' Must be one of the following:'
218
220
  for mode in ApproachEnum:
219
- print(f'\n\t{mode.value}: {mode.name}')
221
+ err_msg += f'\n\t{mode.value}: {mode.name}'
220
222
  raise MultiPyVuError(err_msg)
223
+ set_approach = ApproachEnum(set_approach_number)
221
224
 
225
+ set_driven_number = int(driven)
222
226
  if self.instrument_name != 'PPMS':
227
+ set_driven = drivenEnum(set_driven_number)
223
228
  if set_driven == drivenEnum.persistent:
224
229
  err_msg = f'{self.instrument_name} can only drive the magnet '
225
230
  err_msg += 'in driven mode.'
226
231
  raise MultiPyVuError(err_msg)
227
232
  else:
228
- if set_driven > len(drivenEnum) - 1:
229
- err_msg = f'The mode, {driven}, is out of bounds. Must be '
230
- err_msg += 'one of the following:'
233
+ if set_driven_number > len(drivenEnum) - 1:
234
+ err_msg = f'The driven mode, {set_driven_number}, is out of '
235
+ err_msg += 'bounds. Must be one of the following:'
231
236
  for mode in drivenEnum:
232
237
  err_msg += f'\n\t{mode.value}: {mode.name}'
233
238
  raise MultiPyVuError(err_msg)
239
+ set_driven = drivenEnum(set_driven_number)
234
240
  if self.instrument_name == 'VERSALAB':
235
241
  if set_approach == ApproachEnum.no_overshoot:
236
242
  err_msg = f'{self.instrument_name} does not support the '
@@ -266,7 +272,10 @@ class CommandFieldImp(ICommandImp, CommandFieldBase):
266
272
  CommandFieldBase.__init__(self, instrument_name)
267
273
  self._mvu = multivu_win32com
268
274
 
269
- def get_state_server(self, value_variant, state_variant, params=''):
275
+ def get_state_server(self,
276
+ value_variant,
277
+ state_variant,
278
+ params='') -> Tuple[float, int]:
270
279
  """
271
280
  Retrieves information from MultiVu
272
281
 
@@ -297,8 +306,8 @@ class CommandFieldImp(ICommandImp, CommandFieldBase):
297
306
  def _set_state_imp(self,
298
307
  field: float,
299
308
  set_rate_per_sec: float,
300
- set_approach: int,
301
- set_driven: int
309
+ set_approach: ApproachEnum,
310
+ set_driven: drivenEnum
302
311
  ) -> Union[str, int]:
303
312
  can_error = self._mvu.setField(field,
304
313
  set_rate_per_sec,
@@ -307,17 +316,16 @@ class CommandFieldImp(ICommandImp, CommandFieldBase):
307
316
  )
308
317
  self.set_point = field
309
318
  self.rate = set_rate_per_sec
310
- self.approach_mode = set_approach
311
- self.driven_mode = drivenEnum(set_driven)
319
+ self.approach = set_approach
320
+ self.driven = drivenEnum(set_driven)
312
321
 
322
+ if can_error > 1:
323
+ raise MultiPyVuError('Error when calling SetField()')
324
+ # It is odd that sometimes a can_error of 1 is okay. So far I have
325
+ # only seen this behavior with a few flavors.
313
326
  if self.instrument_name in ('PPMS', 'MPMS3'):
314
- if can_error > 1:
315
- raise MultiPyVuError('Error when calling SetField()')
316
- else:
317
327
  # returning this string makes CommandMultiVu_base happy
318
328
  return 'Call was successful'
319
- elif can_error > 0:
320
- raise MultiPyVuError('Error when calling SetField()')
321
329
  return can_error
322
330
 
323
331
  def test(self) -> bool:
@@ -335,12 +343,12 @@ class CommandFieldImp(ICommandImp, CommandFieldBase):
335
343
  steady = False
336
344
  self._get_values()
337
345
  state_name = self.convert_state_dictionary(self.state)
338
- if state_name == 'Holding (driven)' or state_name == 'Stable':
339
- steady = self.floats_equal(self.current_val,
340
- self.set_point,
341
- accept_pct,
342
- abs_tol,
343
- )
346
+ if state_name in ('Holding (driven)', 'Stable'):
347
+ steady = floats_equal(self.current_val,
348
+ self.set_point,
349
+ accept_pct,
350
+ abs_tol,
351
+ )
344
352
  return steady
345
353
 
346
354
 
@@ -434,7 +442,7 @@ class SimulateFieldChange(ISimulateChange):
434
442
 
435
443
  # set state to ramping
436
444
  start_time = time.time()
437
- self.state = STATE_DICT[2]
445
+ self.state = STATE_DICT[6]
438
446
  self.notify_observers(self.current_val, self.state)
439
447
 
440
448
  # simulate the ramp
@@ -500,20 +508,22 @@ class CommandFieldSim(CommandFieldBase,
500
508
  def _set_state_imp(self,
501
509
  field: float,
502
510
  set_rate_per_sec: float,
503
- set_approach: int,
504
- set_driven: int
511
+ set_approach: ApproachEnum,
512
+ set_driven: drivenEnum
505
513
  ) -> Union[str, int]:
506
- self.change_thread = self.get_sim_instance()
514
+ self.change_thread: SimulateFieldChange = self.get_sim_instance()
507
515
  state_string = STATE_DICT[self.state]
508
516
  self.change_thread.set_params(self.current_val,
509
517
  field,
510
518
  set_rate_per_sec,
511
519
  state_string,
512
520
  )
513
- self.set_approach = set_approach
521
+ self.set_point = field
522
+ self.rate = set_rate_per_sec
523
+ self.approach = set_approach
514
524
  self.change_thread.approach = set_approach
515
- self.driven_mode = drivenEnum(set_driven)
516
- self.change_thread.driven_mode = self.driven_mode
525
+ self.driven = set_driven
526
+ self.change_thread.driven_mode = self.driven
517
527
 
518
528
  self.change_thread.subscribe(self)
519
529
  self.change_thread.start()