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

23 statements  

« prev     ^ index     » next       coverage.py v6.4.2, created at 2022-07-16 11:48 +0000

1# 

2# LSST Data Management System 

3# Copyright 2008-2022 AURA/LSST. 

4# 

5# This product includes software developed by the 

6# LSST Project (http://www.lsst.org/). 

7# 

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

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

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

11# (at your option) any later version. 

12# 

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

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

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

16# GNU General Public License for more details. 

17# 

18# You should have received a copy of the LSST License Statement and 

19# the GNU General Public License along with this program. If not, 

20# see <http://www.lsstcorp.org/LegalNotices/>. 

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