PyOPIA 2.6.1__tar.gz → 2.6.2__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.
Files changed (26) hide show
  1. {pyopia-2.6.1 → pyopia-2.6.2}/PKG-INFO +1 -1
  2. pyopia-2.6.2/pyopia/__init__.py +1 -0
  3. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/cli.py +16 -10
  4. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/pipeline.py +32 -4
  5. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/process.py +1 -1
  6. pyopia-2.6.1/pyopia/__init__.py +0 -1
  7. {pyopia-2.6.1 → pyopia-2.6.2}/LICENSE +0 -0
  8. {pyopia-2.6.1 → pyopia-2.6.2}/README.md +0 -0
  9. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/background.py +0 -0
  10. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/classify.py +0 -0
  11. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/exampledata.py +0 -0
  12. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/instrument/__init__.py +0 -0
  13. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/instrument/common.py +0 -0
  14. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/instrument/holo.py +0 -0
  15. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/instrument/silcam.py +0 -0
  16. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/instrument/uvp.py +0 -0
  17. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/io.py +0 -0
  18. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/plotting.py +0 -0
  19. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/simulator/__init__.py +0 -0
  20. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/simulator/silcam.py +0 -0
  21. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/statistics.py +0 -0
  22. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/tests/__init__.py +0 -0
  23. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/tests/test_classify.py +0 -0
  24. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/tests/test_notebooks.py +0 -0
  25. {pyopia-2.6.1 → pyopia-2.6.2}/pyopia/tests/test_pipeline.py +0 -0
  26. {pyopia-2.6.1 → pyopia-2.6.2}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyOPIA
3
- Version: 2.6.1
3
+ Version: 2.6.2
4
4
  Summary: A Python Ocean Particle Image Analysis toolbox.
5
5
  Home-page: https://github.com/sintef/pyopia
6
6
  Keywords: Ocean,Particles,Imaging,Measurement,Size distribution
@@ -0,0 +1 @@
1
+ __version__ = '2.6.2'
@@ -15,6 +15,7 @@ import rich.progress
15
15
  import pandas as pd
16
16
  import threading
17
17
 
18
+ import pyopia
18
19
  import pyopia.background
19
20
  import pyopia.instrument.silcam
20
21
  import pyopia.instrument.holo
@@ -117,25 +118,27 @@ def generate_config(instrument: str, raw_files: str, model_path: str, outfolder:
117
118
 
118
119
 
119
120
  @app.command()
120
- def process(config_filename: str, num_chunks: int = 1):
121
+ def process(config_filename: str, num_chunks: int = 1, strategy: str = 'block'):
121
122
  '''Run a PyOPIA processing pipeline based on given a config.toml
122
123
 
123
124
  Parameters
124
125
  ----------
125
126
  config_filename : str
126
- config filename
127
+ Config filename
128
+
127
129
  numchunks : int, optional
128
- split the dataset into chucks, and process in parallell, by default 1
130
+ Split the dataset into chucks, and process in parallell, by default 1
129
131
 
132
+ strategy : str, optional
133
+ Strategy to use for chunking dataset, either `block` or `interleave`. Defult: `block`
130
134
  '''
131
- from pyopia.io import load_toml
132
- from pyopia.pipeline import Pipeline
133
-
134
135
  t1 = time.time()
135
136
 
136
137
  with Progress(transient=True) as progress:
138
+ progress.console.print(f"[blue]PYOPIA VERSION {pyopia.__version__}")
139
+
137
140
  progress.console.print("[blue]LOAD CONFIG")
138
- pipeline_config = load_toml(config_filename)
141
+ pipeline_config = pyopia.io.load_toml(config_filename)
139
142
 
140
143
  setup_logging(pipeline_config)
141
144
  logger = logging.getLogger('rich')
@@ -144,11 +147,14 @@ def process(config_filename: str, num_chunks: int = 1):
144
147
  check_chunks(num_chunks, pipeline_config)
145
148
 
146
149
  progress.console.print("[blue]OBTAIN IMAGE LIST")
147
- raw_files = pyopia.pipeline.FilesToProcess(pipeline_config['general']['raw_files'])
148
150
  conf_corrbg = pipeline_config['steps'].get('correctbackground', dict())
149
151
  average_window = conf_corrbg.get('average_window', 0)
150
152
  bgshift_function = conf_corrbg.get('bgshift_function', 'pass')
151
- raw_files.prepare_chunking(num_chunks, average_window, bgshift_function)
153
+ raw_files = pyopia.pipeline.FilesToProcess(pipeline_config['general']['raw_files'])
154
+ raw_files.prepare_chunking(num_chunks, average_window, bgshift_function, strategy=strategy)
155
+
156
+ # Write the dataset list of images to a text file
157
+ raw_files.to_filelist_file('filelist.txt')
152
158
 
153
159
  progress.console.print('[blue]PREPARE FOLDERS')
154
160
  if 'output' not in pipeline_config['steps']:
@@ -167,7 +173,7 @@ def process(config_filename: str, num_chunks: int = 1):
167
173
  progress.console.print("[blue]INITIALISE PIPELINE")
168
174
 
169
175
  def process_file_list(file_list, c):
170
- processing_pipeline = Pipeline(pipeline_config)
176
+ processing_pipeline = pyopia.pipeline.Pipeline(pipeline_config)
171
177
 
172
178
  with get_custom_progress_bar(f'[blue]Processing progress (chunk {c})', disable=c != 0) as pbar:
173
179
  for filename in pbar.track(file_list, description=f'[blue]Processing progress (chunk {c})'):
@@ -373,25 +373,53 @@ class FilesToProcess:
373
373
  with open(path_to_filelist, 'w') as fh:
374
374
  [fh.writelines(L + '\n') for L in self.files]
375
375
 
376
- def prepare_chunking(self, num_chunks, average_window, bgshift_function):
376
+ with open(path_to_filelist+'.chunks', 'w') as fh:
377
+ for i, chunk in enumerate(self.chunked_files):
378
+ fh.write(f'--- Chunk {i}, N = {len(chunk)} ---\n')
379
+ [fh.writelines(L + '\n') for L in chunk]
380
+
381
+ def prepare_chunking(self, num_chunks, average_window, bgshift_function, strategy='block'):
382
+ '''Chunk the file list and add initial background files to each chunk
383
+
384
+ Parameters
385
+ ----------
386
+ num_chunks : int
387
+ Number of chunks to produce (must be at least 1)
388
+ average_window : int
389
+ Number of images to use for background correction
390
+ bgshift_function : str
391
+ Background update strategy, either `pass` (static background) or `accurate`
392
+ strategy : str, optional
393
+ Strategy to use for chunking dataset, either `block` or `interleave`. Defult: `block`
394
+ '''
377
395
  if num_chunks > len(self.files) // 2:
378
396
  raise RuntimeError('Number of chunks exceeds more than half the number of files to process. Use less chunks.')
379
- self.chunk_files(num_chunks)
397
+ self.chunk_files(num_chunks, strategy)
380
398
  self.build_initial_background_files(average_window=average_window)
381
399
  self.insert_bg_files_into_chunks(bgshift_function=bgshift_function)
382
400
 
383
- def chunk_files(self, num_chunks: int):
401
+ def chunk_files(self, num_chunks: int, strategy: str = 'block'):
384
402
  '''Chunk the file list and create FilesToProcess.chunked_files
385
403
 
386
404
  Parameters
387
405
  ----------
388
406
  num_chunks : int
389
407
  number of chunks to produce (must be at least 1)
408
+ strategy : str, optional
409
+ Strategy to use for chunking dataset, either `block` or `interleave`. Defult: `block`
390
410
  '''
391
411
  if num_chunks < 1:
392
412
  raise RuntimeError('You must have at least one chunk')
393
413
  chunk_length = int(np.ceil(len(self.files) / num_chunks))
394
- self.chunked_files = [self.files[i:i + chunk_length] for i in range(0, len(self.files), chunk_length)]
414
+ if strategy == 'block':
415
+ logging.debug('Chunking file list with strategy: block')
416
+ self.chunked_files = [self.files[i:i + chunk_length] for i in range(0, len(self.files), chunk_length)]
417
+ elif strategy == 'interleave':
418
+ logging.debug('Chunking file list with strategy: interleave')
419
+ self.chunked_files = [self.files[i::num_chunks] for i in range(0, num_chunks)]
420
+ else:
421
+ logging.debug(f'Invalid chunking strategy: {strategy}')
422
+ raise RuntimeError(f'Unknown strategy: {strategy}. Should be either block or interleave')
395
423
 
396
424
  def insert_bg_files_into_chunks(self, bgshift_function='pass'):
397
425
  average_window = len(self.background_files)
@@ -623,7 +623,7 @@ class CalculateImageStats():
623
623
 
624
624
  # Add image "global" statistics, separate from the particle stats above (stats)
625
625
  image_saturation = np.nan if stats.empty else stats['saturation'].values[0]
626
- data['image_stats'].loc[data['timestamp'], 'filename'] = getattr(data, 'filename', '')
626
+ data['image_stats'].loc[data['timestamp'], 'filename'] = data.get('filename', '')
627
627
  data['image_stats'].loc[data['timestamp'], 'particle_count'] = int(stats.shape[0])
628
628
  data['image_stats'].loc[data['timestamp'], 'saturation'] = image_saturation
629
629
 
@@ -1 +0,0 @@
1
- __version__ = '2.6.1'
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