27 """This module defines the ButlerSubset class and the ButlerDataRefs contained
28 within it as well as an iterator over the subset."""
30 from __future__
import with_statement
34 """ButlerSubset is a container for ButlerDataRefs. It represents a
35 collection of data ids that can be used to obtain datasets of the type
36 used when creating the collection or a compatible dataset type. It can be
37 thought of as the result of a query for datasets matching a partial data
40 The ButlerDataRefs are generated at a specified level of the data id
41 hierarchy. If that is not the level at which datasets are specified, the
42 ButlerDataRef.subItems() method may be used to dive further into the
45 ButlerSubsets should generally be created using Butler.subset().
47 This mechanism replaces the creation of butlers using partial dataIds.
51 __init__(self, butler, datasetType, level, dataId)
59 def __init__(self, butler, datasetType, level, dataId):
61 Create a ButlerSubset by querying a butler for data ids matching a
62 given partial data id for a given dataset type at a given hierarchy
65 @param butler (Butler) butler that is being queried.
66 @param datasetType (str) the type of dataset to query.
67 @param level (str) the hierarchy level to descend to.
68 @param dataId (dict) the (partial or complete) data id.
77 fmt = list(self.butler.getKeys(datasetType, level).iterkeys())
86 self.cache.append(dataId)
89 for idTuple
in butler.queryMetadata(self.
datasetType,
93 tempId[fmt[0]] = idTuple
95 for i
in xrange(len(fmt)):
96 tempId[fmt[i]] = idTuple[i]
97 self.cache.append(tempId)
101 Number of ButlerDataRefs in the ButlerSubset.
106 return len(self.
cache)
110 Iterator over the ButlerDataRefs in the ButlerSubset.
112 @returns (ButlerIterator)
119 An iterator over the ButlerDataRefs in a ButlerSubset.
134 A ButlerDataRef is a reference to a potential dataset or group of datasets
135 that is portable between compatible dataset types. As such, it can be
136 used to create or retrieve datasets.
138 ButlerDataRefs are (conceptually) created as elements of a ButlerSubset by
139 Butler.subset(). They are initially specific to the dataset type passed
140 to that call, but they may be used with any other compatible dataset type.
141 Dataset type compatibility must be determined externally (or by trial and
144 ButlerDataRefs may be created at any level of a data identifier hierarchy.
145 If the level is not one at which datasets exist, a ButlerSubset
146 with lower-level ButlerDataRefs can be created using
147 ButlerDataRef.subItems().
151 get(self, datasetType=None, **rest)
153 put(self, obj, datasetType=None, **rest)
155 subItems(self, level=None)
157 datasetExists(self, datasetType=None, **rest)
164 For internal use only. ButlerDataRefs should only be created by
165 ButlerSubset and ButlerSubsetIterator.
171 def get(self, datasetType=None, **rest):
173 Retrieve a dataset of the given type (or the type used when creating
174 the ButlerSubset, if None) as specified by the ButlerDataRef.
176 @param datasetType (str) dataset type to retrieve.
177 @param **rest keyword arguments with data identifiers
178 @returns object corresponding to the given dataset type.
181 if datasetType
is None:
182 datasetType = self.butlerSubset.datasetType
183 return self.butlerSubset.butler.get(datasetType, self.
dataId, **rest)
185 def put(self, obj, datasetType=None, doBackup=False, **rest):
187 Persist a dataset of the given type (or the type used when creating
188 the ButlerSubset, if None) as specified by the ButlerDataRef.
190 @param obj object to persist.
191 @param datasetType (str) dataset type to persist.
192 @param doBackup if True, rename existing instead of overwriting
193 @param **rest keyword arguments with data identifiers
195 WARNING: Setting doBackup=True is not safe for parallel processing, as it
196 may be subject to race conditions.
199 if datasetType
is None:
200 datasetType = self.butlerSubset.datasetType
201 self.butlerSubset.butler.put(obj, datasetType, self.
dataId, doBackup=doBackup, **rest)
205 Return a list of the lower levels of the hierarchy than this
208 @returns (iterable) list of strings with level keys."""
211 self.butlerSubset.butler.getKeys(
212 self.butlerSubset.datasetType).keys()
214 self.butlerSubset.butler.getKeys(
215 self.butlerSubset.datasetType,
216 self.butlerSubset.level).keys()
221 Generate a ButlerSubset at a lower level of the hierarchy than this
222 ButlerDataRef, using it as a partial data id. If level is None, a
223 default lower level for the original ButlerSubset level and dataset
226 @param level (str) the hierarchy level to descend to.
227 @returns (ButlerSubset) resulting from the lower-level query or () if
228 there is no lower level.
232 level = self.butlerSubset.butler.mapper.getDefaultSubLevel(
233 self.butlerSubset.level)
236 return self.butlerSubset.butler.subset(self.butlerSubset.datasetType,
241 Determine if a dataset exists of the given type (or the type used when
242 creating the ButlerSubset, if None) as specified by the ButlerDataRef.
244 @param datasetType (str) dataset type to check.
245 @param **rest keywords arguments with data identifiers
248 if datasetType
is None:
249 datasetType = self.butlerSubset.datasetType
250 return self.butlerSubset.butler.datasetExists(
251 datasetType, self.
dataId, **rest)
255 Return the butler associated with this data reference.
257 return self.butlerSubset.butler