PyOPIA 2.4.2__tar.gz → 2.4.4__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.
- {pyopia-2.4.2 → pyopia-2.4.4}/PKG-INFO +1 -1
- pyopia-2.4.4/pyopia/__init__.py +1 -0
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/background.py +25 -35
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/classify.py +47 -24
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/instrument/common.py +8 -12
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/instrument/holo.py +10 -19
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/instrument/silcam.py +16 -22
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/instrument/uvp.py +11 -13
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/io.py +5 -3
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/pipeline.py +32 -35
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/process.py +21 -39
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/simulator/silcam.py +23 -23
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/statistics.py +4 -2
- pyopia-2.4.2/pyopia/__init__.py +0 -1
- {pyopia-2.4.2 → pyopia-2.4.4}/LICENSE +0 -0
- {pyopia-2.4.2 → pyopia-2.4.4}/README.md +0 -0
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/cli.py +0 -0
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/exampledata.py +0 -0
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/instrument/__init__.py +0 -0
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/plotting.py +0 -0
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/simulator/__init__.py +0 -0
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/tests/__init__.py +0 -0
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/tests/test_classify.py +0 -0
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/tests/test_notebooks.py +0 -0
- {pyopia-2.4.2 → pyopia-2.4.4}/pyopia/tests/test_pipeline.py +0 -0
- {pyopia-2.4.2 → pyopia-2.4.4}/pyproject.toml +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '2.4.4'
|
|
@@ -8,7 +8,7 @@ def ini_background(bgfiles, load_function):
|
|
|
8
8
|
'''
|
|
9
9
|
Create and initial background stack and average image
|
|
10
10
|
|
|
11
|
-
Parameters
|
|
11
|
+
Parameters
|
|
12
12
|
-----------
|
|
13
13
|
bgfiles : list
|
|
14
14
|
List of strings of filenames to be used in background creation
|
|
@@ -39,7 +39,7 @@ def shift_bgstack_accurate(bgstack, imbg, imnew):
|
|
|
39
39
|
The new background is calculated slowly by computing the mean of all images
|
|
40
40
|
in the background stack.
|
|
41
41
|
|
|
42
|
-
Parameters
|
|
42
|
+
Parameters
|
|
43
43
|
-----------
|
|
44
44
|
bgstack : list
|
|
45
45
|
list of all images in the background stack
|
|
@@ -69,9 +69,9 @@ def shift_bgstack_fast(bgstack, imbg, imnew):
|
|
|
69
69
|
adding the new image (both scaled by the stacklength).
|
|
70
70
|
This is close to a running mean, but not quite.
|
|
71
71
|
|
|
72
|
-
Parameters
|
|
72
|
+
Parameters
|
|
73
73
|
-----------
|
|
74
|
-
|
|
74
|
+
bgstack : list
|
|
75
75
|
list of all images in the background stack
|
|
76
76
|
imbg : uint8
|
|
77
77
|
background image
|
|
@@ -102,7 +102,7 @@ def correct_im_accurate(imbg, imraw):
|
|
|
102
102
|
There is a small chance of clipping of imc in both crushed blacks and blown
|
|
103
103
|
highlights if the background or raw images are very poorly obtained
|
|
104
104
|
|
|
105
|
-
Parameters
|
|
105
|
+
Parameters
|
|
106
106
|
-----------
|
|
107
107
|
imbg : float64
|
|
108
108
|
background averaged image
|
|
@@ -131,7 +131,7 @@ def correct_im_fast(imbg, imraw):
|
|
|
131
131
|
There is high potential for clipping of imc in both crushed blacks an blown
|
|
132
132
|
highlights, especially if the background or raw images are not properly obtained
|
|
133
133
|
|
|
134
|
-
Parameters
|
|
134
|
+
Parameters
|
|
135
135
|
-----------
|
|
136
136
|
imraw : array
|
|
137
137
|
raw image
|
|
@@ -158,7 +158,7 @@ def shift_and_correct(bgstack, imbg, imraw, stacklength, real_time_stats=False):
|
|
|
158
158
|
|
|
159
159
|
This is a wrapper for shift_bgstack and correct_im
|
|
160
160
|
|
|
161
|
-
Parameters
|
|
161
|
+
Parameters
|
|
162
162
|
-----------
|
|
163
163
|
bgstack : list
|
|
164
164
|
list of all images in the background stack
|
|
@@ -200,16 +200,11 @@ class CorrectBackgroundAccurate():
|
|
|
200
200
|
to this class, and the skip_next_steps flag is set in the pipeline Data. No background correction
|
|
201
201
|
is performed during these steps.
|
|
202
202
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
:class:`pyopia.pipeline.Data`
|
|
206
|
-
|
|
207
|
-
containing the following keys:
|
|
203
|
+
Required keys in :class:`pyopia.pipeline.Data`:
|
|
204
|
+
- :attr:`pyopia.pipeline.Data.imraw`
|
|
208
205
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
Parameters:
|
|
212
|
-
-----------
|
|
206
|
+
Parameters
|
|
207
|
+
----------
|
|
213
208
|
bgshift_function : (string, optional)
|
|
214
209
|
Function used to shift the background. Defaults to passing (i.e. static background)
|
|
215
210
|
Available options are 'accurate', 'fast', or 'pass' to apply a statick background correction:
|
|
@@ -225,9 +220,9 @@ class CorrectBackgroundAccurate():
|
|
|
225
220
|
The key in Pipeline.data of the image to be background corrected.
|
|
226
221
|
Defaults to 'imraw'
|
|
227
222
|
|
|
228
|
-
Returns
|
|
229
|
-
|
|
230
|
-
:class:`pyopia.pipeline.Data`
|
|
223
|
+
Returns
|
|
224
|
+
-------
|
|
225
|
+
data : :class:`pyopia.pipeline.Data`
|
|
231
226
|
containing the following new keys:
|
|
232
227
|
|
|
233
228
|
:attr:`pyopia.pipeline.Data.im_corrected`
|
|
@@ -237,11 +232,11 @@ class CorrectBackgroundAccurate():
|
|
|
237
232
|
|
|
238
233
|
:attr:`pyopia.pipeline.Data.imbg`
|
|
239
234
|
|
|
240
|
-
|
|
241
|
-
|
|
235
|
+
Examples
|
|
236
|
+
--------
|
|
242
237
|
Apply moving average using :func:`pyopia.background.shift_bgstack_accurate` :
|
|
243
238
|
|
|
244
|
-
.. code-block::
|
|
239
|
+
.. code-block:: toml
|
|
245
240
|
|
|
246
241
|
[steps.correctbackground]
|
|
247
242
|
pipeline_class = 'pyopia.background.CorrectBackgroundAccurate'
|
|
@@ -250,7 +245,7 @@ class CorrectBackgroundAccurate():
|
|
|
250
245
|
|
|
251
246
|
Apply static background correction:
|
|
252
247
|
|
|
253
|
-
.. code-block::
|
|
248
|
+
.. code-block:: toml
|
|
254
249
|
|
|
255
250
|
[steps.correctbackground]
|
|
256
251
|
pipeline_class = 'pyopia.background.CorrectBackgroundAccurate'
|
|
@@ -311,21 +306,16 @@ class CorrectBackgroundNone():
|
|
|
311
306
|
This simply makes `data['im_corrected'] = data['imraw'] in the pipeline.
|
|
312
307
|
This simply makes `data['im_corrected'] = data['imraw'] in the pipeline.
|
|
313
308
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
:class:`pyopia.pipeline.Data`
|
|
309
|
+
Required keys in :class:`pyopia.pipeline.Data`:
|
|
310
|
+
- :attr:`pyopia.pipeline.Data.imraw`
|
|
317
311
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
:attr:`pyopia.pipeline.Data.imraw`
|
|
321
|
-
|
|
322
|
-
Parameters:
|
|
312
|
+
Parameters
|
|
323
313
|
-----------
|
|
324
|
-
|
|
314
|
+
None
|
|
325
315
|
|
|
326
|
-
Returns
|
|
316
|
+
Returns
|
|
327
317
|
--------
|
|
328
|
-
:class:`pyopia.pipeline.Data`
|
|
318
|
+
data : :class:`pyopia.pipeline.Data`
|
|
329
319
|
containing the following new keys:
|
|
330
320
|
|
|
331
321
|
:attr:`pyopia.pipeline.Data.im_corrected`
|
|
@@ -335,7 +325,7 @@ class CorrectBackgroundNone():
|
|
|
335
325
|
----------------------
|
|
336
326
|
Don't apply any background correction after image load step :
|
|
337
327
|
|
|
338
|
-
.. code-block::
|
|
328
|
+
.. code-block:: toml
|
|
339
329
|
|
|
340
330
|
[steps.nobackground]
|
|
341
331
|
pipeline_class = 'pyopia.background.CorrectBackgroundNone'
|
|
@@ -29,11 +29,13 @@ class Classify():
|
|
|
29
29
|
A classifier class for PyOPIA workflow.
|
|
30
30
|
This is intended as a parent class that can be used as a template for flexible classification methods
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
model_path : str
|
|
35
|
+
path to particle-classifier e.g. '/testdata/model_name/particle_classifier.keras'
|
|
35
36
|
|
|
36
|
-
Example
|
|
37
|
+
Example
|
|
38
|
+
-------
|
|
37
39
|
|
|
38
40
|
.. code-block:: python
|
|
39
41
|
|
|
@@ -41,7 +43,9 @@ class Classify():
|
|
|
41
43
|
|
|
42
44
|
prediction = cl.proc_predict(roi) # roi is an image roi to be classified
|
|
43
45
|
|
|
44
|
-
Note
|
|
46
|
+
Note
|
|
47
|
+
----
|
|
48
|
+
:meth:`Classify.load_model()`
|
|
45
49
|
is run when the :class:`Classify` class is initialised.
|
|
46
50
|
If this is used in combination with multiprocessing then the model must be loaded
|
|
47
51
|
on the process where it will be used and not passed between processers
|
|
@@ -49,20 +53,23 @@ class Classify():
|
|
|
49
53
|
|
|
50
54
|
The config setup looks like this:
|
|
51
55
|
|
|
52
|
-
.. code-block::
|
|
56
|
+
.. code-block:: toml
|
|
53
57
|
|
|
54
58
|
[steps.classifier]
|
|
55
59
|
pipeline_class = 'pyopia.classify.Classify'
|
|
56
60
|
model_path = 'keras_model.h5' # path to trained nn model
|
|
57
61
|
|
|
58
|
-
If
|
|
62
|
+
If '[steps.classifier]' is not defined, the classification will be skipped and no probabilities reported.
|
|
63
|
+
|
|
64
|
+
See Also
|
|
65
|
+
--------
|
|
59
66
|
|
|
60
67
|
If you want to use an example trained model for SilCam data
|
|
61
|
-
(no guarantee of accuracy for other applications), you can get it using
|
|
62
|
-
within the notebooks folder (https://github.com/SINTEF/pyopia/blob/main/notebooks/exampledata.py):
|
|
68
|
+
(no guarantee of accuracy for other applications), you can get it using :mod:`pyopia.exampledata`:
|
|
63
69
|
|
|
64
70
|
.. code-block:: python
|
|
65
71
|
|
|
72
|
+
import pyopia.exampledata
|
|
66
73
|
model_path = exampledata.get_example_model()
|
|
67
74
|
|
|
68
75
|
'''
|
|
@@ -80,8 +87,12 @@ class Classify():
|
|
|
80
87
|
'''
|
|
81
88
|
Load a trained Keras model into the Classify class.
|
|
82
89
|
|
|
83
|
-
|
|
84
|
-
|
|
90
|
+
Parameters
|
|
91
|
+
----------
|
|
92
|
+
model : tf model object
|
|
93
|
+
loaded Keras model
|
|
94
|
+
class_names: list
|
|
95
|
+
names for the model output classes
|
|
85
96
|
'''
|
|
86
97
|
model_path = self.model_path
|
|
87
98
|
|
|
@@ -112,11 +123,15 @@ class Classify():
|
|
|
112
123
|
'''
|
|
113
124
|
Preprocess ROI ready for prediction. example here based on the pysilcam network setup
|
|
114
125
|
|
|
115
|
-
|
|
116
|
-
|
|
126
|
+
Parameters
|
|
127
|
+
----------
|
|
128
|
+
img_input : float
|
|
129
|
+
A particle ROI before preprocessing with range 0-1
|
|
117
130
|
|
|
118
|
-
Returns
|
|
119
|
-
|
|
131
|
+
Returns
|
|
132
|
+
-------
|
|
133
|
+
img_preprocessed : float
|
|
134
|
+
A particle ROI with range 0.-255., corrected and preprocessed, ready for prediction
|
|
120
135
|
'''
|
|
121
136
|
|
|
122
137
|
whitebalanced = np.copy(img_input).astype(np.float64)
|
|
@@ -153,12 +168,16 @@ class Classify():
|
|
|
153
168
|
'''
|
|
154
169
|
Use tensorflow model to classify particles. example here based on the pysilcam network setup.
|
|
155
170
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
171
|
+
Parameters
|
|
172
|
+
----------
|
|
173
|
+
img_preprocessed: float
|
|
174
|
+
A particle ROI arry, corrected and preprocessed using :meth:`Classify.preprocessing`,
|
|
175
|
+
ready for prediction using :meth:`Classify.predict`
|
|
159
176
|
|
|
160
|
-
Returns
|
|
161
|
-
|
|
177
|
+
Returns
|
|
178
|
+
-------
|
|
179
|
+
prediction : array
|
|
180
|
+
The probability of the roi belonging to each class
|
|
162
181
|
'''
|
|
163
182
|
|
|
164
183
|
prediction = self.model(img_preprocessed, training=False)
|
|
@@ -170,11 +189,15 @@ class Classify():
|
|
|
170
189
|
Run pre-processing (:meth:`Classify.preprocessing`) and prediction (:meth:`Classify.predict`)
|
|
171
190
|
using tensorflow model to classify particles. example here based on the pysilcam network setup.
|
|
172
191
|
|
|
173
|
-
|
|
174
|
-
|
|
192
|
+
Parameters
|
|
193
|
+
----------
|
|
194
|
+
img_input : float
|
|
195
|
+
Aparticle ROI with range 0-1 before preprocessing
|
|
175
196
|
|
|
176
|
-
Returns
|
|
177
|
-
|
|
197
|
+
Returns
|
|
198
|
+
-------
|
|
199
|
+
prediction : array
|
|
200
|
+
The probability of the roi belonging to each class
|
|
178
201
|
'''
|
|
179
202
|
img_preprocessed = self.preprocessing(img_input)
|
|
180
203
|
prediction = self.predict(img_preprocessed)
|
|
@@ -7,21 +7,17 @@ import numpy as np
|
|
|
7
7
|
class RectangularImageMask():
|
|
8
8
|
'''PyOpia pipline-compatible class for masking out part of the raw image.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
:class:`pyopia.pipeline.Data`
|
|
13
|
-
containing the following keys:
|
|
10
|
+
Required keys in :class:`pyopia.pipeline.Data`:
|
|
11
|
+
- :attr:`pyopia.pipeline.Data.imraw`
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Parameters:
|
|
18
|
-
-----------
|
|
13
|
+
Parameters
|
|
14
|
+
----------
|
|
19
15
|
mask_bbox : (list, optional)
|
|
20
16
|
Pixel corner coordinates of rectangle to mask (image outside the rectangle is set to 0)
|
|
21
17
|
|
|
22
|
-
Returns
|
|
23
|
-
|
|
24
|
-
:class:`pyopia.pipeline.Data`
|
|
18
|
+
Returns
|
|
19
|
+
-------
|
|
20
|
+
data : :class:`pyopia.pipeline.Data`
|
|
25
21
|
containing the new key:
|
|
26
22
|
|
|
27
23
|
:attr:`pyopia.pipeline.Data.im_masked`
|
|
@@ -31,7 +27,7 @@ class RectangularImageMask():
|
|
|
31
27
|
----------------------
|
|
32
28
|
Put this in your pipeline right after load step to mask out border outside specified pixel coordinates:
|
|
33
29
|
|
|
34
|
-
.. code-block::
|
|
30
|
+
.. code-block:: toml
|
|
35
31
|
|
|
36
32
|
[steps.mask]
|
|
37
33
|
pipeline_class = 'pyopia.instrument.common.RectangularImageMask'
|
|
@@ -134,6 +134,9 @@ class Load():
|
|
|
134
134
|
class Reconstruct():
|
|
135
135
|
'''PyOpia pipline-compatible class for reconstructing a single holo image
|
|
136
136
|
|
|
137
|
+
Required keys in :class:`pyopia.pipeline.Data`:
|
|
138
|
+
- :attr:`pyopia.pipeline.Data.im_corrected`
|
|
139
|
+
|
|
137
140
|
Parameters
|
|
138
141
|
----------
|
|
139
142
|
stack_clean : float
|
|
@@ -143,16 +146,9 @@ class Reconstruct():
|
|
|
143
146
|
inverse_output_option : int
|
|
144
147
|
switch to control optional scaling of output intensity (0=square/default,1=linear)
|
|
145
148
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
:class:`pyopia.pipeline.Data`
|
|
149
|
-
containing the following keys:
|
|
150
|
-
|
|
151
|
-
:attr:`pyopia.pipeline.Data.im_corrected`
|
|
152
|
-
|
|
153
|
-
Returns:
|
|
154
|
-
--------
|
|
155
|
-
:class:`pyopia.pipeline.Data`
|
|
149
|
+
Returns
|
|
150
|
+
-------
|
|
151
|
+
data : :class:`pyopia.pipeline.Data`
|
|
156
152
|
containing the following new keys:
|
|
157
153
|
|
|
158
154
|
:attr:`pyopia.pipeline.Data.im_stack`
|
|
@@ -440,13 +436,8 @@ def find_focus_sobel(im_stack, bbox, increase_depth_of_field):
|
|
|
440
436
|
class Focus():
|
|
441
437
|
'''PyOpia pipline-compatible class for creating a focussed image from an image stack
|
|
442
438
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
:class:`pyopia.pipeline.Data`
|
|
446
|
-
|
|
447
|
-
containing the following keys:
|
|
448
|
-
|
|
449
|
-
:attr:`pyopia.pipeline.Data.im_stack`
|
|
439
|
+
Required keys in :class:`pyopia.pipeline.Data`:
|
|
440
|
+
- :attr:`pyopia.pipeline.Data.im_stack`
|
|
450
441
|
|
|
451
442
|
Parameters
|
|
452
443
|
----------
|
|
@@ -631,8 +622,8 @@ def generate_config(raw_files: str, model_path: str, outfolder: str, output_pref
|
|
|
631
622
|
output_prefix : str
|
|
632
623
|
output_prefix
|
|
633
624
|
|
|
634
|
-
Returns
|
|
635
|
-
|
|
625
|
+
Returns
|
|
626
|
+
-------
|
|
636
627
|
dict
|
|
637
628
|
pipeline_config toml dict
|
|
638
629
|
'''
|
|
@@ -11,10 +11,12 @@ from skimage.exposure import rescale_intensity
|
|
|
11
11
|
def timestamp_from_filename(filename):
|
|
12
12
|
'''get a pandas timestamp from a silcam filename
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Parameters
|
|
15
|
+
----------
|
|
15
16
|
filename (string): silcam filename (.silc)
|
|
16
17
|
|
|
17
|
-
Returns
|
|
18
|
+
Returns
|
|
19
|
+
-------
|
|
18
20
|
timestamp: timestamp from pandas.to_datetime()
|
|
19
21
|
'''
|
|
20
22
|
|
|
@@ -46,16 +48,12 @@ class SilCamLoad():
|
|
|
46
48
|
and extracting the timestamp using
|
|
47
49
|
:func:`pyopia.instrument.silcam.timestamp_from_filename`
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
:class:`pyopia.pipeline.Data`
|
|
52
|
-
containing the following keys:
|
|
51
|
+
Required keys in :class:`pyopia.pipeline.Data`:
|
|
52
|
+
- :attr:`pyopia.pipeline.Data.filename`
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
--------
|
|
58
|
-
:class:`pyopia.pipeline.Data`
|
|
54
|
+
Returns
|
|
55
|
+
-------
|
|
56
|
+
data : :class:`pyopia.pipeline.Data`
|
|
59
57
|
containing the following new keys:
|
|
60
58
|
|
|
61
59
|
:attr:`pyopia.pipeline.Data.timestamp`
|
|
@@ -77,16 +75,12 @@ class SilCamLoad():
|
|
|
77
75
|
class ImagePrep():
|
|
78
76
|
'''PyOpia pipline-compatible class for preparing silcam images for further analysis
|
|
79
77
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
:class:`pyopia.pipeline.Data`
|
|
83
|
-
containing the following keys:
|
|
78
|
+
Required keys in :class:`pyopia.pipeline.Data`:
|
|
79
|
+
- :attr:`pyopia.pipeline.Data.img`
|
|
84
80
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
--------
|
|
89
|
-
:class:`pyopia.pipeline.Data`
|
|
81
|
+
Returns
|
|
82
|
+
-------
|
|
83
|
+
data : :class:`pyopia.pipeline.Data`
|
|
90
84
|
containing the following new keys:
|
|
91
85
|
|
|
92
86
|
:attr:`pyopia.pipeline.Data.im_minimum`
|
|
@@ -120,8 +114,8 @@ def generate_config(raw_files: str, model_path: str, outfolder: str, output_pref
|
|
|
120
114
|
output_prefix : str
|
|
121
115
|
output_prefix
|
|
122
116
|
|
|
123
|
-
Returns
|
|
124
|
-
|
|
117
|
+
Returns
|
|
118
|
+
-------
|
|
125
119
|
dict
|
|
126
120
|
pipeline_config toml dict
|
|
127
121
|
'''
|
|
@@ -11,10 +11,12 @@ import skimage.io
|
|
|
11
11
|
def timestamp_from_filename(filename):
|
|
12
12
|
'''get a pandas timestamp from a UVP vignette image filename
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Parameters
|
|
15
|
+
----------
|
|
15
16
|
filename (string): UVP filename (.png)
|
|
16
17
|
|
|
17
|
-
Returns
|
|
18
|
+
Returns
|
|
19
|
+
-------
|
|
18
20
|
timestamp: timestamp from pandas.to_datetime()
|
|
19
21
|
'''
|
|
20
22
|
|
|
@@ -48,16 +50,12 @@ class UVPLoad():
|
|
|
48
50
|
and extracting the timestamp using
|
|
49
51
|
:func:`pyopia.instrument.uvp.timestamp_from_filename`
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
:class:`pyopia.pipeline.Data`
|
|
54
|
-
containing the following keys:
|
|
55
|
-
|
|
56
|
-
:attr:`pyopia.pipeline.Data.filename`
|
|
53
|
+
Required keys in :class:`pyopia.pipeline.Data`:
|
|
54
|
+
- :attr:`pyopia.pipeline.Data.filename`
|
|
57
55
|
|
|
58
|
-
Returns
|
|
59
|
-
|
|
60
|
-
:class:`pyopia.pipeline.Data`
|
|
56
|
+
Returns
|
|
57
|
+
-------
|
|
58
|
+
data : :class:`pyopia.pipeline.Data`
|
|
61
59
|
containing the following new keys:
|
|
62
60
|
|
|
63
61
|
:attr:`pyopia.pipeline.Data.timestamp`
|
|
@@ -90,8 +88,8 @@ def generate_config(raw_files: str, model_path: str, outfolder: str, output_pref
|
|
|
90
88
|
output_prefix : str
|
|
91
89
|
output_prefix
|
|
92
90
|
|
|
93
|
-
Returns
|
|
94
|
-
|
|
91
|
+
Returns
|
|
92
|
+
-------
|
|
95
93
|
dict
|
|
96
94
|
pipeline_config toml dict
|
|
97
95
|
'''
|
|
@@ -314,12 +314,14 @@ class StatsToDisc():
|
|
|
314
314
|
|
|
315
315
|
Returns
|
|
316
316
|
-------
|
|
317
|
-
data :
|
|
318
|
-
data from pipeline
|
|
317
|
+
data : :class:`pyopia.pipeline.Data`
|
|
318
|
+
data from the pipeline
|
|
319
319
|
|
|
320
|
+
Example
|
|
321
|
+
-------
|
|
320
322
|
Example config for pipeline useage:
|
|
321
323
|
|
|
322
|
-
.. code-block::
|
|
324
|
+
.. code-block:: toml
|
|
323
325
|
|
|
324
326
|
[steps.output]
|
|
325
327
|
pipeline_class = 'pyopia.io.StatsToDisc'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'''
|
|
2
2
|
Module for managing the PyOpia processing pipeline
|
|
3
3
|
|
|
4
|
-
Refer to :class:`Pipeline` for examples of how to process datasets and images
|
|
4
|
+
Refer to the :class:`Pipeline` class documentation for examples of how to process datasets and images
|
|
5
5
|
'''
|
|
6
6
|
from typing import TypedDict
|
|
7
7
|
import datetime
|
|
@@ -18,15 +18,15 @@ logger = logging.getLogger()
|
|
|
18
18
|
|
|
19
19
|
class Pipeline():
|
|
20
20
|
'''The processing pipeline class
|
|
21
|
-
================================
|
|
22
21
|
|
|
22
|
+
Note
|
|
23
|
+
----
|
|
23
24
|
The classes called in the Pipeline steps can be modified, and the names of the steps changed.
|
|
24
25
|
New steps can be added or deleted as required.
|
|
25
26
|
|
|
26
27
|
The classes called in the Pipeline steps need to take a TOML-formatted dictionary as input
|
|
27
|
-
and return a dictionary of data as output.
|
|
28
|
-
|
|
29
|
-
or variables generated by each step can be passed along the pipeline.
|
|
28
|
+
and return a dictionary of data as output. This common data dictionary: :class:`pyopia.pipeline.Data`
|
|
29
|
+
is therefore passed between steps so that data or variables generated by each step can be passed along the pipeline.
|
|
30
30
|
|
|
31
31
|
By default, the step names: `initial`, `classifier`, and `createbackground`
|
|
32
32
|
are run when initialising `Pipeline`.
|
|
@@ -38,15 +38,15 @@ class Pipeline():
|
|
|
38
38
|
The step called 'classifier' must return a dict containing:
|
|
39
39
|
:attr:`pyopia.pipeline.Data.cl` in order to run successfully.
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
`Pipeline.run()` takes a string as input.
|
|
45
|
-
This string is put into the `data` dict available to the steps in the pipeline as `data['filename']`.
|
|
41
|
+
:func:`Pipeline.run()` takes a string as input.
|
|
42
|
+
This string is put into :class:`pyopia.pipeline.Data`, available to the steps in the pipeline as `data['filename']`.
|
|
46
43
|
This is intended for use in looping through several files during processing, so run can be
|
|
47
44
|
called multiple times with different filenames.
|
|
48
45
|
|
|
49
|
-
Examples
|
|
46
|
+
Examples
|
|
47
|
+
--------
|
|
48
|
+
|
|
49
|
+
Examples of setting up and running a pipeline
|
|
50
50
|
can be found for SilCam `here <https://github.com/SINTEF/pyopia/blob/main/notebooks/pipeline-holo.ipynb>`_,
|
|
51
51
|
and holographic analysis `here <https://github.com/SINTEF/pyopia/blob/main/notebooks/pipeline-holo.ipynb>`_.
|
|
52
52
|
|
|
@@ -54,7 +54,7 @@ class Pipeline():
|
|
|
54
54
|
and for holographic analysis `here <https://github.com/SINTEF/pyopia/blob/main/notebooks/config-holo.toml>`_.
|
|
55
55
|
|
|
56
56
|
You can check the workflow used by reading the steps from the metadata in the
|
|
57
|
-
output file using :func:`pyopia.
|
|
57
|
+
output file using :func:`pyopia.io.steps_from_xstats`
|
|
58
58
|
|
|
59
59
|
More examples and guides can be found on the `PyOIA By Example <https://pyopia.readthedocs.io/en/latest/examples.html>`_ page.
|
|
60
60
|
'''
|
|
@@ -94,11 +94,13 @@ class Pipeline():
|
|
|
94
94
|
stats : DataFrame
|
|
95
95
|
particle statistics associated with 'filename'
|
|
96
96
|
|
|
97
|
-
Note
|
|
97
|
+
Note
|
|
98
|
+
----
|
|
99
|
+
The returned stats from this function are single-image only and not appended
|
|
98
100
|
if you loop through several filenames! It is recommended to use this step in the pipeline
|
|
99
101
|
for properly appending data into NetCDF format when processing several files.
|
|
100
102
|
|
|
101
|
-
.. code-block::
|
|
103
|
+
.. code-block:: toml
|
|
102
104
|
|
|
103
105
|
[steps.output]
|
|
104
106
|
pipeline_class = 'pyopia.io.StatsDisc'
|
|
@@ -187,15 +189,6 @@ class Pipeline():
|
|
|
187
189
|
|
|
188
190
|
class Data(TypedDict):
|
|
189
191
|
'''Data dictionary which is passed between :class:`pyopia.pipeline` steps.
|
|
190
|
-
|
|
191
|
-
For debugging, you can use :class:`pyopia.pipeline.ReturnData`
|
|
192
|
-
at the end of a steps dictionary to return of this Data dictionary
|
|
193
|
-
for exploratory purposes.
|
|
194
|
-
|
|
195
|
-
In future this may be better as a data class with slots (from python 3.10).
|
|
196
|
-
|
|
197
|
-
This is an example of a link to the imc key doc:
|
|
198
|
-
:attr:`pyopia.pipeline.Data.im_corrected`
|
|
199
192
|
'''
|
|
200
193
|
|
|
201
194
|
raw_files: str
|
|
@@ -335,16 +328,16 @@ def build_steps(toml_steps):
|
|
|
335
328
|
|
|
336
329
|
|
|
337
330
|
class FilesToProcess:
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
File list from glob will be sorted.
|
|
331
|
+
'''Build file list from glob pattern if specified.
|
|
332
|
+
Create FilesToProcess.chunked_files is chunks specified
|
|
333
|
+
File list from glob will be sorted.
|
|
342
334
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
335
|
+
Parameters
|
|
336
|
+
----------
|
|
337
|
+
glob_pattern : str, optional
|
|
338
|
+
Glob pattern, by default None
|
|
339
|
+
'''
|
|
340
|
+
def __init__(self, glob_pattern=None):
|
|
348
341
|
self.files = None
|
|
349
342
|
self.background_files = []
|
|
350
343
|
self.chunked_files = []
|
|
@@ -382,7 +375,7 @@ class FilesToProcess:
|
|
|
382
375
|
|
|
383
376
|
Parameters
|
|
384
377
|
----------
|
|
385
|
-
|
|
378
|
+
num_chunks : int
|
|
386
379
|
number of chunks to produce (must be at least 1)
|
|
387
380
|
'''
|
|
388
381
|
if num_chunks < 1:
|
|
@@ -404,8 +397,12 @@ class FilesToProcess:
|
|
|
404
397
|
chunk = [chunk.insert(0, bg_file) for bg_file in reversed(self.background_files[-average_window:])]
|
|
405
398
|
|
|
406
399
|
def build_initial_background_files(self, average_window=0):
|
|
407
|
-
'''
|
|
408
|
-
|
|
400
|
+
'''Create a list of files to use for initializing the background in the first chunk
|
|
401
|
+
|
|
402
|
+
Parameters
|
|
403
|
+
----------
|
|
404
|
+
average_window : int, optional
|
|
405
|
+
number of images to use in creating a background, by default 0
|
|
409
406
|
'''
|
|
410
407
|
self.background_files = []
|
|
411
408
|
for f in self.files[0:average_window]:
|
|
@@ -481,15 +481,10 @@ def statextract(imbw, timestamp, imc,
|
|
|
481
481
|
class Segment():
|
|
482
482
|
'''PyOpia pipline-compatible class for calling segment
|
|
483
483
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
:class:`pyopia.pipeline.Data`
|
|
484
|
+
Required keys in :class:`pyopia.pipeline.Data`:
|
|
485
|
+
- :attr:`pyopia.pipeline.Data.im_corrected`
|
|
487
486
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
:attr:`pyopia.pipeline.Data.im_corrected`
|
|
491
|
-
|
|
492
|
-
Parameters:
|
|
487
|
+
Parameters
|
|
493
488
|
----------
|
|
494
489
|
minimum_area : (int, optional)
|
|
495
490
|
minimum number of pixels for particle detection. Defaults to 12.
|
|
@@ -501,9 +496,9 @@ class Segment():
|
|
|
501
496
|
The key in Pipeline.data of the image to be segmented.
|
|
502
497
|
Defaults to 'im_corrected'
|
|
503
498
|
|
|
504
|
-
Returns
|
|
505
|
-
|
|
506
|
-
:class:`pyopia.pipeline.Data`
|
|
499
|
+
Returns
|
|
500
|
+
-------
|
|
501
|
+
data : :class:`pyopia.pipeline.Data`
|
|
507
502
|
containing the following new keys:
|
|
508
503
|
|
|
509
504
|
:attr:`pyopia.pipeline.Data.imbw`
|
|
@@ -529,19 +524,12 @@ class Segment():
|
|
|
529
524
|
class CalculateStats():
|
|
530
525
|
'''PyOpia pipline-compatible class for calling statextract
|
|
531
526
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
containing the following keys:
|
|
537
|
-
|
|
538
|
-
:attr:`pyopia.pipeline.Data.imbw`
|
|
539
|
-
|
|
540
|
-
:attr:`pyopia.pipeline.Data.timestamp`
|
|
541
|
-
|
|
542
|
-
:attr:`pyopia.pipeline.Data.cl`
|
|
527
|
+
Required keys in :class:`pyopia.pipeline.Data`:
|
|
528
|
+
- :attr:`pyopia.pipeline.Data.imbw`
|
|
529
|
+
- :attr:`pyopia.pipeline.Data.timestamp`
|
|
530
|
+
- :attr:`pyopia.pipeline.Data.cl`
|
|
543
531
|
|
|
544
|
-
Parameters
|
|
532
|
+
Parameters
|
|
545
533
|
----------
|
|
546
534
|
max_coverage : (int, optional)
|
|
547
535
|
percentage of the image that is allowed to be filled by particles. Defaults to 30.
|
|
@@ -560,9 +548,9 @@ class CalculateStats():
|
|
|
560
548
|
Key of an image in Pipeline.data that is used for outputting ROIs and passing to the classifier.
|
|
561
549
|
Defaults to 'im_corrected'
|
|
562
550
|
|
|
563
|
-
Returns
|
|
564
|
-
|
|
565
|
-
:class:`pyopia.pipeline.Data`
|
|
551
|
+
Returns
|
|
552
|
+
-------
|
|
553
|
+
data : :class:`pyopia.pipeline.Data`
|
|
566
554
|
containing the following new keys:
|
|
567
555
|
|
|
568
556
|
:attr:`pyopia.pipeline.Data.stats`
|
|
@@ -606,23 +594,17 @@ class CalculateStats():
|
|
|
606
594
|
class CalculateImageStats():
|
|
607
595
|
'''PyOpia pipline-compatible class for collecting whole-image statistics
|
|
608
596
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
containing the following keys:
|
|
614
|
-
|
|
615
|
-
:attr:`pyopia.pipeline.Data.stats`
|
|
616
|
-
|
|
617
|
-
:attr:`pyopia.pipeline.Data.timestamp`
|
|
597
|
+
Required keys in :class:`pyopia.pipeline.Data`:
|
|
598
|
+
- :attr:`pyopia.pipeline.Data.stats`
|
|
599
|
+
- :attr:`pyopia.pipeline.Data.timestamp`
|
|
618
600
|
|
|
619
|
-
Parameters
|
|
601
|
+
Parameters
|
|
620
602
|
----------
|
|
621
603
|
None
|
|
622
604
|
|
|
623
|
-
Returns
|
|
624
|
-
|
|
625
|
-
:class:`pyopia.pipeline.Data`
|
|
605
|
+
Returns
|
|
606
|
+
-------
|
|
607
|
+
data : :class:`pyopia.pipeline.Data`
|
|
626
608
|
containing the following new keys:
|
|
627
609
|
|
|
628
610
|
:attr:`pyopia.pipeline.Data.image_stats`
|
|
@@ -15,15 +15,7 @@ from pyopia.pipeline import Pipeline
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class SilcamSimulator():
|
|
18
|
-
|
|
19
|
-
d50=1000,
|
|
20
|
-
MinD=10,
|
|
21
|
-
PIX_SIZE=28,
|
|
22
|
-
PATH_LENGTH=40,
|
|
23
|
-
imx=2048,
|
|
24
|
-
imy=2448,
|
|
25
|
-
nims=50):
|
|
26
|
-
'''SilCam simulator
|
|
18
|
+
'''SilCam simulator
|
|
27
19
|
|
|
28
20
|
Parameters
|
|
29
21
|
----------
|
|
@@ -44,20 +36,28 @@ class SilcamSimulator():
|
|
|
44
36
|
nims : int, optional
|
|
45
37
|
number of images to simulate, by default 50
|
|
46
38
|
|
|
47
|
-
Example
|
|
48
|
-
|
|
39
|
+
Example
|
|
40
|
+
-------
|
|
49
41
|
|
|
50
|
-
|
|
51
|
-
from pyopia.simulator.silcam import SilcamSimulator
|
|
42
|
+
.. code-block:: python
|
|
52
43
|
|
|
53
|
-
|
|
54
|
-
sim.check_convergence()
|
|
55
|
-
sim.synthesize()
|
|
56
|
-
sim.process_synthetic_image()
|
|
57
|
-
sim.plot()
|
|
58
|
-
```
|
|
44
|
+
from pyopia.simulator.silcam import SilcamSimulator
|
|
59
45
|
|
|
60
|
-
|
|
46
|
+
sim = SilcamSimulator()
|
|
47
|
+
sim.check_convergence()
|
|
48
|
+
sim.synthesize()
|
|
49
|
+
sim.process_synthetic_image()
|
|
50
|
+
sim.plot()
|
|
51
|
+
|
|
52
|
+
'''
|
|
53
|
+
def __init__(self, total_volume_concentration=1000,
|
|
54
|
+
d50=1000,
|
|
55
|
+
MinD=10,
|
|
56
|
+
PIX_SIZE=28,
|
|
57
|
+
PATH_LENGTH=40,
|
|
58
|
+
imx=2048,
|
|
59
|
+
imy=2448,
|
|
60
|
+
nims=50):
|
|
61
61
|
self.total_volume_concentration = total_volume_concentration
|
|
62
62
|
self.d50 = d50
|
|
63
63
|
self.MinD = MinD
|
|
@@ -97,7 +97,7 @@ class SilcamSimulator():
|
|
|
97
97
|
'''Check statistical convergence of randomly selected size distributions
|
|
98
98
|
over the `nims`number of images
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
Parameters
|
|
101
101
|
----------
|
|
102
102
|
data['volume_distribution'] : array
|
|
103
103
|
volume distribution of shape (nims, dias)
|
|
@@ -164,7 +164,7 @@ class SilcamSimulator():
|
|
|
164
164
|
def synthesize(self):
|
|
165
165
|
'''Synthesize an image and measure droplets
|
|
166
166
|
|
|
167
|
-
|
|
167
|
+
Parameters
|
|
168
168
|
----------
|
|
169
169
|
data['synthetic_image_data']['image'] : array
|
|
170
170
|
synthetic image
|
|
@@ -205,7 +205,7 @@ class SilcamSimulator():
|
|
|
205
205
|
def process_synthetic_image(self):
|
|
206
206
|
'''Put the synthetic image `data['synthetic_image_data']['image']` through a basic pyopia processing pipeline
|
|
207
207
|
|
|
208
|
-
|
|
208
|
+
Parameters
|
|
209
209
|
----------
|
|
210
210
|
data['synthetic_image_data']['pyopia_processed_volume_distribution'] : array
|
|
211
211
|
pyopia processed volume distribution associated with `dias`size classes
|
|
@@ -523,7 +523,8 @@ def get_j(dias, number_distribution):
|
|
|
523
523
|
number_distribution : array
|
|
524
524
|
number distribution in number per micron per litre
|
|
525
525
|
|
|
526
|
-
Returns
|
|
526
|
+
Returns
|
|
527
|
+
-------
|
|
527
528
|
junge_slope : float
|
|
528
529
|
Junge slope from fitting of psd between 150 and 300um
|
|
529
530
|
'''
|
|
@@ -977,7 +978,8 @@ def vd_to_nd(volume_distribution, dias):
|
|
|
977
978
|
def vd_to_nc(volume_distribution, dias):
|
|
978
979
|
'''calculate number concentration from volume distribution
|
|
979
980
|
|
|
980
|
-
|
|
981
|
+
Parameters
|
|
982
|
+
----------
|
|
981
983
|
volume_distribution : array
|
|
982
984
|
particle volume distribution calculated from vd_from_stats()
|
|
983
985
|
dias : array
|
pyopia-2.4.2/pyopia/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '2.4.2'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|