Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# This file is part of daf_butler. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (http://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 <http://www.gnu.org/licenses/>. 

21 

22from astropy.table import Table 

23import itertools 

24from numpy import array 

25 

26from .. import Butler 

27from ..core.utils import globToRegex 

28 

29 

30def queryCollections(repo, glob, collection_type, chains): 

31 """Get the collections whose names match an expression. 

32 

33 Parameters 

34 ---------- 

35 repo : `str` 

36 URI to the location of the repo or URI to a config file describing the 

37 repo and its location. 

38 glob : iterable [`str`] 

39 A list of glob-style search string that fully or partially identify 

40 the dataset type names to search for. 

41 collection_type : `Iterable` [ `CollectionType` ], optional 

42 If provided, only return collections of these types. 

43 chains : `str` 

44 Must be one of "FLATTEN", "TABLE", or "TREE" (case sensitive). 

45 Affects contents and formatting of results, see 

46 ``cli.commands.query_collections``. 

47 

48 Returns 

49 ------- 

50 collections : `astropy.table.Table` 

51 A table containing information about collections. 

52 """ 

53 butler = Butler(repo) 

54 expression = globToRegex(glob) 

55 # Only pass expression to queryCollections if there is an expression to 

56 # apply; otherwise let queryCollections use its default value. 

57 kwargs = {} 

58 if expression: 

59 kwargs["expression"] = expression 

60 

61 if chains == "TABLE": 

62 collectionNames = butler.registry.queryCollections(collectionTypes=frozenset(collection_type), 

63 **kwargs) 

64 collectionNames = list(collectionNames) # Materialize list for multiple use. 

65 collectionTypes = [butler.registry.getCollectionType(c).name for c in collectionNames] 

66 collectionDefinitions = [str(butler.registry.getCollectionChain(name)) if colType == "CHAINED" else "" 

67 for name, colType in zip(collectionNames, collectionTypes)] 

68 

69 # Only add a definition column if at least one definition row is 

70 # populated: 

71 if any(collectionDefinitions): 

72 return Table((collectionNames, collectionTypes, collectionDefinitions), 

73 names=("Name", "Type", "Definition")) 

74 return Table((collectionNames, collectionTypes), names=("Name", "Type")) 

75 elif chains == "TREE": 

76 def getCollections(collectionName, nesting=0): 

77 """Get a list of the name and type of the passed-in collection, 

78 and its child collections, if it is a CHAINED collection. Child 

79 collection names are indended from their parents by adding spaces 

80 before the collection name. 

81 

82 Parameters 

83 ---------- 

84 collectionName : `str` 

85 The name of the collection to get. 

86 nesting : `int` 

87 The amount of indent to apply before each collection. 

88 

89 Returns 

90 ------- 

91 collections : `list` [`tuple` [`str`, `str`]] 

92 Tuples of the collection name and its type. Starts with the 

93 passed-in collection, and if it is a CHAINED collection, each 

94 of its children follows, and so on. 

95 """ 

96 def nested(val): 

97 stepDepth = 2 

98 return " " * (stepDepth * nesting) + val 

99 

100 collectionType = butler.registry.getCollectionType(collectionName).name 

101 if collectionType == "CHAINED": 

102 # Get the child collections of the chained collection: 

103 childCollections = list(butler.registry.getCollectionChain(collectionName)) 

104 

105 # Fill in the child collections of the chained collection: 

106 collections = itertools.chain(*[getCollections(child, nesting + 1) 

107 for child in childCollections]) 

108 

109 # Insert the chained (parent) collection at the beginning of 

110 # the list, and return the list: 

111 return [(nested(collectionName), "CHAINED")] + list(collections) 

112 else: 

113 return [(nested(collectionName), collectionType)] 

114 

115 collectionNames = butler.registry.queryCollections(collectionTypes=frozenset(collection_type), 

116 **kwargs) 

117 collections = itertools.chain(*[getCollections(name) for name in collectionNames]) 

118 return Table(array(list(collections)), names=("Name", "Type")) 

119 elif chains == "FLATTEN": 

120 collectionNames = list(butler.registry.queryCollections(collectionTypes=frozenset(collection_type), 

121 flattenChains=True, 

122 **kwargs)) 

123 collectionTypes = [butler.registry.getCollectionType(c).name for c in collectionNames] 

124 return Table((collectionNames, 

125 collectionTypes), 

126 names=("Name", "Type")) 

127 raise RuntimeError(f"Value for --chains not recognized: {chains}")