LSSTApplications  17.0+11,17.0+34,17.0+56,17.0+57,17.0+59,17.0+7,17.0-1-g377950a+33,17.0.1-1-g114240f+2,17.0.1-1-g4d4fbc4+28,17.0.1-1-g55520dc+49,17.0.1-1-g5f4ed7e+52,17.0.1-1-g6dd7d69+17,17.0.1-1-g8de6c91+11,17.0.1-1-gb9095d2+7,17.0.1-1-ge9fec5e+5,17.0.1-1-gf4e0155+55,17.0.1-1-gfc65f5f+50,17.0.1-1-gfc6fb1f+20,17.0.1-10-g87f9f3f+1,17.0.1-11-ge9de802+16,17.0.1-16-ga14f7d5c+4,17.0.1-17-gc79d625+1,17.0.1-17-gdae4c4a+8,17.0.1-2-g26618f5+29,17.0.1-2-g54f2ebc+9,17.0.1-2-gf403422+1,17.0.1-20-g2ca2f74+6,17.0.1-23-gf3eadeb7+1,17.0.1-3-g7e86b59+39,17.0.1-3-gb5ca14a,17.0.1-3-gd08d533+40,17.0.1-30-g596af8797,17.0.1-4-g59d126d+4,17.0.1-4-gc69c472+5,17.0.1-6-g5afd9b9+4,17.0.1-7-g35889ee+1,17.0.1-7-gc7c8782+18,17.0.1-9-gc4bbfb2+3,w.2019.22
LSSTDataManagementBasePackage
butlerLocation.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 #
4 # LSST Data Management System
5 # Copyright 2008, 2009, 2010 LSST Corporation.
6 #
7 # This product includes software developed by the
8 # LSST Project (http://www.lsst.org/).
9 #
10 # This program is free software: you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation, either version 3 of the License, or
13 # (at your option) any later version.
14 #
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
19 #
20 # You should have received a copy of the LSST License Statement and
21 # the GNU General Public License along with this program. If not,
22 # see <http://www.lsstcorp.org/LegalNotices/>.
23 #
24 
25 
26 """This module defines the ButlerLocation class."""
27 
28 import lsst.daf.base as dafBase
29 
30 import os
31 from past.builtins import basestring
32 import yaml
33 
34 from . import iterify, doImport
35 
36 
38  """Initializer
39 
40  Parameters
41  ----------
42  assembler : function object
43  Function object or importable string to a function object that can be called with the assembler
44  signature: (dataId, componentDict, cls).
45  disassembler : function object
46  Function object or importable string to a function object that can be called with the disassembler
47  signature: (object, dataId, componentDict).
48  python : class object
49  A python class object or importable string to a class object that can be used by the assembler to
50  instantiate an object to be returned.
51  dataId : dict or DataId
52  The dataId that is used to look up components.
53  mapper : Mapper instance
54  A reference to the mapper that created this ButlerComposite object.
55  """
56 
57  class ComponentInfo():
58  """Information about a butler composite object. Some details come from the policy and some are filled
59  in by the butler. Component info is used while assembling and disassembling a composite object in
60  butler. It is used as an input to assemblers and disassemblers (which are part of the butler public
61  API).
62 
63  Parameters
64  ----------
65  datasetType : string
66  The datasetType of the component.
67  obj : object instance
68  The python object instance that is this component.
69  setter : string
70  The name of the function in the parent object to set this component.
71  Optional - may be None
72  getter : string
73  The name of the function in the parent object to get this component.
74  Optional - may be None
75  subset : bool
76  If true, indicates that the obj should be a list of objects found via butlerSubset.
77  inputOnly : bool
78  If true, indicates that the obj should not be serialized when performing a butler.put.
79  """
80  def __init__(self, datasetType, obj, setter, getter, subset, inputOnly):
81  self.datasetType = datasetType
82  self.obj = obj
83  self.setter = setter
84  self.getter = getter
85  self.subset = subset
86  self.inputOnly = inputOnly
87 
88  def __repr__(self):
89  return 'ComponentInfo(datasetType:%s, obj:%s, setter:%s, getter:%s, subset:%s)' % \
90  (self.datasetType, self.obj, self.setter, self.getter, self.subset)
91 
92  def __repr__(self):
93  return 'ButlerComposite(assembler:%s, disassembler:%s, python:%s, dataId:%s, mapper:%s, ' \
94  'componentInfo:%s, repository:%s)' % \
95  (self.assembler,
96  self.disassembler,
97  self.python,
98  self.dataId,
99  self.mapper,
100  self.componentInfo,
101  self.repository)
102 
103  def __init__(self, assembler, disassembler, python, dataId, mapper):
104  self.assembler = doImport(assembler) if isinstance(assembler, basestring) else assembler
105  self.disassembler = doImport(disassembler) if isinstance(disassembler, basestring) else disassembler
106  self.python = doImport(python) if isinstance(python, basestring) else python
107  self.dataId = dataId
108  self.mapper = mapper
109  self.componentInfo = {}
110  self.repository = None
111 
112  def add(self, id, datasetType, setter, getter, subset, inputOnly):
113  """Add a description of a component needed to fetch the composite dataset.
114 
115  Parameters
116  ----------
117  id : string
118  The name of the component in the policy definition.
119  datasetType : string
120  The name of the datasetType of the component.
121  setter : string or None
122  The name of the function used to set this component into the python type that contains it.
123  Specifying a setter is optional, use None if the setter won't be specified or used.
124  getter : string or None
125  The name of the function used to get this component from the python type that contains it.
126  Specifying a setter is optional, use None if the setter won't be specified or used.
127  subset : bool
128  If true, indicates that the obj should be a list of objects found via butlerSubset.
129  inputOnly : bool
130  If true, indicates that the obj should not be serialized when performing a butler.put.
131  """
132  self.componentInfo[id] = ButlerComposite.ComponentInfo(datasetType=datasetType,
133  obj=None,
134  setter=setter,
135  getter=getter,
136  subset=subset,
137  inputOnly=inputOnly)
138 
139  def setRepository(self, repository):
140  self.repository = repository
141 
142  def getRepository(self):
143  return self.repository
144 
145  def getPythonType(self):
146  return self.python
147 
148 
149 class ButlerLocation(yaml.YAMLObject):
150  """ButlerLocation is a struct-like class that holds information needed to
151  persist and retrieve an object using the LSST Persistence Framework.
152 
153  Mappers should create and return ButlerLocations from their
154  map_{datasetType} methods.
155 
156  Parameters
157  ----------
158  pythonType - string or class instance
159  This is the type of python object that should be created when reading the location.
160 
161  cppType - string or None
162  The type of cpp object represented by the location (optional, may be None)
163 
164  storageName - string
165  The type of storage the object is in or should be place into.
166 
167  locationList - list of string
168  A list of URI to place the object or where the object might be found. (Typically when reading the
169  length is expected to be exactly 1).
170 
171  dataId - dict
172  The dataId that was passed in when mapping the location. This may include keys that were not used for
173  mapping this location.
174 
175  mapper - mapper class instance
176  The mapper object that mapped this location.
177 
178  storage - storage class instance
179  The storage interface that can be used to read or write this location.
180 
181  usedDataId - dict
182  The dataId components that were used to map this location. If the mapper had to look up keys those
183  will be in this dict (even though they may not appear in the dataId parameter). If the dataId
184  parameter contained keys that were not required to map this item then those keys will NOT be in this
185  parameter.
186 
187  datasetType - string
188  The datasetType that this location represents.
189 
190  additionalData : `lsst.daf.base.PropertySet`, optional
191  Additional metadata to be passed to the persistence framework,
192  or `None`.
193  """
194 
195  yaml_tag = u"!ButlerLocation"
196  try:
197  # PyYAML >=5.1 prefers a different loader
198  yaml_loader = yaml.FullLoader
199  except AttributeError:
200  yaml_loader = yaml.Loader
201  yaml_dumper = yaml.Dumper
202 
203  def __repr__(self):
204  return \
205  'ButlerLocation(pythonType=%r, cppType=%r, storageName=%r, storage=%r, locationList=%r,' \
206  ' additionalData=%r, mapper=%r, dataId=%r)' % \
207  (self.pythonType, self.cppType, self.storageName, self.storage, self.locationList,
208  self.additionalData, self.mapper, self.dataId)
209 
210  def __init__(self, pythonType, cppType, storageName, locationList, dataId, mapper, storage,
211  usedDataId=None, datasetType=None, additionalData=None):
212  # pythonType is sometimes unicode with Python 2 and pybind11; this breaks the interpreter
213  self.pythonType = str(pythonType) if isinstance(pythonType, basestring) else pythonType
214  self.cppType = cppType
215  self.storageName = storageName
216  self.mapper = mapper
217  self.storage = storage
218  self.locationList = iterify(locationList)
219  self.additionalData = additionalData if additionalData else dafBase.PropertySet()
220  for k, v in dataId.items():
221  self.additionalData.set(k, v)
222  self.dataId = dataId
223  self.usedDataId = usedDataId
224  self.datasetType = datasetType
225 
226  def __str__(self):
227  s = "%s at %s(%s)" % (self.pythonType, self.storageName,
228  ", ".join(self.locationList))
229  return s
230 
231  @staticmethod
232  def to_yaml(dumper, obj):
233  """Representer for dumping to YAML
234  :param dumper:
235  :param obj:
236  :return:
237  """
238  return dumper.represent_mapping(ButlerLocation.yaml_tag,
239  {'pythonType': obj.pythonType, 'cppType': obj.cppType,
240  'storageName': obj.storageName,
241  'locationList': obj.locationList, 'mapper': obj.mapper,
242  'storage': obj.storage, 'dataId': obj.dataId})
243 
244  @staticmethod
245  def from_yaml(loader, node):
246  obj = loader.construct_mapping(node)
247  return ButlerLocation(**obj)
248 
249  def setRepository(self, repository):
250  self.repository = repository
251 
252  def getRepository(self):
253  return self.repository
254 
255  def getPythonType(self):
256  return self.pythonType
257 
258  def getCppType(self):
259  return self.cppType
260 
261  def getStorageName(self):
262  return self.storageName
263 
264  def getLocations(self):
265  return self.locationList
266 
268  return [os.path.join(self.storage.root, l) for l in self.getLocations()]
269 
270  def getAdditionalData(self):
271  return self.additionalData
272 
273  def getStorage(self):
274  return self.storage
def __init__(self, pythonType, cppType, storageName, locationList, dataId, mapper, storage, usedDataId=None, datasetType=None, additionalData=None)
def __init__(self, datasetType, obj, setter, getter, subset, inputOnly)
def __init__(self, assembler, disassembler, python, dataId, mapper)
daf::base::PropertySet * set
Definition: fits.cc:884
def doImport(pythonType)
Definition: utils.py:106
def add(self, id, datasetType, setter, getter, subset, inputOnly)
Class for storing generic metadata.
Definition: PropertySet.h:68