Coverage for python/lsst/daf/butler/script/queryCollections.py : 10%

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/>.
22from astropy.table import Table
23import itertools
24from numpy import array
26from .. import Butler
27from ..core.utils import globToRegex
30def queryCollections(repo, glob, collection_type, chains):
31 """Get the collections whose names match an expression.
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``.
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
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)]
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.
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.
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
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))
105 # Fill in the child collections of the chained collection:
106 collections = itertools.chain(*[getCollections(child, nesting + 1)
107 for child in childCollections])
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)]
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}")