Coverage for src/ufig/plugins/saturate_pixels.py: 100%

31 statements  

« prev     ^ index     » next       coverage.py v7.6.9, created at 2024-12-12 19:08 +0000

1# Copyright (c) 2013 ETH Zurich, Institute of Astronomy, Lukas Gamper 

2# <lukas.gamper@usystems.ch> 

3""" 

4Created on Oct 7, 2013 

5@author: Lukas Gamper 

6""" 

7 

8import numpy as np 

9from ivy.plugin.base_plugin import BasePlugin 

10 

11 

12class Plugin(BasePlugin): 

13 """ 

14 For pixels that exceed the saturation flux, leak the photons in the column direction 

15 until all pixels are under the saturation level. 

16 

17 :param gain: gain of CCD detector (e/ADU) 

18 :param size_x: size of image in x-direction (pixel) 

19 :param size_y: size of image in y-direction (pixel) 

20 :param saturation_level: saturation level in electrons 

21 

22 """ 

23 

24 def __call__(self): 

25 # saturate pixels 

26 saturation = self.ctx.parameters.saturation_level 

27 

28 ox, oy = np.where(self.ctx.image > saturation) 

29 odiff = (self.ctx.image[ox, oy] - saturation) / 2.0 

30 self.ctx.image[ox, oy] = saturation 

31 

32 ix, iy, idiff = ox.copy(), oy.copy(), odiff.copy() 

33 

34 while True: 

35 ix = ix + 1 

36 mask = (idiff > 0) & (ix < self.ctx.parameters.size_y) 

37 if not np.any(mask): 

38 break 

39 ix, iy, idiff = ix[mask], iy[mask], idiff[mask] 

40 self.ctx.image[ix, iy] += idiff 

41 idiff = self.ctx.image[ix, iy] - saturation 

42 mask = idiff > 0 

43 self.ctx.image[ix[mask], iy[mask]] = saturation 

44 

45 while True: 

46 # index is not writable, so use + instead of += 

47 ox = ox - 1 

48 mask = (odiff > 0) & (ox >= 0) 

49 if not np.any(mask): 

50 break 

51 ox, oy, odiff = ox[mask], oy[mask], odiff[mask] 

52 self.ctx.image[ox, oy] += odiff 

53 odiff = self.ctx.image[ox, oy] - saturation 

54 mask = odiff > 0 

55 self.ctx.image[ox[mask], oy[mask]] = saturation 

56 

57 if np.any(self.ctx.image > saturation): # pragma: no cover 

58 lost = np.sum(self.ctx.image[self.ctx.image > saturation] - saturation) 

59 if np.sum(lost) > 0: 

60 print( 

61 f"Lost {np.sum(lost):.0f} photons in saturation" 

62 f" on {lost.size} pixels" 

63 ) 

64 

65 def __str__(self): 

66 return "saturate pixels"