Coverage for src/susi/analyse/contrast.py: 36%
44 statements
« prev ^ index » next coverage.py v7.5.0, created at 2025-06-13 14:15 +0000
« prev ^ index » next coverage.py v7.5.0, created at 2025-06-13 14:15 +0000
1"""
2Compute contrast of a series of frames.
3"""
4from __future__ import annotations
6import glob
7import logging
8import numpy as np
10from ..io import FitsBatch
11from ..base import Config, InsufficientDataException
12from ..utils import MP
14log = logging.getLogger('SUSI')
17class ContrastAnalyser:
18 """
19 Compute contrast of a series of frames.
20 """
21 def __init__(self, config: Config, workers: int = None, upscale: int = 1):
22 self.batch = FitsBatch(config=config, slices=config.cam.data_shape)
23 #: The config to apply (i.e. defines the frame set to analyse)
24 self.config = config
25 #: The number of parallel processes to use
26 self.workers = config.base.workers
27 #: The upscale factor to analyse sub-pixel shifts(default 1)
28 self.upscale = upscale
29 #: Dark image
30 self.dark_file = None
31 #: The result
32 self.result = []
34 def with_dark_correction(self, dark_file):
35 """
36 Chainable configuration method to activate dark img correction
38 :param file: [String] the path of the darks file to use
39 :return: self
40 """
41 self.dark_file = dark_file
42 return self
44 def run(self) -> ContrastAnalyser:
45 self.__load_data()
46 self.__apply_dark()
47 self.__analyse()
48 return self
50 def __load_data(self):
51 file_list = self.config.find_files()
52 log.debug('Loading area %s of all files ...', self.config.cam.data_shape)
53 self.batch.load(file_list, workers=min(len(file_list), 100), sort_by=self.config.base.timestamp_field)
55 def __apply_dark(self):
56 if self.dark_file is not None:
57 self.batch.apply_dark(self.dark_file)
59 def __analyse(self):
60 frames = self.batch.data_array()
61 args = [{'idx': i, 'frame': frames[i]} for i in range(0, len(frames))]
62 log.debug('Compute contrast')
63 result = dict(MP.simultaneous(_compute_contrast, args, workers=self.workers))
64 log.debug('Analysis done, collecting results...')
65 for i in range(len(result.keys())):
66 self.result.append(result[i])
69def _compute_contrast(data: dict) -> tuple:
70 """
71 :param data: a dictionary with
72 - 'idx' the index of the frame
73 - 'frame' the frame to correlate
75 :return: A tuple where element 0 is the idx and element 1 is the contrast value
76 """
77 if data['idx'] % 200 == 0:
78 log.debug('\tProcessing Frame %s', data['idx'])
79 contrast = np.std(data['frame']) / np.mean(data['frame'])
80 return data['idx'], contrast