pychemstation 0.4.7.dev1__py3-none-any.whl → 0.4.7.dev3__py3-none-any.whl

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 (104) hide show
  1. pychemstation/control/__init__.py +3 -2
  2. hein-analytical-control/devices/Agilent/hplc.py → pychemstation/control/comm.py +21 -181
  3. pychemstation/control/method.py +232 -0
  4. pychemstation/control/sequence.py +140 -0
  5. pychemstation/control/table_controller.py +75 -0
  6. pychemstation/utils/__init__.py +0 -2
  7. {ag_hplc_macro/control → pychemstation/utils}/chromatogram.py +2 -1
  8. pychemstation/utils/constants.py +1 -1
  9. hein_analytical_control/devices/Agilent/hplc_param_types.py → pychemstation/utils/macro.py +5 -69
  10. pychemstation/utils/method_types.py +44 -0
  11. pychemstation/utils/sequence_types.py +33 -0
  12. pychemstation/utils/table_types.py +60 -0
  13. {pychemstation-0.4.7.dev1.dist-info → pychemstation-0.4.7.dev3.dist-info}/METADATA +13 -12
  14. pychemstation-0.4.7.dev3.dist-info/RECORD +30 -0
  15. ag_hplc_macro/__init__.py +0 -3
  16. ag_hplc_macro/analysis/__init__.py +0 -1
  17. ag_hplc_macro/analysis/base_spectrum.py +0 -509
  18. ag_hplc_macro/analysis/spec_utils.py +0 -304
  19. ag_hplc_macro/analysis/utils.py +0 -63
  20. ag_hplc_macro/control/__init__.py +0 -5
  21. ag_hplc_macro/control/hplc.py +0 -673
  22. ag_hplc_macro/generated/__init__.py +0 -56
  23. ag_hplc_macro/generated/dad_method.py +0 -367
  24. ag_hplc_macro/generated/pump_method.py +0 -519
  25. ag_hplc_macro/utils/__init__.py +0 -2
  26. ag_hplc_macro/utils/constants.py +0 -15
  27. ag_hplc_macro/utils/hplc_param_types.py +0 -185
  28. hein-analytical-control/__init__.py +0 -3
  29. hein-analytical-control/analysis/__init__.py +0 -1
  30. hein-analytical-control/analysis/base_spectrum.py +0 -509
  31. hein-analytical-control/analysis/spec_utils.py +0 -304
  32. hein-analytical-control/analysis/utils.py +0 -63
  33. hein-analytical-control/devices/Agilent/__init__.py +0 -3
  34. hein-analytical-control/devices/Agilent/chemstation.py +0 -290
  35. hein-analytical-control/devices/Agilent/chromatogram.py +0 -129
  36. hein-analytical-control/devices/Agilent/hplc_param_types.py +0 -141
  37. hein-analytical-control/devices/Magritek/Spinsolve/__init__.py +0 -0
  38. hein-analytical-control/devices/Magritek/Spinsolve/commands.py +0 -495
  39. hein-analytical-control/devices/Magritek/Spinsolve/spectrum.py +0 -822
  40. hein-analytical-control/devices/Magritek/Spinsolve/spinsolve.py +0 -425
  41. hein-analytical-control/devices/Magritek/Spinsolve/utils/__init__.py +0 -5
  42. hein-analytical-control/devices/Magritek/Spinsolve/utils/connection.py +0 -168
  43. hein-analytical-control/devices/Magritek/Spinsolve/utils/constants.py +0 -8
  44. hein-analytical-control/devices/Magritek/Spinsolve/utils/exceptions.py +0 -25
  45. hein-analytical-control/devices/Magritek/Spinsolve/utils/parser.py +0 -340
  46. hein-analytical-control/devices/Magritek/Spinsolve/utils/shimming.py +0 -55
  47. hein-analytical-control/devices/Magritek/Spinsolve/utils/spinsolve_logging.py +0 -43
  48. hein-analytical-control/devices/Magritek/__init__.py +0 -0
  49. hein-analytical-control/devices/OceanOptics/IR/NIRQuest512.py +0 -90
  50. hein-analytical-control/devices/OceanOptics/IR/__init__.py +0 -0
  51. hein-analytical-control/devices/OceanOptics/IR/ir_spectrum.py +0 -191
  52. hein-analytical-control/devices/OceanOptics/Raman/__init__.py +0 -0
  53. hein-analytical-control/devices/OceanOptics/Raman/raman_control.py +0 -46
  54. hein-analytical-control/devices/OceanOptics/Raman/raman_spectrum.py +0 -148
  55. hein-analytical-control/devices/OceanOptics/UV/QEPro2192.py +0 -90
  56. hein-analytical-control/devices/OceanOptics/UV/__init__.py +0 -0
  57. hein-analytical-control/devices/OceanOptics/UV/uv_spectrum.py +0 -227
  58. hein-analytical-control/devices/OceanOptics/__init__.py +0 -0
  59. hein-analytical-control/devices/OceanOptics/oceanoptics.py +0 -115
  60. hein-analytical-control/devices/__init__.py +0 -15
  61. hein-analytical-control/generated/__init__.py +0 -56
  62. hein-analytical-control/generated/dad_method.py +0 -367
  63. hein-analytical-control/generated/pump_method.py +0 -519
  64. hein_analytical_control/__init__.py +0 -3
  65. hein_analytical_control/analysis/__init__.py +0 -1
  66. hein_analytical_control/analysis/base_spectrum.py +0 -509
  67. hein_analytical_control/analysis/spec_utils.py +0 -304
  68. hein_analytical_control/analysis/utils.py +0 -63
  69. hein_analytical_control/devices/Agilent/__init__.py +0 -3
  70. hein_analytical_control/devices/Agilent/chemstation.py +0 -290
  71. hein_analytical_control/devices/Agilent/chromatogram.py +0 -129
  72. hein_analytical_control/devices/Agilent/hplc.py +0 -436
  73. hein_analytical_control/devices/Magritek/Spinsolve/__init__.py +0 -0
  74. hein_analytical_control/devices/Magritek/Spinsolve/commands.py +0 -495
  75. hein_analytical_control/devices/Magritek/Spinsolve/spectrum.py +0 -822
  76. hein_analytical_control/devices/Magritek/Spinsolve/spinsolve.py +0 -425
  77. hein_analytical_control/devices/Magritek/Spinsolve/utils/__init__.py +0 -5
  78. hein_analytical_control/devices/Magritek/Spinsolve/utils/connection.py +0 -168
  79. hein_analytical_control/devices/Magritek/Spinsolve/utils/constants.py +0 -8
  80. hein_analytical_control/devices/Magritek/Spinsolve/utils/exceptions.py +0 -25
  81. hein_analytical_control/devices/Magritek/Spinsolve/utils/parser.py +0 -340
  82. hein_analytical_control/devices/Magritek/Spinsolve/utils/shimming.py +0 -55
  83. hein_analytical_control/devices/Magritek/Spinsolve/utils/spinsolve_logging.py +0 -43
  84. hein_analytical_control/devices/Magritek/__init__.py +0 -0
  85. hein_analytical_control/devices/OceanOptics/IR/NIRQuest512.py +0 -90
  86. hein_analytical_control/devices/OceanOptics/IR/__init__.py +0 -0
  87. hein_analytical_control/devices/OceanOptics/IR/ir_spectrum.py +0 -191
  88. hein_analytical_control/devices/OceanOptics/Raman/__init__.py +0 -0
  89. hein_analytical_control/devices/OceanOptics/Raman/raman_control.py +0 -46
  90. hein_analytical_control/devices/OceanOptics/Raman/raman_spectrum.py +0 -148
  91. hein_analytical_control/devices/OceanOptics/UV/QEPro2192.py +0 -90
  92. hein_analytical_control/devices/OceanOptics/UV/__init__.py +0 -0
  93. hein_analytical_control/devices/OceanOptics/UV/uv_spectrum.py +0 -227
  94. hein_analytical_control/devices/OceanOptics/__init__.py +0 -0
  95. hein_analytical_control/devices/OceanOptics/oceanoptics.py +0 -115
  96. hein_analytical_control/devices/__init__.py +0 -15
  97. hein_analytical_control/generated/__init__.py +0 -56
  98. hein_analytical_control/generated/dad_method.py +0 -367
  99. hein_analytical_control/generated/pump_method.py +0 -519
  100. pychemstation-0.4.7.dev1.dist-info/RECORD +0 -109
  101. /ag_hplc_macro/utils/chemstation.py → /pychemstation/utils/parsing.py +0 -0
  102. {pychemstation-0.4.7.dev1.dist-info → pychemstation-0.4.7.dev3.dist-info}/LICENSE +0 -0
  103. {pychemstation-0.4.7.dev1.dist-info → pychemstation-0.4.7.dev3.dist-info}/WHEEL +0 -0
  104. {pychemstation-0.4.7.dev1.dist-info → pychemstation-0.4.7.dev3.dist-info}/top_level.txt +0 -0
@@ -1,340 +0,0 @@
1
- """
2
- Python module to parse the xml messages received from Spinsolve NMR.
3
- """
4
- import logging
5
-
6
- import xml.etree.ElementTree as ET
7
- from xml.etree.ElementTree import ParseError
8
-
9
- from .exceptions import RequestError, HardwareError, ShimmingError, NMRError
10
- from .constants import (
11
- CURRENT_SPINSOLVE_VERSION,
12
- USER_DATA_TAG,
13
- )
14
-
15
-
16
- class ReplyParser:
17
- """Parses usefull information from the xml reply"""
18
-
19
- ### Response tags for easier handling ###
20
- HARDWARE_RESPONSE_TAG = "HardwareResponse"
21
- AVAILABLE_PROTOCOL_OPTIONS_RESPONSE_TAG = "AvailableProtocolOptionsResponse"
22
- STATUS_TAG = "StatusNotification"
23
- ESTIMATE_DURATION_RESPONSE_TAG = "EstimateDurationResponse"
24
- CHECK_SHIM_RESPONSE_TAG = "CheckShimResponse"
25
- QUICK_SHIM_RESPONSE_TAG = "QuickShimResponse"
26
- POWER_SHIM_RESPONSE_TAG = "PowerShimResponse"
27
- COMPLETED_NOTIFICATION_TAG = "CompletedNotificationType"
28
- GET_RESPONSE_TAG = "GetResponse"
29
-
30
- def __init__(self, device_ready_flag, data_folder_queue):
31
- """
32
- Args:
33
- device_ready_flag (:obj: "threading.Event"): The threading event indicating
34
- that the instrument is ready for the next commands
35
- data_folder_queue (:obj: "queue.Queue"): A queue object to store the data folder information
36
- for subsequent access with Spectrum class
37
- """
38
-
39
- self.device_ready_flag = device_ready_flag
40
- self.data_folder_queue = data_folder_queue
41
- self.connected_tag = None # String to indicate if the instrument is connected, updated with HardwareRequest
42
-
43
- self.logger = logging.getLogger("spinsolve.parser")
44
-
45
- # For shimming validation
46
- self.shimming_line_width_threshold = 1
47
- self.shimming_base_width_threshold = 40
48
-
49
- def parse(self, message):
50
- """Parses the message into valuable XML element
51
-
52
- Depending on the element tag, invokes various parsing methods
53
-
54
- Args:
55
- message (bytes): The message received from the instrument
56
- """
57
-
58
- self.logger.debug("Obtained the message: \n%s", message)
59
-
60
- # Checking the obtained message
61
- try:
62
- msg_root = ET.fromstring(message)
63
- except ParseError:
64
- self.logger.error(
65
- "ParseError: invalid XML message received, check the full message \n <%s>",
66
- message.decode(),
67
- )
68
- raise ParseError(
69
- "Invalid XML message received from the instrument, please check the log for the full message"
70
- ) from None
71
- if msg_root.tag != "Message" or len(msg_root) > 1:
72
- self.logger.error(
73
- "ParseError: incorrect message received, check the full message \n <%s>",
74
- message.decode(),
75
- )
76
- raise ParseError(
77
- "Incorrect message received from the instrument, please check the log for the full message"
78
- )
79
-
80
- # Main message element
81
- msg_element = msg_root[0]
82
-
83
- # Invoking specific methods for specific responds
84
- if msg_element.tag == self.HARDWARE_RESPONSE_TAG:
85
- return self.hardware_processing(msg_element)
86
- elif msg_element.tag == self.AVAILABLE_PROTOCOL_OPTIONS_RESPONSE_TAG:
87
- return message
88
- elif msg_element.tag in [
89
- self.CHECK_SHIM_RESPONSE_TAG,
90
- self.QUICK_SHIM_RESPONSE_TAG,
91
- self.POWER_SHIM_RESPONSE_TAG,
92
- ]:
93
- return self.shimming_processing(msg_element)
94
- elif (
95
- msg_element.tag == self.STATUS_TAG
96
- or msg_element.tag == self.COMPLETED_NOTIFICATION_TAG
97
- ):
98
- return self.status_processing(msg_element)
99
- elif msg_element.tag == self.ESTIMATE_DURATION_RESPONSE_TAG:
100
- return self.estimate_duration_processing(msg_element)
101
- elif msg_element.tag == self.GET_RESPONSE_TAG:
102
- return self.data_response_processing(msg_element)
103
- else:
104
- self.logger.info(
105
- "No specific parser requested, returning full decoded message"
106
- )
107
- return message.decode()
108
-
109
- def hardware_processing(self, element):
110
- """Process the message if the Hardware tag is present
111
-
112
- Args:
113
- element (:obj: xml.etree.ElementTree.Element): An element containing all
114
- usefull information regarding Hardware response from the instrument
115
-
116
- Returns:
117
- dict: Dictionary with usefull hardware information
118
-
119
- Raises:
120
- HardwareError: In case the instrument is not connected
121
- """
122
-
123
- # Checking if the instrument is physically connected
124
- self.logger.debug("Parsing message with <%s> tag", element.tag)
125
- self.connected_tag = element.find(".//ConnectedToHardware").text
126
- if self.connected_tag == "false":
127
- raise HardwareError("The instrument is not connected!")
128
-
129
- software_tag = element.find(".//SpinsolveSoftware").text
130
-
131
- spinsolve_tag = element.find(".//SpinsolveType").text
132
-
133
- self.logger.info(
134
- "The %s NMR instrument is successfully connected \nRunning under %s Spinsolve software version",
135
- spinsolve_tag,
136
- software_tag,
137
- )
138
- if software_tag[:6] != CURRENT_SPINSOLVE_VERSION:
139
- self.logger.warning(
140
- "The current software version <%s> was not tested, please update or use at your own risk",
141
- software_tag,
142
- )
143
-
144
- # If the instrument is connected, setting the ready flag
145
- self.device_ready_flag.set()
146
-
147
- usefull_information_dict = {
148
- "Connected": f"{self.connected_tag}",
149
- "SoftwareVersion": f"{software_tag}",
150
- "InstrumentType": f"{spinsolve_tag}",
151
- }
152
-
153
- return usefull_information_dict
154
-
155
- def data_response_processing(self, element):
156
- """Process the message if the user parameters response is present.
157
-
158
- Args:
159
- element (:obj: xml.etree.ElementTree.Element): An element containing
160
- all usefull information regarding Hardware response from the
161
- instrument.
162
-
163
- Returns:
164
- Dict: Dictionary with user/experiment specific parameter, e.g.
165
- userdata, solvent or sample.
166
- """
167
-
168
- self.logger.debug("Parsing message with <%s> tag", element.tag)
169
- # messages with GetResponse have only one child
170
- if len(element) > 1:
171
- raise RequestError(
172
- "Returned response for user data is incorrect, \
173
- check log files for details!"
174
- )
175
-
176
- chelement = element[0]
177
-
178
- # special case for user data
179
- if chelement.tag == USER_DATA_TAG:
180
- return {
181
- subel.attrib["key"]: subel.attrib["value"]
182
- for subel in chelement # iterating over subelements
183
- }
184
-
185
- return chelement.text
186
-
187
- def shimming_processing(self, element):
188
- """Process the message if the Shim tag is present
189
-
190
- Args:
191
- element (:obj: xml.etree.ElementTree.Element): An element containing all
192
- usefull information regarding shimming response from the instrument
193
-
194
- Returns:
195
- True if shimming was successfull
196
-
197
- Raises:
198
- ShimmingError: If the shimming process failed
199
- """
200
-
201
- self.logger.debug("Parsing message with <%s> tag", element.tag)
202
-
203
- self.device_ready_flag.set()
204
-
205
- error_text = element.get("error")
206
- if error_text:
207
- self.logger.error(
208
- "ShimmingError: check the error message below\
209
- \n%s",
210
- error_text,
211
- )
212
- if (
213
- self.shimming_base_width_threshold == 40
214
- and self.shimming_line_width_threshold == 1
215
- ):
216
- # only raise error if default line widths were used as the
217
- # reference point
218
- raise ShimmingError(f"Shimming error: {error_text}")
219
-
220
- for child in element:
221
- self.logger.info("%s - %s", child.tag, child.text)
222
-
223
- # Obtaining shimming parameters
224
- line_width = round(float(element.find(".//LineWidth").text), 2)
225
- base_width = round(float(element.find(".//BaseWidth").text), 2)
226
- system_ready = element.find(".//SystemIsReady").text
227
-
228
- # Checking shimming criteria
229
- if line_width > self.shimming_line_width_threshold:
230
- self.logger.critical(
231
- "Shimming line width <%.2f> is above requested threshold <%.2f>, consider running another shimming method",
232
- line_width,
233
- self.shimming_line_width_threshold,
234
- )
235
- if base_width > self.shimming_base_width_threshold:
236
- self.logger.critical(
237
- "Shimming line width <%.2f> is above requested threshold <%.2f>, consider running another shimming method",
238
- line_width,
239
- self.shimming_line_width_threshold,
240
- )
241
- if system_ready != "true":
242
- self.logger.critical(
243
- "System is not ready after shimming, consider running another shimming method"
244
- )
245
- return False
246
- else:
247
- return True
248
-
249
- def status_processing(self, element):
250
- """Process the message if the Status tag is present
251
-
252
- Logs the incoming messages and manages device_ready_flag
253
-
254
- Args:
255
- element (:obj: xml.etree.ElementTree.Element): An element containing all
256
- usefull information regarding status response from the instrument
257
-
258
- Returns:
259
- str: String containing the path to the saved NMR data
260
-
261
- Raises:
262
- NMRError: in case of the protocol errors
263
- """
264
-
265
- self.logger.debug("Parsing message with <%s> tag", element.tag)
266
-
267
- # Valuable data from the message
268
- state_tag = element[0].tag
269
- state_elem = element[0]
270
- protocol_attrib = state_elem.get("protocol")
271
-
272
- # Checking for errors first
273
- error_attrib = state_elem.get("error")
274
-
275
- # No error is actually raised, since the instrument
276
- # Continues with protocol execution even if an error was returned
277
- # TODO add an option to handle the error and stop the execution
278
- if error_attrib:
279
- self.logger.error(
280
- "NMRError: <%s>, check the log for the full message", error_attrib
281
- )
282
- # raise NMRError(f"Error running the protocol <{protocol_attrib}>: {error_attrib}")
283
-
284
- status_attrib = state_elem.get("status")
285
- percentage_attrib = state_elem.get("percentage")
286
- seconds_remaining_attrib = state_elem.get("secondsRemaining")
287
-
288
- # Logging the data
289
- if state_tag == "State":
290
- # Resetting the event to False to block the incoming msg
291
- if status_attrib == "Running":
292
- self.logger.debug("Device in operation, blocking the incoming messages")
293
- self.device_ready_flag.clear()
294
- self.logger.info("%s the <%s> protocol", status_attrib, protocol_attrib)
295
- if status_attrib == "Ready":
296
- # When device is ready, setting the event to True for the next protocol to be executed
297
- # Delay the flag setting for the SHIM protocol
298
- if protocol_attrib != "SHIM":
299
- self.device_ready_flag.set()
300
- data_folder = state_elem.get("dataFolder")
301
- self.logger.info(
302
- "The protocol <%s> is complete, the NMR data is saved in <%s>",
303
- protocol_attrib,
304
- data_folder,
305
- )
306
- self.data_folder_queue.put(data_folder)
307
- return data_folder
308
-
309
- if state_tag == "Progress":
310
- self.logger.info(
311
- "The protocol <%s> is performing, %s%% completed, %s seconds remain",
312
- protocol_attrib,
313
- percentage_attrib,
314
- seconds_remaining_attrib,
315
- )
316
-
317
- def estimate_duration_processing(self, element):
318
- """Process the message if protocol duration was requested
319
-
320
- Args:
321
- element (:obj: xml.etree.ElementTree.Element): An element containing all
322
- usefull information regarding duration estimation from the instrument
323
-
324
- Returns:
325
- int: Estimated duration for the requested protocol in seconds
326
-
327
- Raises:
328
- RequestError: In case the instrument returns an error attribute
329
- """
330
-
331
- self.logger.debug("Parsing message with <%s> tag", element.tag)
332
-
333
- error_text = element.get("error")
334
- if error_text:
335
- self.logger.error("RequestError: check the log for the full message")
336
- raise RequestError(f"Duration request error: {error_text}")
337
-
338
- duration_in_seconds = element.get("durationInSeconds")
339
-
340
- return int(duration_in_seconds)
@@ -1,55 +0,0 @@
1
- """
2
- Utility function to record last shimming results
3
- """
4
- import time
5
- import os
6
- import json
7
- import queue
8
- from functools import wraps
9
-
10
-
11
- HERE = os.path.dirname(os.path.abspath(__file__))
12
- SHIMMING_PARAMETERS = "shim.par"
13
- TIME_FORMAT = r"%Y-%m-%dT%H:%M:%S.%f"
14
-
15
-
16
- def shimming(f):
17
- """Decorator to record shimming data."""
18
-
19
- @wraps(f)
20
- def wrapper(*args, **kwargs):
21
- spinsolve_instance = args[0]
22
-
23
- # performing shimming
24
- result = f(*args, **kwargs)
25
- params_path = os.path.join(result, SHIMMING_PARAMETERS)
26
-
27
- # extracting and saving shimming parameters
28
- spinsolve_instance.last_shimming_results = (
29
- spinsolve_instance.spectrum.extract_parameters(params_path)
30
- )
31
-
32
- # appending path
33
- spinsolve_instance.last_shimming_results.update(path=params_path)
34
-
35
- # loading and saving timestamp
36
- shimming_time = time.strptime(
37
- spinsolve_instance.last_shimming_results["CurrentTime"], TIME_FORMAT
38
- )
39
- spinsolve_instance.last_shimming_results.update(
40
- timestamp=time.mktime(shimming_time)
41
- )
42
-
43
- # emptying data folder queue, as shimming doesn't need processing
44
- try:
45
- spinsolve_instance.data_folder_queue.get_nowait()
46
- except queue.Empty:
47
- pass
48
-
49
- # saving to json
50
- with open(os.path.join(HERE, "shimming.json"), "w") as fobj:
51
- json.dump(spinsolve_instance.last_shimming_results, fobj)
52
-
53
- return result
54
-
55
- return wrapper
@@ -1,43 +0,0 @@
1
- import logging
2
- from logging.handlers import RotatingFileHandler
3
- import os
4
- from datetime import datetime
5
-
6
-
7
- now = datetime.now().strftime("%d%m%y")
8
-
9
- LEVEL = logging.INFO
10
- HERE = os.path.abspath(".")
11
- LOG_PATH = os.path.join(HERE, "spinsolve_logs")
12
- NAME = "spinsolve"
13
- MAX_BYTES_SIZE = 3 * 1000 * 1000 # 2 MB is enough to store ~30 spectra records
14
- BACKUP_COUNT = 5 # will give in total logs for ~150 spectra records
15
-
16
-
17
- def get_logger():
18
- """Returns logger object with predefined console and file handlers."""
19
-
20
- logger = logging.getLogger(NAME)
21
- logger.setLevel(logging.DEBUG)
22
- logger.handlers = [] # resetting
23
-
24
- ff = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
25
-
26
- # console handler
27
- ch = logging.StreamHandler()
28
- ch.setLevel(LEVEL)
29
- ch.setFormatter(ff)
30
-
31
- # file handler
32
- os.makedirs(LOG_PATH, exist_ok=True)
33
- file_path = os.path.join(LOG_PATH, f"{NAME}-{now}.log")
34
- fh = RotatingFileHandler(
35
- filename=file_path, mode="a", maxBytes=MAX_BYTES_SIZE, backupCount=BACKUP_COUNT
36
- )
37
- fh.setLevel(logging.DEBUG)
38
- fh.setFormatter(ff)
39
-
40
- logger.addHandler(ch)
41
- logger.addHandler(fh)
42
-
43
- return logger
File without changes
@@ -1,90 +0,0 @@
1
- """
2
- .. module:: NIRQuest512
3
- :synopsis: Module representing the NIRQUest512 Near-IR spectrometer
4
- :platforms: Unix, Windows
5
-
6
- .. moduleauthor:: Graham Keenan (Cronin Lab 2020)
7
-
8
- .. note:: Edit as needed. This is a skeletal implementation for minimal
9
- functionality.
10
-
11
- """
12
-
13
- import json
14
- from pathlib import Path
15
- from typing import Union, Dict
16
- from .ir_spectrum import IRSpectrum
17
- from ..oceanoptics import OceanOpticsSpectrometer
18
-
19
-
20
- class NoReferenceException(Exception):
21
- """Exception for calling spectrum without a reference"""
22
-
23
-
24
- class NIRQuest512(OceanOpticsSpectrometer):
25
- """Class representing the NIRQuest512 Near-IR spectrometer
26
-
27
- Inherits:
28
- OceanOpticsSpectrometer
29
- """
30
-
31
- def __init__(self):
32
- super().__init__("IR", name="NIRQuest512 IR Spectrometer")
33
- self.reference = {}
34
- self.__ref_called = False
35
-
36
- def load_reference(self, ref: Union[str, Dict]):
37
- """Loads a pre-existing reference from disk or from dict.
38
-
39
- Args:
40
- ref (Union[str, Dict]): Reference as either a dictionary
41
- or JSON filepath
42
- """
43
-
44
- # Filepath, load and set
45
- if isinstance(ref, str) or isinstance(ref, Path):
46
- with open(ref) as fd:
47
- self.reference = json.load(fd)
48
- self.__ref_called = True
49
-
50
- # Dict, set
51
- elif isinstance(ref, dict):
52
- self.reference = ref
53
- self.__ref_called = True
54
-
55
- # Not supported
56
- else:
57
- self.logger.warning(f"Reference {ref} is unsupported. Not loading")
58
-
59
- def obtain_reference_spectrum(self) -> IRSpectrum:
60
- """Obtain a reference spectrum
61
-
62
- Returns:
63
- IRSpectrum: Reference IR spectrum
64
- """
65
-
66
- wavelength, intensities = self.scan()
67
- self.reference["wavelength"] = wavelength
68
- self.reference["intensities"] = intensities
69
- self.__ref_called = True
70
-
71
- return IRSpectrum(wavelength, intensities)
72
-
73
- def obtain_spectrum(self) -> IRSpectrum:
74
- """Obtain an IR spectrum of a sample.
75
-
76
- Raises:
77
- NoReferenceException: Attempting to measure a sample without#
78
- reference data.
79
-
80
- Returns:
81
- IRSpectrum: Sample IR spectrum.
82
- """
83
-
84
- if not self.__ref_called:
85
- raise NoReferenceException(
86
- "Attempting to call a spectrum without a valid reference."
87
- )
88
-
89
- wavelength, intensities = self.scan()
90
- return IRSpectrum(wavelength, intensities, ref=self.reference)