Coverage for src/spectroflat/fitting/line.py: 100%

29 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2024-03-28 07:59 +0000

1#!/usr/bin/env python3 

2# -*- coding: utf-8 -*- 

3""" 

4provides Line dataclass 

5 

6@author: hoelken 

7""" 

8import numpy as np 

9 

10from ..base.exceptions import IllegalStateException 

11 

12DER2RAD = np.pi / 180 

13 

14 

15class Line: 

16 """ 

17 Container to store a map of line points 

18 """ 

19 

20 def __init__(self, center, max_length, rot_anker: int = 2048 // 2, line_distance: int = 25, rotation: float = 0.0): 

21 #: The averaged line center 

22 self.center = center 

23 #: rotation point (i.e. central row (center of y-axis)) 

24 self.rot_anker = rot_anker 

25 # The tangent based on the rotation in degree 

26 self.tan_alpha = np.tan(rotation*DER2RAD) 

27 # The start of the lookup area on the x-axis to search for peaks 

28 self.start = self.center - line_distance 

29 # The stop of the lookup area on the x-axis to search for peaks 

30 self.stop = self.center + line_distance 

31 # The max length ot the inspected row 

32 self.max_length = max_length 

33 #: The resulting list of `[(x1,y1), (x2,y2), ...]` points with the line centers 

34 self.map = [] 

35 

36 def add(self, point) -> None: 

37 """ 

38 Add a point to the `Line`. 

39 

40 :param point: The point to add as (x,y) tuple 

41 """ 

42 self.map.append(point) 

43 

44 def gaps(self, coord=1) -> list: 

45 """Compute distance between the `coord` coordinates of the line points""" 

46 self.map.sort(key=lambda tup: tup[coord]) 

47 gaps = [self.map[0][coord]] 

48 for i in range(len(self.map) - 1): 

49 gaps.append(abs(self.map[i+1][coord] - self.map[i][coord])) 

50 return gaps 

51 

52 def area(self, row: int) -> range: 

53 """The lookup area for the line in a given row.""" 

54 shift = self.shift(row) 

55 return range(max(0, self.start + shift), min(self.stop + shift, self.max_length)) 

56 

57 def shift(self, row: int) -> int: 

58 distance = row - self.rot_anker 

59 if self.tan_alpha == 0.0 or distance == 0: 

60 return 0 

61 

62 return int(np.round(distance * self.tan_alpha)) * -1