pychemstation 0.6.1__py3-none-any.whl → 0.6.3__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.
@@ -1,18 +1,15 @@
1
- """
2
- pip install pandas
3
- pip install aghplctools==4.8.6
4
- """
5
-
6
1
  import os
7
2
  import re
8
3
  from dataclasses import dataclass
9
- from typing import List, AnyStr
4
+ from typing import List, AnyStr, Dict
10
5
 
11
6
  import pandas as pd
12
7
  from aghplctools.ingestion.text import _no_peaks_re, _area_report_re, _header_block_re, _signal_info_re, \
13
8
  _signal_table_re, chunk_string
14
9
  from result import Result, Err, Ok
15
10
 
11
+ from pychemstation.utils.tray_types import FiftyFourVialPlate, int_to_ffvp, Tray
12
+
16
13
 
17
14
  @dataclass
18
15
  class AgilentPeak:
@@ -25,6 +22,13 @@ class AgilentPeak:
25
22
  height_percent: float
26
23
 
27
24
 
25
+ @dataclass
26
+ class AgilentReport:
27
+ vial_location: Tray
28
+ signals: Dict[AnyStr, List[AgilentPeak]]
29
+ solvents: Dict[AnyStr, AnyStr]
30
+
31
+
28
32
  _column_re_dictionary = { # regex matches for column and unit combinations
29
33
  'Peak': { # peak index
30
34
  '#': '[ ]+(?P<Peak>[\d]+)', # number
@@ -51,7 +55,7 @@ _column_re_dictionary = { # regex matches for column and unit combinations
51
55
  }
52
56
 
53
57
 
54
- def build_peak_regex(signal_table: str):
58
+ def build_peak_regex(signal_table: str) -> re.Pattern[AnyStr]:
55
59
  """
56
60
  Builds a peak regex from a signal table
57
61
 
@@ -211,9 +215,40 @@ def process_folder(folder_path, target_wavelengths=None, min_retention_time=0, m
211
215
  return results_df
212
216
 
213
217
 
214
- def process_csv_report(folder_path: str, num: int) -> Result[List[AgilentPeak], AnyStr]:
215
- potential_report = os.path.join(folder_path, f'REPORT0{num}.CSV')
216
- if os.path.exists(potential_report):
217
- df = pd.read_csv(potential_report, encoding="utf-16", header=None)
218
- return Ok(df.apply(lambda row: AgilentPeak(*row), axis=1))
218
+ def process_csv_report(folder_path: str) -> Result[AgilentReport, AnyStr]:
219
+ labels = os.path.join(folder_path, f'REPORT00.CSV')
220
+ if os.path.exists(labels):
221
+ df_labels: Dict[int, Dict[int: AnyStr]] = pd.read_csv(labels, encoding="utf-16", header=None).to_dict()
222
+ vial_location = []
223
+ signals = {}
224
+ solvents = {}
225
+ for pos, val in df_labels[0].items():
226
+ if val == "Location":
227
+ vial_location = df_labels[1][pos]
228
+ elif "Solvent" in val:
229
+ if val not in solvents.keys():
230
+ solvents[val] = df_labels[2][pos]
231
+ elif val == "Number of Signals":
232
+ num_signals = int(df_labels[1][pos])
233
+ for s in range(1, num_signals + 1):
234
+ peaks = process_peaks(os.path.join(folder_path, f'REPORT0{s}.CSV'))
235
+ if peaks.is_ok():
236
+ wavelength = df_labels[1][pos + s].partition(",4 Ref=off")[0][-3:]
237
+ signals[wavelength] = peaks.ok_value
238
+ break
239
+
240
+ return Ok(AgilentReport(
241
+ signals=signals,
242
+ vial_location=int_to_ffvp(vial_location),
243
+ solvents=solvents
244
+ ))
245
+
219
246
  return Err("No report found")
247
+
248
+
249
+ def process_peaks(folder_path: str) -> Result[List[AgilentPeak], AnyStr]:
250
+ try:
251
+ df = pd.read_csv(folder_path, encoding="utf-16", header=None)
252
+ return Ok(df.apply(lambda row: AgilentPeak(*row), axis=1))
253
+ except Exception:
254
+ return Err("Trouble reading report")
@@ -132,7 +132,7 @@ class MethodController(TableController):
132
132
  :raise IndexError: Response did not have expected format. Try again.
133
133
  :raise AssertionError: The desired method is not selected. Try again.
134
134
  """
135
- self.send(Command.SWITCH_METHOD_CMD.value.format(method_dir=self.src,
135
+ self.send(Command.SWITCH_METHOD_CMD_SPECIFIC.value.format(method_dir=self.src,
136
136
  method_name=method_name))
137
137
 
138
138
  time.sleep(2)
@@ -305,5 +305,5 @@ class TableController(abc.ABC):
305
305
  try:
306
306
  spec.load_spectrum(data_path=data_path, channel=channel)
307
307
  except FileNotFoundError:
308
- self.spectra[channel] = None
308
+ self.spectra[channel] = AgilentHPLCChromatogram(self.data_dir)
309
309
  print(f"No data at channel: {channel}")
@@ -38,6 +38,7 @@ class Command(Enum):
38
38
  GET_METHOD_CMD = "response$ = _MethFile$"
39
39
  GET_ROWS_CMD = 'response_num = TabHdrVal({register}, "{table_name}", "{col_name}")'
40
40
  SWITCH_METHOD_CMD = 'LoadMethod _MethPath$, _MethFile$'
41
+ SWITCH_METHOD_CMD_SPECIFIC = 'LoadMethod "{method_dir}", "{method_name}.M"'
41
42
  START_METHOD_CMD = "StartMethod"
42
43
  RUN_METHOD_CMD = 'RunMethod "{data_dir}",, "{experiment_name}_{timestamp}"'
43
44
  STOP_METHOD_CMD = "StopMethod"
@@ -18,16 +18,16 @@ class Num(Enum):
18
18
 
19
19
 
20
20
  class Plate(Enum):
21
- ONE = "1"
22
- TWO = "2"
21
+ ONE = 0
22
+ TWO = 4000
23
23
 
24
24
 
25
25
  class Letter(Enum):
26
- A = 8191
27
- B = 8255
28
- C = 8319
29
- D = 8383
30
- F = 8447
26
+ A = 4191
27
+ B = 4255
28
+ C = 4319
29
+ D = 4383
30
+ F = 4447
31
31
 
32
32
 
33
33
  @dataclass
@@ -37,7 +37,11 @@ class FiftyFourVialPlate:
37
37
  num: Num
38
38
 
39
39
  def value(self) -> int:
40
- return self.letter.value + self.num.value
40
+ return self.plate.value + self.letter.value + self.num.value
41
+
42
+
43
+ def int_to_ffvp(num: int) -> FiftyFourVialPlate:
44
+ return num
41
45
 
42
46
 
43
47
  class TenVialColumn(Enum):
@@ -53,4 +57,4 @@ class TenVialColumn(Enum):
53
57
  TEN = 10
54
58
 
55
59
 
56
- Tray = Union[FiftyFourVialPlate, TenVialColumn]
60
+ Tray = Union[FiftyFourVialPlate, TenVialColumn]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pychemstation
3
- Version: 0.6.1
3
+ Version: 0.6.3
4
4
  Summary: Library to interact with Chemstation software, primarily used in Hein lab
5
5
  Home-page: https://gitlab.com/heingroup/device-api/pychemstation
6
6
  Author: Lucy Hao
@@ -1,7 +1,7 @@
1
1
  pychemstation/__init__.py,sha256=SpTl-Tg1B1HTyjNOE-8ue-N2wGnXN_2zl7RFUSxlkiM,33
2
2
  pychemstation/analysis/__init__.py,sha256=EWoU47iyn9xGS-b44zK9eq50bSjOV4AC5dvt420YMI4,44
3
3
  pychemstation/analysis/base_spectrum.py,sha256=XPf9eJ72uz0CnxCY5uFOyu1MbVX-OTTXeN1tLzIMok4,16536
4
- pychemstation/analysis/process_report.py,sha256=d290KgPY-cMlQg4yHaspLFxgso_yu9qNxXG6SF2qpuo,9054
4
+ pychemstation/analysis/process_report.py,sha256=l7LiCBctXUAcINGwBetAlSAziSKhxG7v7wuM9aWFrUU,10409
5
5
  pychemstation/analysis/spec_utils.py,sha256=UOo9hJR3evJfmaohEEsyb7aq6X996ofuUfu-GKjiDi8,10201
6
6
  pychemstation/analysis/utils.py,sha256=ISupAOb_yqA4_DZRK9v18UL-XjUQccAicIJKb1VMnGg,2055
7
7
  pychemstation/control/__init__.py,sha256=4xTy8X-mkn_PPZKr7w9rnj1wZhtmTesbQptPhpYmKXs,64
@@ -19,10 +19,10 @@ pychemstation/control/controllers/devices/device.py,sha256=QUFpUwmGxMzmG1CiRhNau
19
19
  pychemstation/control/controllers/devices/injector.py,sha256=Kxf4NjxPUt2xjOmJ9Pea1b9YzWyGcpW8VdOlx9Jo-Nw,5540
20
20
  pychemstation/control/controllers/devices/pump.py,sha256=DJQh4lNXEraeC1CWrsKmsITOjuYlRI3tih_XRB3F1hg,1404
21
21
  pychemstation/control/controllers/tables/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
- pychemstation/control/controllers/tables/method.py,sha256=3GdAQ6Cwf20QL3v7eMkwNieWbJdtr9GN12USbSVl_iE,16426
22
+ pychemstation/control/controllers/tables/method.py,sha256=Bzo0BHatMOFf_TmMBVuQbtLvZRTARaW5q1e2-WKJVHY,16435
23
23
  pychemstation/control/controllers/tables/ms.py,sha256=JFD-tOhu8uRyKdl-E3-neRssii8MNqVRIlsrnFhNY_M,682
24
24
  pychemstation/control/controllers/tables/sequence.py,sha256=vqwJeV38YWdFnaDXvZVOGYl-UCV9lmMbh8Fj5kQ3mqY,8815
25
- pychemstation/control/controllers/tables/table.py,sha256=J-uNIFHVznPJqOKPmmqrJBXt70KlxmZlSdtEVM2pEKM,12576
25
+ pychemstation/control/controllers/tables/table.py,sha256=GjZ15aJhsCQ9Ps9imOh3Q5NgK97kzangrJcOGa8bjKA,12610
26
26
  pychemstation/control/table/__init__.py,sha256=RgMN4uIWHdNUHpGRBWdzmzAbk7XEKl6Y-qtqWCxzSZU,124
27
27
  pychemstation/control/table/method.py,sha256=THVoGomSXff_CTU3eAYme0BYwkPzab5UgZKsiZ29QSk,12196
28
28
  pychemstation/control/table/sequence.py,sha256=Eri52AnbE3BGthfrRSvYKYciquUzvHKo0lYUTySYYE8,10542
@@ -33,23 +33,23 @@ pychemstation/generated/pump_method.py,sha256=sUhE2Oo00nzVcoONtq3EMWsN4wLSryXbG8
33
33
  pychemstation/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
34
  pychemstation/utils/chromatogram.py,sha256=-q3_hL9GTyi4C95os7IwAiOrkTM4EXIiigm-nW9pFmM,3221
35
35
  pychemstation/utils/injector_types.py,sha256=SD452SwEHNx4Xs2p-mhg6X0pd99XewQ1Zbu-r9kPOJs,817
36
- pychemstation/utils/macro.py,sha256=o1dypIKhEMbDea34VFh4gKu-kWIjXZAFyqK4FYjCKjo,2836
36
+ pychemstation/utils/macro.py,sha256=PZ916baFfqCkPaSqpdjm2N5mhfg4V4H8KQl7N5l3rUw,2916
37
37
  pychemstation/utils/method_types.py,sha256=3qxKeREl_97GnQ74qcA3kxibnvWI4ueb-6XZlxcV2Hg,1632
38
38
  pychemstation/utils/parsing.py,sha256=bnFIsZZwFy9NKzVUf517yN-ogzQbm0hp_aho3KUD6Is,9317
39
39
  pychemstation/utils/pump_types.py,sha256=HWQHxscGn19NTrfYBwQRCO2VcYfwyko7YfBO5uDhEm4,93
40
40
  pychemstation/utils/sequence_types.py,sha256=4cNpmRdPLN5oGN7ozHgT21E65aBO8vV3ZcRXMOQ3EA8,1084
41
41
  pychemstation/utils/table_types.py,sha256=0kg7gZXFk7O5l0K1BEBaF4OFFdja3-hFUG9UbN5PBcs,3173
42
- pychemstation/utils/tray_types.py,sha256=MaHN36rhcEI5mAY95VU8hfP9HhAlngQvMYq-2oyC0hc,764
42
+ pychemstation/utils/tray_types.py,sha256=NZVMi2bYfUApMPEigFacKzEQL3-6J2e7kD8pq-lbFqE,849
43
43
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
44
  tests/constants.py,sha256=55DOLpylLt12mb_gSgzEo-EYynwTmI2uH7PcrTM6Iq0,2455
45
45
  tests/test_comb.py,sha256=TS-CbtiPbntL4u6E1gSZ6xquNp6cQxIFdJqUr2ak7PA,5515
46
46
  tests/test_comm.py,sha256=iwl-Ey-xoytXmlNrjG84pDm82Ry_QUX6wY4gmVh4NDc,2516
47
- tests/test_inj.py,sha256=Blpk-z9PQuqo4xQ7AUi0CS2czMiYm-pqZe75OFTXru4,1092
47
+ tests/test_inj.py,sha256=UakPA1Sd1GAbFvFepEredWcWPoW7PMLKotfqVZ1i4hE,1434
48
48
  tests/test_method.py,sha256=KB7yAtVb4gZftnYzh-VfPb9LGVZOHUIW6OljEYRtbhA,4570
49
- tests/test_proc_rep.py,sha256=WhUiFqDD1Aey_Nc6Hvbd2zo48K4MWjwDhfO9LiwEQ7M,703
49
+ tests/test_proc_rep.py,sha256=sxRiTBybVm6lyAqmgrri-T2EfZgs27oSgbYXSsN9CwU,1380
50
50
  tests/test_sequence.py,sha256=vs5-dqkItRds_tPM2-N6MNJ37FB0nLRFaDzBV8d42i8,4880
51
- pychemstation-0.6.1.dist-info/LICENSE,sha256=9bdF75gIf1MecZ7oymqWgJREVz7McXPG-mjqrTmzzD8,18658
52
- pychemstation-0.6.1.dist-info/METADATA,sha256=oGTCg13YoFF8G2T3aPXss0aKXNveIK9n_UMLpdYQVxM,4370
53
- pychemstation-0.6.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
54
- pychemstation-0.6.1.dist-info/top_level.txt,sha256=zXfKu_4nYWwPHo3OsuhshMNC3SPkcoTGCyODjURaghY,20
55
- pychemstation-0.6.1.dist-info/RECORD,,
51
+ pychemstation-0.6.3.dist-info/LICENSE,sha256=9bdF75gIf1MecZ7oymqWgJREVz7McXPG-mjqrTmzzD8,18658
52
+ pychemstation-0.6.3.dist-info/METADATA,sha256=cfjChXxJ_G29LqdihU0BapRxhWhzkdSMH9sfBQFCKWk,4370
53
+ pychemstation-0.6.3.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
54
+ pychemstation-0.6.3.dist-info/top_level.txt,sha256=zXfKu_4nYWwPHo3OsuhshMNC3SPkcoTGCyODjURaghY,20
55
+ pychemstation-0.6.3.dist-info/RECORD,,
tests/test_inj.py CHANGED
@@ -2,22 +2,27 @@ import os
2
2
  import unittest
3
3
 
4
4
  from pychemstation.control import HPLCController
5
+ from pychemstation.utils.tray_types import FiftyFourVialPlate, Letter, Plate, Num
5
6
  from tests.constants import *
6
7
 
8
+ offline = True
9
+
7
10
 
8
11
  class TestInj(unittest.TestCase):
9
12
  def setUp(self):
10
13
  path_constants = room(254)
11
14
  for path in path_constants:
12
- if not os.path.exists(path):
15
+ if not offline and not os.path.exists(path):
13
16
  self.fail(
14
17
  f"{path} does not exist on your system. If you would like to run tests, please change this path.")
15
18
 
16
- self.hplc_controller = HPLCController(comm_dir=path_constants[0],
19
+ self.hplc_controller = HPLCController(offline=offline,
20
+ comm_dir=path_constants[0],
17
21
  method_dir=path_constants[1],
18
22
  data_dir=path_constants[2],
19
23
  sequence_dir=path_constants[3])
20
- # self.hplc_controller.switch_method(DEFAULT_METHOD)
24
+ if not offline:
25
+ self.hplc_controller.switch_method(DEFAULT_METHOD)
21
26
 
22
27
  def test_load_inj(self):
23
28
  try:
@@ -26,7 +31,8 @@ class TestInj(unittest.TestCase):
26
31
  except Exception as e:
27
32
  self.fail(f"Should have not failed, {e}")
28
33
 
29
-
34
+ def test_plate_number(self):
35
+ self.assertEqual(4096, FiftyFourVialPlate(plate=Plate.ONE, letter=Letter.A, num=Num.FOUR).value())
30
36
 
31
37
 
32
38
  if __name__ == '__main__':
tests/test_proc_rep.py CHANGED
@@ -7,18 +7,43 @@ from pychemstation.analysis.process_report import process_csv_report
7
7
 
8
8
  class TestReport(unittest.TestCase):
9
9
 
10
- def test_process_reporttxt(self):
10
+ def test_build_peak_regex(self):
11
11
  try:
12
12
  # TODO
13
13
  print('yes')
14
14
  except Exception as e:
15
15
  self.fail(f"Should have not failed, {e}")
16
16
 
17
- def test_report_csv(self):
17
+ def test_parse_area_report(self):
18
18
  try:
19
- possible_peaks: Result = process_csv_report(folder_path="0_2025-03-15 19-14-35.D", num=1)
20
- self.assertTrue(len(possible_peaks.ok_value) == 16)
19
+ # TODO
21
20
  print('yes')
21
+ except Exception as e:
22
+ self.fail(f"Should have not failed, {e}")
23
+
24
+ def test_process_export_report(self):
25
+ try:
26
+ import pandas as pd
27
+
28
+ file_path = "/Users/lucyhao/Codes/pychemstation/tests/0_2025-03-15 19-14-35.D/Report00.CSV"
29
+ df = pd.read_csv(file_path, encoding="utf-16")
30
+
31
+ # Print the first column
32
+ print(df)
33
+ except Exception as e:
34
+ self.fail(f"Should have not failed, {e}")
35
+
36
+ def test_process_folder(self):
37
+ try:
38
+ # TODO
39
+ print('yes')
40
+ except Exception as e:
41
+ self.fail(f"Should have not failed, {e}")
42
+
43
+ def test_report_csv(self):
44
+ try:
45
+ report: Result = process_csv_report(folder_path="0_2025-03-15 19-14-35.D")
46
+ print(report)
22
47
  except Exception as e:
23
48
  self.fail(f"Should have not failed: {e}")
24
49