Coverage for python/lsst/summit/extras/annotations.py: 37%

35 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-03-30 13:58 +0000

1# This file is part of summit_extras. 

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 

22from lsst.summit.extras.imageSorter import TAGS, ImageSorter 

23 

24 

25def _idTrans(dataIdDictOrTuple): 

26 """Take a dataId and turn it into the internal tuple format.""" 

27 if isinstance(dataIdDictOrTuple, tuple): 27 ↛ 28line 27 didn't jump to line 28, because the condition on line 27 was never true

28 return dataIdDictOrTuple 

29 elif isinstance(dataIdDictOrTuple, dict): 29 ↛ 32line 29 didn't jump to line 32, because the condition on line 29 was never false

30 return (dataIdDictOrTuple["dayObs"], dataIdDictOrTuple["seqNum"]) 

31 else: 

32 raise RuntimeError(f"Failed to parse dataId {dataIdDictOrTuple}") 

33 

34 

35class Annotations: 

36 """Class for interfacing with annotations, as written by the 

37 imageSorter. 

38 """ 

39 

40 def __init__(self, filename): 

41 self.filename = filename 

42 self.tags, self.notes = self._load(filename) 

43 

44 def _load(self, filename): 

45 """Load tags and notes from specified file.""" 

46 tags, notes = ImageSorter.loadAnnotations(filename) 

47 return tags, notes 

48 

49 def getTags(self, dataId): 

50 """Get the tags for a specified dataId. 

51 

52 Empty string means no tags, None means not examined""" 

53 return self.tags.get(_idTrans(dataId), None) 

54 

55 def getNotes(self, dataId): 

56 """Get the notes for the specified dataId.""" 

57 return self.notes.get(_idTrans(dataId), None) 

58 

59 def hasTags(self, dataId, flags): 

60 """Check if a dataId has all the specificed tags""" 

61 tag = self.getTags(dataId) 

62 if tag is None: # not just 'if tag' becuase '' is not the same as None but both as False-y 

63 return None 

64 return all(i in tag for i in flags.upper()) 

65 

66 def getListOfCheckedData(self): 

67 """Return a list of all dataIds which have been examined.""" 

68 return sorted(list(self.tags.keys())) 

69 

70 def getListOfDataWithNotes(self): 

71 """Return a list of all dataIds which have notes associated.""" 

72 return sorted(list(self.notes.keys())) 

73 

74 def isExamined(self, dataId): 

75 """Check if the dataId has been examined or not.""" 

76 return _idTrans(dataId) in self.tags 

77 

78 def printTags(self): 

79 """Display the list of tag definitions.""" 

80 print(TAGS) 

81 

82 def getIdsWithGivenTags(self, tags, exactMatches=False): 

83 if exactMatches: 

84 return [ 

85 dId 

86 for (dId, tag) in self.tags.items() 

87 if (all(t in tag for t in tags.upper()) and (len(tags) == len(tag))) 

88 ] 

89 else: 

90 return [dId for (dId, tag) in self.tags.items() if all(t in tag for t in tags.upper())]