pychemstation 0.10.2__py3-none-any.whl → 0.10.4__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 (31) hide show
  1. pychemstation/__init__.py +1 -1
  2. pychemstation/analysis/__init__.py +3 -4
  3. pychemstation/analysis/base_spectrum.py +7 -7
  4. pychemstation/{utils → analysis}/chromatogram.py +4 -4
  5. pychemstation/analysis/process_report.py +106 -70
  6. pychemstation/control/README.md +21 -53
  7. pychemstation/control/__init__.py +3 -2
  8. pychemstation/control/controllers/__init__.py +1 -5
  9. pychemstation/control/controllers/comm.py +20 -11
  10. pychemstation/control/controllers/devices/device.py +22 -12
  11. pychemstation/control/controllers/devices/injector.py +24 -14
  12. pychemstation/control/controllers/tables/method.py +233 -100
  13. pychemstation/control/controllers/tables/ms.py +7 -4
  14. pychemstation/control/controllers/tables/sequence.py +134 -54
  15. pychemstation/control/controllers/tables/table.py +152 -92
  16. pychemstation/control/hplc.py +96 -78
  17. pychemstation/generated/__init__.py +0 -2
  18. pychemstation/generated/pump_method.py +15 -19
  19. pychemstation/utils/macro.py +10 -9
  20. pychemstation/utils/method_types.py +1 -0
  21. pychemstation/utils/num_utils.py +2 -2
  22. pychemstation/utils/parsing.py +0 -11
  23. pychemstation/utils/sequence_types.py +2 -3
  24. pychemstation/utils/spec_utils.py +2 -3
  25. pychemstation/utils/table_types.py +10 -9
  26. pychemstation/utils/tray_types.py +48 -38
  27. {pychemstation-0.10.2.dist-info → pychemstation-0.10.4.dist-info}/METADATA +46 -20
  28. pychemstation-0.10.4.dist-info/RECORD +37 -0
  29. pychemstation-0.10.2.dist-info/RECORD +0 -37
  30. {pychemstation-0.10.2.dist-info → pychemstation-0.10.4.dist-info}/WHEEL +0 -0
  31. {pychemstation-0.10.2.dist-info → pychemstation-0.10.4.dist-info}/licenses/LICENSE +0 -0
@@ -1,10 +1,8 @@
1
- from __future__ import annotations
2
-
3
- from .device import DeviceController
4
1
  from ....control.controllers import CommunicationController
5
2
  from ....utils.injector_types import (
6
3
  Draw,
7
4
  Inject,
5
+ InjectorFunction,
8
6
  InjectorTable,
9
7
  Mode,
10
8
  Remote,
@@ -14,14 +12,16 @@ from ....utils.injector_types import (
14
12
  )
15
13
  from ....utils.table_types import RegisterFlag, Table
16
14
  from ....utils.tray_types import Tray
15
+ from .device import DeviceController
17
16
 
18
17
 
19
18
  class InjectorController(DeviceController):
20
-
21
- def __init__(self, controller: CommunicationController, table: Table, offline: bool):
19
+ def __init__(
20
+ self, controller: CommunicationController, table: Table, offline: bool
21
+ ):
22
22
  super().__init__(controller, table, offline)
23
23
 
24
- def get_row(self, row: int) -> None | Remote | Draw | Wait | Inject:
24
+ def get_row(self, row: int) -> InjectorFunction:
25
25
  def return_tray_loc() -> Tray:
26
26
  pass
27
27
 
@@ -34,18 +34,28 @@ class InjectorController(DeviceController):
34
34
  # TODO: better error handling
35
35
  is_source = SourceType(self.get_text(row, RegisterFlag.DRAW_SOURCE))
36
36
  is_volume = Mode(self.get_text(row, RegisterFlag.DRAW_VOLUME))
37
- vol = self.get_num(row, RegisterFlag.DRAW_VOLUME_VALUE) if is_volume == Mode.SET else None
37
+ vol = (
38
+ self.get_num(row, RegisterFlag.DRAW_VOLUME_VALUE)
39
+ if is_volume == Mode.SET
40
+ else None
41
+ )
38
42
  if is_source is SourceType.SPECIFIC_LOCATION:
39
43
  return Draw(amount=vol, source=return_tray_loc())
40
44
  elif is_source is SourceType.LOCATION:
41
- return Draw(amount=vol, location=self.get_text(row, RegisterFlag.DRAW_LOCATION))
45
+ return Draw(
46
+ amount=vol, location=self.get_text(row, RegisterFlag.DRAW_LOCATION)
47
+ )
42
48
  elif function == "Remote":
43
- return Remote(command=RemoteCommand(self.get_text(row, RegisterFlag.REMOTE)),
44
- duration=self.get_num(row, RegisterFlag.REMOTE_DUR))
49
+ return Remote(
50
+ command=RemoteCommand(self.get_text(row, RegisterFlag.REMOTE)),
51
+ duration=self.get_num(row, RegisterFlag.REMOTE_DUR),
52
+ )
45
53
 
46
- def load(self) -> InjectorTable | None:
54
+ def load(self) -> InjectorTable:
47
55
  rows = self.get_num_rows()
48
56
  if rows.is_ok():
49
- return InjectorTable(functions=[self.get_row(i) for i in range(int(rows.ok_value.num_response))])
50
-
51
-
57
+ return InjectorTable(
58
+ functions=[
59
+ self.get_row(i) for i in range(int(rows.ok_value.num_response))
60
+ ]
61
+ )
@@ -9,7 +9,7 @@ from xsdata.formats.dataclass.parsers import XmlParser
9
9
  from ....analysis.process_report import AgilentReport, ReportType
10
10
  from ....control.controllers import CommunicationController
11
11
  from ....generated import DadMethod, PumpMethod, SolventElement
12
- from ....utils.chromatogram import (
12
+ from pychemstation.analysis.chromatogram import (
13
13
  TIME_FORMAT,
14
14
  AgilentChannelChromatogramData,
15
15
  AgilentHPLCChromatogram,
@@ -32,15 +32,24 @@ class MethodController(TableController):
32
32
  Class containing method related logic
33
33
  """
34
34
 
35
- def __init__(self, controller: CommunicationController,
36
- src: str,
37
- data_dirs: List[str],
38
- table: Table,
39
- offline: bool,
40
- injector_controller: InjectorController):
35
+ def __init__(
36
+ self,
37
+ controller: CommunicationController,
38
+ src: str,
39
+ data_dirs: List[str],
40
+ table: Table,
41
+ offline: bool,
42
+ injector_controller: InjectorController,
43
+ ):
41
44
  self.injector_controller = injector_controller
42
45
  self.data_files: List[str] = []
43
- super().__init__(controller=controller, src=src, data_dirs=data_dirs, table=table, offline=offline)
46
+ super().__init__(
47
+ controller=controller,
48
+ src=src,
49
+ data_dirs=data_dirs,
50
+ table=table,
51
+ offline=offline,
52
+ )
44
53
 
45
54
  def check(self) -> str:
46
55
  time.sleep(2)
@@ -52,16 +61,17 @@ class MethodController(TableController):
52
61
  return "ERROR"
53
62
 
54
63
  def get_method_params(self) -> HPLCMethodParams:
55
- return HPLCMethodParams(organic_modifier=self.controller.get_num_val(
56
- cmd=TableOperation.GET_OBJ_HDR_VAL.value.format(
57
- register=self.table_locator.register,
58
- register_flag=RegisterFlag.SOLVENT_B_COMPOSITION
59
- )
60
- ),
64
+ return HPLCMethodParams(
65
+ organic_modifier=self.controller.get_num_val(
66
+ cmd=TableOperation.GET_OBJ_HDR_VAL.value.format(
67
+ register=self.table_locator.register,
68
+ register_flag=RegisterFlag.SOLVENT_B_COMPOSITION,
69
+ )
70
+ ),
61
71
  flow=self.controller.get_num_val(
62
72
  cmd=TableOperation.GET_OBJ_HDR_VAL.value.format(
63
73
  register=self.table_locator.register,
64
- register_flag=RegisterFlag.FLOW
74
+ register_flag=RegisterFlag.FLOW,
65
75
  )
66
76
  ),
67
77
  )
@@ -79,9 +89,11 @@ class MethodController(TableController):
79
89
  except RuntimeError:
80
90
  pass
81
91
 
82
- return TimeTableEntry(start_time=self.get_num(row, RegisterFlag.TIME),
83
- organic_modifer=om,
84
- flow=flow)
92
+ return TimeTableEntry(
93
+ start_time=self.get_num(row, RegisterFlag.TIME),
94
+ organic_modifer=om,
95
+ flow=flow,
96
+ )
85
97
 
86
98
  def get_timetable(self, rows: int):
87
99
  uncoalesced_timetable_rows = [self.get_row(r + 1) for r in range(rows)]
@@ -89,9 +101,11 @@ class MethodController(TableController):
89
101
  for row in uncoalesced_timetable_rows:
90
102
  time_key = str(row.start_time)
91
103
  if time_key not in timetable_rows.keys():
92
- timetable_rows[time_key] = TimeTableEntry(start_time=row.start_time,
93
- flow=row.flow,
94
- organic_modifer=row.organic_modifer)
104
+ timetable_rows[time_key] = TimeTableEntry(
105
+ start_time=row.start_time,
106
+ flow=row.flow,
107
+ organic_modifer=row.organic_modifer,
108
+ )
95
109
  else:
96
110
  if row.flow:
97
111
  timetable_rows[time_key].flow = row.flow
@@ -109,11 +123,13 @@ class MethodController(TableController):
109
123
  params = self.get_method_params()
110
124
  stop_time = self.get_stop_time()
111
125
  post_time = self.get_post_time()
112
- self.table_state = MethodDetails(name=method_name,
113
- timetable=timetable_rows,
114
- stop_time=stop_time,
115
- post_time=post_time,
116
- params=params)
126
+ self.table_state = MethodDetails(
127
+ name=method_name,
128
+ timetable=timetable_rows,
129
+ stop_time=stop_time,
130
+ post_time=post_time,
131
+ params=params,
132
+ )
117
133
  return self.table_state
118
134
  else:
119
135
  raise RuntimeError(rows.err_value)
@@ -128,13 +144,17 @@ class MethodController(TableController):
128
144
  return self.controller.get_num_val(
129
145
  cmd=TableOperation.GET_OBJ_HDR_VAL.value.format(
130
146
  register=self.table_locator.register,
131
- register_flag=RegisterFlag.POST_TIME))
147
+ register_flag=RegisterFlag.POST_TIME,
148
+ )
149
+ )
132
150
 
133
151
  def get_stop_time(self) -> Union[int, float]:
134
152
  return self.controller.get_num_val(
135
153
  cmd=TableOperation.GET_OBJ_HDR_VAL.value.format(
136
154
  register=self.table_locator.register,
137
- register_flag=RegisterFlag.MAX_TIME))
155
+ register_flag=RegisterFlag.MAX_TIME,
156
+ )
157
+ )
138
158
 
139
159
  def get_total_runtime(self) -> Union[int, float]:
140
160
  """Returns total method runtime in minutes."""
@@ -163,7 +183,11 @@ class MethodController(TableController):
163
183
  :raise AssertionError: The desired method is not selected. Try again.
164
184
  """
165
185
  method_dir = self.src if not alt_method_dir else alt_method_dir
166
- self.send(Command.SWITCH_METHOD_CMD_SPECIFIC.value.format(method_dir=method_dir, method_name=method_name))
186
+ self.send(
187
+ Command.SWITCH_METHOD_CMD_SPECIFIC.value.format(
188
+ method_dir=method_dir, method_name=method_name
189
+ )
190
+ )
167
191
 
168
192
  time.sleep(2)
169
193
  self.send(Command.GET_METHOD_CMD)
@@ -186,8 +210,14 @@ class MethodController(TableController):
186
210
  """
187
211
  warnings.warn("This method is not actively maintained.")
188
212
  method_folder = f"{method_name}.M"
189
- method_path = os.path.join(self.src, method_folder, "AgilentPumpDriver1.RapidControl.MethodXML.xml")
190
- dad_path = os.path.join(self.src, method_folder, "Agilent1200erDadDriver1.RapidControl.MethodXML.xml")
213
+ method_path = os.path.join(
214
+ self.src, method_folder, "AgilentPumpDriver1.RapidControl.MethodXML.xml"
215
+ )
216
+ dad_path = os.path.join(
217
+ self.src,
218
+ method_folder,
219
+ "Agilent1200erDadDriver1.RapidControl.MethodXML.xml",
220
+ )
191
221
 
192
222
  if os.path.exists(os.path.join(self.src, f"{method_name}.M")):
193
223
  parser = XmlParser()
@@ -195,25 +225,29 @@ class MethodController(TableController):
195
225
  dad = parser.parse(dad_path, DadMethod)
196
226
 
197
227
  organic_modifier: Optional[SolventElement] = None
198
- aq_modifier: Optional[SolventElement] = None
199
228
 
200
229
  if len(method.solvent_composition.solvent_element) == 2:
201
230
  for solvent in method.solvent_composition.solvent_element:
202
- if solvent.channel == "Channel_A":
203
- aq_modifier = solvent
204
- elif solvent.channel == "Channel_B":
231
+ if solvent.channel == "Channel_B":
205
232
  organic_modifier = solvent
206
233
 
207
- self.table_state = MethodDetails(name=method_name,
208
- params=HPLCMethodParams(organic_modifier=organic_modifier.percentage,
209
- flow=method.flow),
210
- stop_time=method.stop_time.stop_time_value,
211
- post_time=method.post_time.post_time_value,
212
- timetable=[TimeTableEntry(start_time=tte.time,
213
- organic_modifer=tte.percent_b,
214
- flow=method.flow
215
- ) for tte in method.timetable.timetable_entry],
216
- dad_wavelengthes=dad.signals.signal)
234
+ self.table_state = MethodDetails(
235
+ name=method_name,
236
+ params=HPLCMethodParams(
237
+ organic_modifier=organic_modifier.percentage, flow=method.flow
238
+ ),
239
+ stop_time=method.stop_time.stop_time_value,
240
+ post_time=method.post_time.post_time_value,
241
+ timetable=[
242
+ TimeTableEntry(
243
+ start_time=tte.time,
244
+ organic_modifer=tte.percent_b,
245
+ flow=method.flow,
246
+ )
247
+ for tte in method.timetable.timetable_entry
248
+ ],
249
+ dad_wavelengthes=dad.signals.signal,
250
+ )
217
251
  return self.table_state
218
252
  else:
219
253
  raise FileNotFoundError
@@ -225,43 +259,90 @@ class MethodController(TableController):
225
259
  :param save: if false only modifies the method, otherwise saves to disk
226
260
  """
227
261
  self.table_state = updated_method
228
- initial_organic_modifier: Param = Param(val=updated_method.params.organic_modifier,
229
- chemstation_key=RegisterFlag.SOLVENT_B_COMPOSITION,
230
- ptype=PType.NUM)
231
- max_time: Param = Param(val=updated_method.stop_time,
232
- chemstation_key=RegisterFlag.MAX_TIME,
233
- ptype=PType.NUM)
234
- post_time: Param = Param(val=updated_method.post_time,
235
- chemstation_key=RegisterFlag.POST_TIME,
236
- ptype=PType.NUM)
237
- flow: Param = Param(val=updated_method.params.flow,
238
- chemstation_key=RegisterFlag.FLOW,
239
- ptype=PType.NUM)
240
-
241
262
  # Method settings required for all runs
242
- self.update_method_params(flow, initial_organic_modifier, max_time, post_time)
243
- self._update_method_timetable(updated_method.timetable)
263
+ self.update_method_params(
264
+ new_flow=updated_method.params.flow,
265
+ new_initial_om=updated_method.params.organic_modifier,
266
+ new_stop_time=updated_method.stop_time,
267
+ new_post_time=updated_method.post_time,
268
+ )
269
+ self.edit_method_timetable(updated_method.timetable)
244
270
 
245
271
  if save:
246
- self.send(Command.SAVE_METHOD_CMD.value.format(
247
- commit_msg=f"saved method at {str(time.time())}"
248
- ))
272
+ self.send(
273
+ Command.SAVE_METHOD_CMD.value.format(
274
+ commit_msg=f"saved method at {str(time.time())}"
275
+ )
276
+ )
249
277
 
250
- def update_method_params(self, flow, initial_organic_modifier, max_time, post_time):
251
- self.delete_table()
278
+ def edit_initial_om(self, new_om: Union[int, float]):
279
+ initial_organic_modifier: Param = Param(
280
+ val=new_om,
281
+ chemstation_key=RegisterFlag.SOLVENT_B_COMPOSITION,
282
+ ptype=PType.NUM,
283
+ )
252
284
  self._update_param(initial_organic_modifier)
285
+
286
+ def edit_flow(self, new_flow: Union[int, float]):
287
+ flow: Param = Param(
288
+ val=new_flow, chemstation_key=RegisterFlag.FLOW, ptype=PType.NUM
289
+ )
253
290
  self._update_param(flow)
291
+
292
+ def edit_stop_time(self, new_stop_time: Union[int, float]):
293
+ stop_time: Param = Param(
294
+ val=new_stop_time,
295
+ chemstation_key=RegisterFlag.MAX_TIME,
296
+ ptype=PType.NUM,
297
+ )
298
+ self._update_param(
299
+ Param(
300
+ val="Set", chemstation_key=RegisterFlag.STOPTIME_MODE, ptype=PType.STR
301
+ )
302
+ )
303
+ self._update_param(stop_time)
304
+
305
+ def edit_post_time(self, new_post_time: Union[int, float]):
306
+ post_time: Param = Param(
307
+ val=new_post_time,
308
+ chemstation_key=RegisterFlag.POST_TIME,
309
+ ptype=PType.NUM,
310
+ )
311
+ self._update_param(
312
+ Param(val="Set", chemstation_key=RegisterFlag.POSTIME_MODE, ptype=PType.STR)
313
+ )
314
+ self._update_param(post_time)
315
+
316
+ def update_method_params(
317
+ self,
318
+ new_flow: Union[int, float],
319
+ new_initial_om: Union[int, float],
320
+ new_stop_time: Union[int, float],
321
+ new_post_time: Union[int, float],
322
+ ):
323
+ self.delete_table()
324
+ self.edit_initial_om(new_initial_om)
325
+ self.edit_flow(new_flow)
254
326
  if self.table_state.stop_time:
255
- self._update_param(Param(val="Set", chemstation_key=RegisterFlag.STOPTIME_MODE, ptype=PType.STR))
256
- self._update_param(max_time)
327
+ self.edit_stop_time(new_stop_time)
257
328
  else:
258
- self._update_param(Param(val="Off", chemstation_key=RegisterFlag.STOPTIME_MODE, ptype=PType.STR))
329
+ self._update_param(
330
+ Param(
331
+ val="Off",
332
+ chemstation_key=RegisterFlag.STOPTIME_MODE,
333
+ ptype=PType.STR,
334
+ )
335
+ )
259
336
  if self.table_state.post_time:
260
- self._update_param(Param(val="Set", chemstation_key=RegisterFlag.POSTIME_MODE, ptype=PType.STR))
261
- self._update_param(post_time)
337
+ self.edit_post_time(new_post_time)
262
338
  else:
263
- self._update_param(Param(val="Off", chemstation_key=RegisterFlag.POSTIME_MODE, ptype=PType.STR))
264
- self.download()
339
+ self._update_param(
340
+ Param(
341
+ val="Off",
342
+ chemstation_key=RegisterFlag.POSTIME_MODE,
343
+ ptype=PType.STR,
344
+ )
345
+ )
265
346
 
266
347
  def _update_param(self, method_param: Param):
267
348
  """Change a method parameter, changes what is visibly seen in Chemstation GUI.
@@ -270,34 +351,55 @@ class MethodController(TableController):
270
351
  :param method_param: a parameter to update for currently loaded method.
271
352
  """
272
353
  register = self.table_locator.register
273
- setting_command = TableOperation.UPDATE_OBJ_HDR_VAL if method_param.ptype == PType.NUM else TableOperation.UPDATE_OBJ_HDR_TEXT
354
+ setting_command = (
355
+ TableOperation.UPDATE_OBJ_HDR_VAL
356
+ if method_param.ptype == PType.NUM
357
+ else TableOperation.UPDATE_OBJ_HDR_TEXT
358
+ )
274
359
  if isinstance(method_param.chemstation_key, list):
275
360
  for register_flag in method_param.chemstation_key:
276
- self.send(setting_command.value.format(register=register,
277
- register_flag=register_flag,
278
- val=method_param.val))
361
+ self.send(
362
+ setting_command.value.format(
363
+ register=register,
364
+ register_flag=register_flag,
365
+ val=method_param.val,
366
+ )
367
+ )
279
368
  else:
280
- self.send(setting_command.value.format(register=register,
281
- register_flag=method_param.chemstation_key,
282
- val=method_param.val))
369
+ self.send(
370
+ setting_command.value.format(
371
+ register=register,
372
+ register_flag=method_param.chemstation_key,
373
+ val=method_param.val,
374
+ )
375
+ )
283
376
  time.sleep(2)
377
+ self.download()
284
378
 
285
379
  def download(self):
286
- self.send('Sleep 1')
380
+ self.send("Sleep 1")
287
381
  self.sleepy_send("DownloadRCMethod PMP1")
288
- self.send('Sleep 1')
382
+ self.send("Sleep 1")
289
383
 
290
- def edit_row(self, row: TimeTableEntry, first_row: bool = False):
384
+ def _edit_row(self, row: TimeTableEntry, first_row: bool = False):
291
385
  if first_row:
292
386
  if row.organic_modifer:
293
387
  self.add_row()
294
- self.add_new_col_text(col_name=RegisterFlag.FUNCTION, val=RegisterFlag.SOLVENT_COMPOSITION.value)
388
+ self.add_new_col_text(
389
+ col_name=RegisterFlag.FUNCTION,
390
+ val=RegisterFlag.SOLVENT_COMPOSITION.value,
391
+ )
295
392
  self.add_new_col_num(col_name=RegisterFlag.TIME, val=row.start_time)
296
- self.add_new_col_num(col_name=RegisterFlag.TIMETABLE_SOLVENT_B_COMPOSITION, val=row.organic_modifer)
393
+ self.add_new_col_num(
394
+ col_name=RegisterFlag.TIMETABLE_SOLVENT_B_COMPOSITION,
395
+ val=row.organic_modifer,
396
+ )
297
397
  if row.flow:
298
398
  self.add_row()
299
399
  self.get_num_rows()
300
- self._edit_row_text(col_name=RegisterFlag.FUNCTION, val=RegisterFlag.FLOW.value)
400
+ self._edit_row_text(
401
+ col_name=RegisterFlag.FUNCTION, val=RegisterFlag.FLOW.value
402
+ )
301
403
  self.add_new_col_num(col_name=RegisterFlag.TIMETABLE_FLOW, val=row.flow)
302
404
  self._edit_row_num(col_name=RegisterFlag.TIMETABLE_FLOW, val=row.flow)
303
405
  self.download()
@@ -305,19 +407,27 @@ class MethodController(TableController):
305
407
  if row.organic_modifer:
306
408
  self.add_row()
307
409
  self.get_num_rows()
308
- self._edit_row_text(col_name=RegisterFlag.FUNCTION, val=RegisterFlag.SOLVENT_COMPOSITION.value)
410
+ self._edit_row_text(
411
+ col_name=RegisterFlag.FUNCTION,
412
+ val=RegisterFlag.SOLVENT_COMPOSITION.value,
413
+ )
309
414
  self._edit_row_num(col_name=RegisterFlag.TIME, val=row.start_time)
310
- self._edit_row_num(col_name=RegisterFlag.TIMETABLE_SOLVENT_B_COMPOSITION, val=row.organic_modifer)
415
+ self._edit_row_num(
416
+ col_name=RegisterFlag.TIMETABLE_SOLVENT_B_COMPOSITION,
417
+ val=row.organic_modifer,
418
+ )
311
419
  self.download()
312
420
  if row.flow:
313
421
  self.add_row()
314
422
  self.get_num_rows()
315
- self._edit_row_text(col_name=RegisterFlag.FUNCTION, val=RegisterFlag.FLOW.value)
423
+ self._edit_row_text(
424
+ col_name=RegisterFlag.FUNCTION, val=RegisterFlag.FLOW.value
425
+ )
316
426
  self._edit_row_num(col_name=RegisterFlag.TIMETABLE_FLOW, val=row.flow)
317
427
  self._edit_row_num(col_name=RegisterFlag.TIME, val=row.start_time)
318
428
  self.download()
319
429
 
320
- def _update_method_timetable(self, timetable_rows: List[TimeTableEntry]):
430
+ def edit_method_timetable(self, timetable_rows: List[TimeTableEntry]):
321
431
  self.get_num_rows()
322
432
  self.delete_table()
323
433
  res = self.get_num_rows()
@@ -329,7 +439,7 @@ class MethodController(TableController):
329
439
  self.get_num_rows()
330
440
 
331
441
  for i, row in enumerate(timetable_rows):
332
- self.edit_row(row=row, first_row=i == 0)
442
+ self._edit_row(row=row, first_row=i == 0)
333
443
 
334
444
  def stop(self):
335
445
  """
@@ -337,7 +447,12 @@ class MethodController(TableController):
337
447
  """
338
448
  self.send(Command.STOP_METHOD_CMD)
339
449
 
340
- def run(self, experiment_name: str, add_timestamp: bool = True, stall_while_running: bool = True):
450
+ def run(
451
+ self,
452
+ experiment_name: str,
453
+ add_timestamp: bool = True,
454
+ stall_while_running: bool = True,
455
+ ):
341
456
  """
342
457
  :param experiment_name: Name of the experiment
343
458
  :param stall_while_running: whether to stall or immediately return
@@ -349,9 +464,19 @@ class MethodController(TableController):
349
464
  tries = 0
350
465
  while tries < 10 and not hplc_is_running:
351
466
  timestamp = time.strftime(TIME_FORMAT)
352
- self.send(Command.RUN_METHOD_CMD.value.format(data_dir=self.data_dirs[0],
353
- experiment_name=f"{experiment_name}_{timestamp}" if add_timestamp else experiment_name))
354
- folder_name = f"{experiment_name}_{timestamp}.D" if add_timestamp else f"{experiment_name}.D"
467
+ self.send(
468
+ Command.RUN_METHOD_CMD.value.format(
469
+ data_dir=self.data_dirs[0],
470
+ experiment_name=f"{experiment_name}_{timestamp}"
471
+ if add_timestamp
472
+ else experiment_name,
473
+ )
474
+ )
475
+ folder_name = (
476
+ f"{experiment_name}_{timestamp}.D"
477
+ if add_timestamp
478
+ else f"{experiment_name}.D"
479
+ )
355
480
  hplc_is_running = self.check_hplc_is_running()
356
481
  tries += 1
357
482
 
@@ -377,27 +502,35 @@ class MethodController(TableController):
377
502
  warning = f"Data folder {self.data_files[-1]} may not exist, returning and will check again after run is done."
378
503
  warnings.warn(warning)
379
504
 
380
-
381
505
  def fuzzy_match_most_recent_folder(self, most_recent_folder: T) -> Result[T, str]:
382
506
  if os.path.exists(most_recent_folder):
383
507
  return Ok(most_recent_folder)
384
508
  return Err("Folder not found!")
385
509
 
386
- def get_data(self, custom_path: Optional[str] = None) -> AgilentChannelChromatogramData:
510
+ def get_data(
511
+ self, custom_path: Optional[str] = None
512
+ ) -> AgilentChannelChromatogramData:
387
513
  custom_path = custom_path if custom_path else self.data_files[-1]
388
514
  self.get_spectrum_at_channels(custom_path)
389
515
  return AgilentChannelChromatogramData(**self.spectra)
390
516
 
391
- def get_data_uv(self, custom_path: Optional[str] = None) -> Dict[str, AgilentHPLCChromatogram]:
517
+ def get_data_uv(
518
+ self, custom_path: Optional[str] = None
519
+ ) -> Dict[str, AgilentHPLCChromatogram]:
392
520
  custom_path = custom_path if custom_path else self.data_files[-1]
393
521
  self.get_uv_spectrum(custom_path)
394
522
  return self.uv
395
523
 
396
- def get_report(self, custom_path: Optional[str] = None,
397
- report_type: ReportType = ReportType.TXT) -> List[AgilentReport]:
524
+ def get_report(
525
+ self,
526
+ custom_path: Optional[str] = None,
527
+ report_type: ReportType = ReportType.TXT,
528
+ ) -> List[AgilentReport]:
398
529
  custom_path = self.data_files[-1] if not custom_path else custom_path
399
530
  metd_report = self.get_report_details(custom_path, report_type)
400
- chrom_data: List[AgilentHPLCChromatogram] = list(self.get_data(custom_path).__dict__.values())
531
+ chrom_data: List[AgilentHPLCChromatogram] = list(
532
+ self.get_data(custom_path).__dict__.values()
533
+ )
401
534
  for i, signal in enumerate(metd_report.signals):
402
535
  possible_data = chrom_data[i]
403
536
  if len(possible_data.x) > 0:
@@ -2,13 +2,14 @@ from typing import Union
2
2
 
3
3
  from ....control.controllers import CommunicationController
4
4
  from ....control.controllers.tables.table import TableController
5
- from ....utils.chromatogram import AgilentChannelChromatogramData
5
+ from pychemstation.analysis.chromatogram import AgilentChannelChromatogramData
6
6
  from ....utils.table_types import Table
7
7
 
8
8
 
9
9
  class MassSpecController(TableController):
10
-
11
- def __init__(self, controller: CommunicationController, src: str, data_dir: str, table: Table):
10
+ def __init__(
11
+ self, controller: CommunicationController, src: str, data_dir: str, table: Table
12
+ ):
12
13
  super().__init__(controller, src, data_dir, table)
13
14
 
14
15
  def get_row(self, row: int):
@@ -17,5 +18,7 @@ class MassSpecController(TableController):
17
18
  def retrieve_recent_data_files(self):
18
19
  pass
19
20
 
20
- def get_data(self) -> Union[list[AgilentChannelChromatogramData], AgilentChannelChromatogramData]:
21
+ def get_data(
22
+ self,
23
+ ) -> Union[list[AgilentChannelChromatogramData], AgilentChannelChromatogramData]:
21
24
  pass