diff --git a/templates/index.html b/templates/index.html index e2fd5767bfa218a1f4203d87f736fba7d2a2c123..38b595670c16d0dc0b11d69bcede4568c5a9fe65 100644 --- a/templates/index.html +++ b/templates/index.html @@ -23,6 +23,7 @@ <p style="font-size: 23px">Linearity: <span id="linearity" style="color: red"></span></p> <p style="font-size: 23px">Max spot size: <span id="max_spot_size" style="color: red"></span></p> <p style="font-size: 23px">Ion roundness: <span id="roundness" style="color: red"></span>%</p> + <p style="font-size: 23px">Fit error: <span id="fit_error" style="color: red"></span> (Moving avg: <span id="fit_avg" style="color: red"></span>) <span id="response" style="color: red"></span></p> <h2 style="font-size: 35px">Stream:</h2> <span class="img-container"> <img src="{{ url_for('video_feed') }}" width="450" height="350" alt="Streaming"> @@ -36,6 +37,12 @@ for (let key in jsonResponse) { document.getElementById(key).innerText = jsonResponse[key]; } + if (Number(document.getElementById("fit_avg").innerText) >= 20) { + document.getElementById("response").innerText = "Calibration needed!" + } + else{ + document.getElementById("response").innerText = "" + } }; setInterval(() => { diff --git a/tools.py b/tools.py index 9d620a3c7c77dd26192e2b1fd2196f9d013d3623..4f1b284415455447681e031a08a1a723006bde6b 100644 --- a/tools.py +++ b/tools.py @@ -48,6 +48,7 @@ class Main: # Instantiate classes self.memory = Memory() self.count_avg = MovingAverage() + self.fit_avg = FitAverage() self.trap_state = TrapState() # Define class attributes @@ -87,7 +88,9 @@ class Main: 'reorder_avg': self.count_avg.moving_avg, 'reorder_flag': -1, 'max_spot_size': -1, - 'roundness': -1 + 'roundness': -1, + 'fit_error': -1, + 'fit_avg': -1 } elif not ion_cloud: @@ -121,7 +124,8 @@ class Main: linearity = ion_linearity(coord) if len(coord) > 1 and dist_factor is not None: - coord = dark_ions(img, coord, dist_factor) + coord, fit_error = dark_ions(img, coord, dist_factor) + self.fit_avg.update_value(fit_error) else: roundness = 0 max_int, num_pix = (0, 0) @@ -163,7 +167,9 @@ class Main: 'reorder_avg': self.count_avg.moving_avg, 'reorder_flag': reorder_flag, 'max_spot_size': int(max_spot_size), - 'roundness': int(roundness) + 'roundness': int(roundness), + 'fit_error': int(fit_error), + 'fit_avg': int(self.fit_avg.moving_avg) } def _save_in_memory(self, output): @@ -278,6 +284,38 @@ class Memory: return max_value +class FitAverage: + """ + Compute moving average of fit error + """ + def __init__(self): + self.value = 0 + self.value_history = [0] + self.moving_avg = 0 + + self.update_history() + + def update_history(self): + """ + Every second update history and compute moving average. + """ + _thread = threading.Timer(1, self.update_history) + _thread.daemon = True + _thread.start() + self.value_history.append(self.value) + if len(self.value_history) > 60: + self.value_history.pop(0) + self.moving_avg = np.mean(self.value_history) + min_val = min(self.value_history) + self.value_history = [i - min_val for i in self.value_history] + self.value -= min_val + + def update_value(self, value): + """ + Update value. + """ + self.value = value + class MovingAverage: """ Keep record of number of reorders of the ions and return a moving average of @@ -603,7 +641,7 @@ def dark_ions(image, coord, dist_factor): # warnings.warn("Loss is too high... " # "Try calculating a new factor value using calibrate() function.") - return coord + return coord, loss.min() def acquire_semaphore_read(name: str, timeout=1):