pytrms 0.9.2__py3-none-any.whl → 0.9.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.
pytrms/measurement.py CHANGED
@@ -1,173 +1,173 @@
1
- import time
2
- from operator import attrgetter
3
- from itertools import chain
4
- from abc import abstractmethod, ABC
5
-
6
- import pandas as pd
7
-
8
- from .readers import IoniTOFReader
9
-
10
- __all__ = ['Measurement', 'PreparingMeasurement', 'RunningMeasurement', 'FinishedMeasurement']
11
-
12
-
13
- class Measurement(ABC):
14
- """Class for PTRMS-measurements and batch processing.
15
-
16
- The start time of the measurement is given by `.time_of_meas`.
17
-
18
- A measurement is iterable over the 'rows' of its data.
19
- In the online case, this would slowly produce the current trace, one
20
- after another.
21
- In the offline case, this would quickly iterate over the traces in the given
22
- measurement file.
23
- """
24
-
25
- def _new_state(self, newstate):
26
- # Note: we get ourselves a nifty little state-machine :)
27
- self.__class__ = newstate
28
-
29
- def start(self, filename=''):
30
- """Start a measurement on the PTR server.
31
-
32
- 'filename' is the filename of the datafile to write to.
33
- If left blank, start a "quick measurement".
34
-
35
- If pointing to a file and the file exist on the (local) server, this raises an exception.
36
- To create unique filenames, use placeholders for year (%Y), month (%m), and so on,
37
- for example `filename=C:/Ionicon/Data/Sauerteig_%Y-%m-%d_%H-%M-%S.h5`.
38
-
39
- see also:
40
- """
41
- # this method must be implemented by each state
42
- raise RuntimeError("can't start %s" % self.__class__)
43
-
44
- # (see also: this docstring)
45
- start.__doc__ += time.strftime.__doc__
46
-
47
- def stop(self):
48
- """Stop the current measurement on the PTR server."""
49
- raise RuntimeError("can't stop %s" % self.__class__)
50
-
51
- @abstractmethod
52
- def __len__(self):
53
- pass
54
-
55
-
56
- class PreparingMeasurement(Measurement):
57
-
58
- @property
59
- def single_spec_duration_ms(self):
60
- return self.ptr.get('ACQ_SRV_SpecTime_ms')
61
-
62
- @single_spec_duration_ms.setter
63
- def single_spec_duration_ms(self, value):
64
- self.ptr.set('ACQ_SRV_SpecTime_ms', int(value), unit='ms')
65
-
66
- @property
67
- def extraction_time_us(self):
68
- return self.ptr.get('ACQ_SRV_ExtractTime')
69
-
70
- @extraction_time_us.setter
71
- def extraction_time_us(self, value):
72
- self.ptr.set('ACQ_SRV_ExtractTime', int(value), unit='us')
73
-
74
- @property
75
- def max_flight_time_us(self):
76
- return self.ptr.get('ACQ_SRV_MaxFlighttime')
77
-
78
- @max_flight_time_us.setter
79
- def max_flight_time_us(self, value):
80
- self.ptr.set('ACQ_SRV_MaxFlighttime', int(value), unit='us')
81
-
82
- @property
83
- def expected_mass_range_amu(self):
84
- return self.ptr.get('ACQ_SRV_ExpectMRange')
85
-
86
- @expected_mass_range_amu.setter
87
- def expected_mass_range_amu(self, value):
88
- self.ptr.set('ACQ_SRV_ExpectMRange', int(value), unit='amu')
89
-
90
- def __init__(self, instrument):
91
- self.ptr = instrument
92
-
93
- def start(self, filename=''):
94
- self.ptr.start_measurement(filename)
95
- self._new_state(RunningMeasurement)
96
-
97
- def __len__(self):
98
- return 0
99
-
100
-
101
- class RunningMeasurement(Measurement):
102
-
103
- def __init__(self, instrument):
104
- self.ptr = instrument
105
-
106
- def stop(self):
107
- self.ptr.stop_measurement()
108
- self._new_state(FinishedMeasurement)
109
-
110
- def __len__(self):
111
- return -1
112
-
113
-
114
- class FinishedMeasurement(Measurement):
115
-
116
- @classmethod
117
- def _check(cls, sourcefiles):
118
- _assumptions = ("incompatible files! "
119
- "sourcefiles must have the same number-of-timebins and "
120
- "the same instrument-type to be collected as a batch")
121
-
122
- assert 1 == len(set(sf.inst_type for sf in sourcefiles)), _assumptions
123
- assert 1 == len(set(sf.number_of_timebins for sf in sourcefiles)), _assumptions
124
-
125
- @property
126
- def number_of_timebins(self):
127
- return next(iter(self.sourcefiles)).number_of_timebins
128
-
129
- @property
130
- def poisson_deadtime_ns(self):
131
- return next(iter(self.sourcefiles)).poisson_deadtime_ns
132
-
133
- @property
134
- def pulsing_period_ns(self):
135
- return next(iter(self.sourcefiles)).pulsing_period_ns
136
-
137
- @property
138
- def single_spec_duration_ms(self):
139
- return next(iter(self.sourcefiles)).single_spec_duration_ms
140
-
141
- @property
142
- def start_delay_ns(self):
143
- return next(iter(self.sourcefiles)).start_delay_ns
144
-
145
- @property
146
- def timebin_width_ps(self):
147
- return next(iter(self.sourcefiles)).timebin_width_ps
148
-
149
- def __init__(self, *filenames, _reader=IoniTOFReader):
150
- if not len(filenames):
151
- raise ValueError("no filename given")
152
-
153
- self.sourcefiles = sorted((_reader(f) for f in filenames), key=attrgetter('time_of_file'))
154
- self._check(self.sourcefiles)
155
-
156
- def read_traces(self, kind='conc', index='abs_cycle', force_original=False):
157
- """Return the timeseries ("traces") of all masses, compounds and settings.
158
-
159
- 'kind' is the type of traces and must be one of 'raw', 'concentration' or
160
- 'corrected'.
161
-
162
- 'index' specifies the desired index and must be one of 'abs_cycle', 'rel_cycle',
163
- 'abs_time' or 'rel_time'.
164
-
165
- """
166
- return pd.concat(sf.read_all(kind, index, force_original) for sf in self.sourcefiles)
167
-
168
- def __iter__(self):
169
- return iter(self.sourcefiles)
170
-
171
- def __len__(self):
172
- return len(self.sourcefiles)
173
-
1
+ import time
2
+ from operator import attrgetter
3
+ from itertools import chain
4
+ from abc import abstractmethod, ABC
5
+
6
+ import pandas as pd
7
+
8
+ from .readers import IoniTOFReader
9
+
10
+ __all__ = ['Measurement', 'PreparingMeasurement', 'RunningMeasurement', 'FinishedMeasurement']
11
+
12
+
13
+ class Measurement(ABC):
14
+ """Class for PTRMS-measurements and batch processing.
15
+
16
+ The start time of the measurement is given by `.time_of_meas`.
17
+
18
+ A measurement is iterable over the 'rows' of its data.
19
+ In the online case, this would slowly produce the current trace, one
20
+ after another.
21
+ In the offline case, this would quickly iterate over the traces in the given
22
+ measurement file.
23
+ """
24
+
25
+ def _new_state(self, newstate):
26
+ # Note: we get ourselves a nifty little state-machine :)
27
+ self.__class__ = newstate
28
+
29
+ def start(self, filename=''):
30
+ """Start a measurement on the PTR server.
31
+
32
+ 'filename' is the filename of the datafile to write to.
33
+ If left blank, start a "quick measurement".
34
+
35
+ If pointing to a file and the file exist on the (local) server, this raises an exception.
36
+ To create unique filenames, use placeholders for year (%Y), month (%m), and so on,
37
+ for example `filename=C:/Ionicon/Data/Sauerteig_%Y-%m-%d_%H-%M-%S.h5`.
38
+
39
+ see also:
40
+ """
41
+ # this method must be implemented by each state
42
+ raise RuntimeError("can't start %s" % self.__class__)
43
+
44
+ # (see also: this docstring)
45
+ start.__doc__ += time.strftime.__doc__
46
+
47
+ def stop(self):
48
+ """Stop the current measurement on the PTR server."""
49
+ raise RuntimeError("can't stop %s" % self.__class__)
50
+
51
+ @abstractmethod
52
+ def __len__(self):
53
+ pass
54
+
55
+
56
+ class PreparingMeasurement(Measurement):
57
+
58
+ @property
59
+ def single_spec_duration_ms(self):
60
+ return self.ptr.get('ACQ_SRV_SpecTime_ms')
61
+
62
+ @single_spec_duration_ms.setter
63
+ def single_spec_duration_ms(self, value):
64
+ self.ptr.set('ACQ_SRV_SpecTime_ms', int(value), unit='ms')
65
+
66
+ @property
67
+ def extraction_time_us(self):
68
+ return self.ptr.get('ACQ_SRV_ExtractTime')
69
+
70
+ @extraction_time_us.setter
71
+ def extraction_time_us(self, value):
72
+ self.ptr.set('ACQ_SRV_ExtractTime', int(value), unit='us')
73
+
74
+ @property
75
+ def max_flight_time_us(self):
76
+ return self.ptr.get('ACQ_SRV_MaxFlighttime')
77
+
78
+ @max_flight_time_us.setter
79
+ def max_flight_time_us(self, value):
80
+ self.ptr.set('ACQ_SRV_MaxFlighttime', int(value), unit='us')
81
+
82
+ @property
83
+ def expected_mass_range_amu(self):
84
+ return self.ptr.get('ACQ_SRV_ExpectMRange')
85
+
86
+ @expected_mass_range_amu.setter
87
+ def expected_mass_range_amu(self, value):
88
+ self.ptr.set('ACQ_SRV_ExpectMRange', int(value), unit='amu')
89
+
90
+ def __init__(self, instrument):
91
+ self.ptr = instrument
92
+
93
+ def start(self, filename=''):
94
+ self.ptr.start_measurement(filename)
95
+ self._new_state(RunningMeasurement)
96
+
97
+ def __len__(self):
98
+ return 0
99
+
100
+
101
+ class RunningMeasurement(Measurement):
102
+
103
+ def __init__(self, instrument):
104
+ self.ptr = instrument
105
+
106
+ def stop(self):
107
+ self.ptr.stop_measurement()
108
+ self._new_state(FinishedMeasurement)
109
+
110
+ def __len__(self):
111
+ return -1
112
+
113
+
114
+ class FinishedMeasurement(Measurement):
115
+
116
+ @classmethod
117
+ def _check(cls, sourcefiles):
118
+ _assumptions = ("incompatible files! "
119
+ "sourcefiles must have the same number-of-timebins and "
120
+ "the same instrument-type to be collected as a batch")
121
+
122
+ assert 1 == len(set(sf.inst_type for sf in sourcefiles)), _assumptions
123
+ assert 1 == len(set(sf.number_of_timebins for sf in sourcefiles)), _assumptions
124
+
125
+ @property
126
+ def number_of_timebins(self):
127
+ return next(iter(self.sourcefiles)).number_of_timebins
128
+
129
+ @property
130
+ def poisson_deadtime_ns(self):
131
+ return next(iter(self.sourcefiles)).poisson_deadtime_ns
132
+
133
+ @property
134
+ def pulsing_period_ns(self):
135
+ return next(iter(self.sourcefiles)).pulsing_period_ns
136
+
137
+ @property
138
+ def single_spec_duration_ms(self):
139
+ return next(iter(self.sourcefiles)).single_spec_duration_ms
140
+
141
+ @property
142
+ def start_delay_ns(self):
143
+ return next(iter(self.sourcefiles)).start_delay_ns
144
+
145
+ @property
146
+ def timebin_width_ps(self):
147
+ return next(iter(self.sourcefiles)).timebin_width_ps
148
+
149
+ def __init__(self, *filenames, _reader=IoniTOFReader):
150
+ if not len(filenames):
151
+ raise ValueError("no filename given")
152
+
153
+ self.sourcefiles = sorted((_reader(f) for f in filenames), key=attrgetter('time_of_file'))
154
+ self._check(self.sourcefiles)
155
+
156
+ def read_traces(self, kind='conc', index='abs_cycle', force_original=False):
157
+ """Return the timeseries ("traces") of all masses, compounds and settings.
158
+
159
+ 'kind' is the type of traces and must be one of 'raw', 'concentration' or
160
+ 'corrected'.
161
+
162
+ 'index' specifies the desired index and must be one of 'abs_cycle', 'rel_cycle',
163
+ 'abs_time' or 'rel_time'.
164
+
165
+ """
166
+ return pd.concat(sf.read_all(kind, index, force_original) for sf in self.sourcefiles)
167
+
168
+ def __iter__(self):
169
+ return iter(self.sourcefiles)
170
+
171
+ def __len__(self):
172
+ return len(self.sourcefiles)
173
+