Coverage for python/lsst/pipe/tasks/reserveIsolatedStars.py: 52%

23 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2022-11-15 02:38 -0800

1# This file is part of pipe_tasks. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (https://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# This program is free software: you can redistribute it and/or modify 

10# it under the terms of the GNU General Public License as published by 

11# the Free Software Foundation, either version 3 of the License, or 

12# (at your option) any later version. 

13# 

14# This program is distributed in the hope that it will be useful, 

15# but WITHOUT ANY WARRANTY; without even the implied warranty of 

16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

17# GNU General Public License for more details. 

18# 

19# You should have received a copy of the GNU General Public License 

20# along with this program. If not, see <https://www.gnu.org/licenses/>. 

21 

22"""Task to make a flexible and repeatable selection of reserve stars. 

23""" 

24 

25__all__ = ['ReserveIsolatedStarsConfig', 

26 'ReserveIsolatedStarsTask'] 

27 

28import numpy as np 

29import hashlib 

30 

31import lsst.pex.config as pexConfig 

32import lsst.pipe.base as pipeBase 

33 

34 

35class ReserveIsolatedStarsConfig(pexConfig.Config): 

36 """Configuration for ReserveIsolatedStarsTask.""" 

37 reserve_name = pexConfig.Field( 

38 doc='Name to use for random seed selection hash.', 

39 dtype=str, 

40 default='reserved', 

41 ) 

42 reserve_fraction = pexConfig.RangeField( 

43 doc='Fraction of stars to reserve. None if == 0.', 

44 dtype=float, 

45 default=0.1, 

46 min=0.0, 

47 max=1.0, 

48 inclusiveMin=True, 

49 inclusiveMax=True, 

50 ) 

51 

52 

53class ReserveIsolatedStarsTask(pipeBase.Task): 

54 """Reserve isolated stars with repeatable hash.""" 

55 ConfigClass = ReserveIsolatedStarsConfig 

56 _DefaultName = 'reserve_isolated_stars' 

57 

58 def run(self, nstar, extra=''): 

59 """Retrieve a selection of reserved stars. 

60 

61 Parameters 

62 ---------- 

63 nstar : `int` 

64 Number of stars to select from. 

65 extra : `str`, optional 

66 Extra name to appended to reserve_name, often tract or pixel, 

67 and may be combined with band name. 

68 

69 Returns 

70 ------- 

71 selection : `np.ndarray` (N,) 

72 Boolean index array, with ``True`` for reserved stars. 

73 """ 

74 selection = np.zeros(nstar, dtype=bool) 

75 

76 if self.config.reserve_fraction == 0.0: 

77 return selection 

78 

79 # Full name combines the configured reserve name and the tract. 

80 name = self.config.reserve_name + '_' + extra 

81 # Random seed is the lower 32 bits of the hashed name. 

82 # We use hashlib.sha256 for guaranteed repeatability. 

83 hex_hash = hashlib.sha256(name.encode('UTF-8')).hexdigest() 

84 seed = int('0x' + hex_hash, 0) & 0xFFFFFFFF 

85 

86 rng = np.random.default_rng(seed) 

87 

88 selection[:int(nstar*self.config.reserve_fraction)] = True 

89 rng.shuffle(selection) 

90 

91 return selection