Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DM-10319: _filename functions return first mappable repository even when file does not exist #86

Merged
merged 8 commits into from
Mar 12, 2018
50 changes: 50 additions & 0 deletions python/lsst/daf/persistence/butler.py
Original file line number Diff line number Diff line change
Expand Up @@ -1536,6 +1536,56 @@ def dataRef(self, datasetType, level=None, dataId={}, **rest):
(str(datasetType), str(level), str(dataId), str(rest)))
return ButlerDataRef(subset, subset.cache[0])

def getUri(self, datasetType, dataId=None, write=False, **rest):
"""Return the URI for a dataset

.. warning:: This is intended only for debugging. The URI should
never be used for anything other than printing.

.. note:: In the event there are multiple URIs for read, we return only
the first.

.. note:: getUri() does not currently support composite datasets.

Parameters
----------
datasetType : `str`
The dataset type of interest.
dataId : `dict`, optional
The data identifier.
write : `bool`, optional
Return the URI for writing?
rest : `dict`, optional
Keyword arguments for the data id.

Returns
-------
uri : `str`
URI for dataset.
"""
datasetType = self._resolveDatasetTypeAlias(datasetType)
dataId = DataId(dataId)
dataId.update(**rest)
locations = self._locate(datasetType, dataId, write=write)
if locations is None:
raise NoResults("No locations for getUri: ", datasetType, dataId)

if write:
# Follow the write path
# Return the first valid write location.
for location in locations:
if isinstance(location, ButlerComposite):
for name, info in location.componentInfo.items():
if not info.inputOnly:
return self.getUri(info.datasetType, location.dataId, write=True)
else:
return location.getLocationsWithRoot()[0]
# fall back to raise
raise NoResults("No locations for getUri(write=True): ", datasetType, dataId)
else:
# Follow the read path, only return the first valid read
return locations.getLocationsWithRoot()[0]

def _read(self, location):
"""Unpersist an object using data inside a ButlerLocation or ButlerComposite object.

Expand Down
30 changes: 30 additions & 0 deletions python/lsst/daf/persistence/butlerSubset.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,36 @@ def put(self, obj, datasetType=None, doBackup=False, **rest):
datasetType = self.butlerSubset.datasetType
self.butlerSubset.butler.put(obj, datasetType, self.dataId, doBackup=doBackup, **rest)

def getUri(self, datasetType=None, write=False, **rest):
"""Return the URL for a dataset

.. warning:: This is intended only for debugging. The URI should
never be used for anything other than printing.

.. note:: In the event there are multiple URIs, we return only
the first.

.. note:: getUri() does not currently support composite datasets.

Parameters
----------
datasetType : `str`, optional
The dataset type of interest.
write : `bool`, optional
Return the URI for writing?
rest : `dict`, optional
Keyword arguments for the data id.

Returns
-------
uri : `str`
URI for dataset
"""

if datasetType is None:
datasetType = self.butlerSubset.datasetType
return self.butlerSubset.butler.getUri(datasetType, self.dataId, write=write, **rest)

def subLevels(self):
"""
Return a list of the lower levels of the hierarchy than this
Expand Down
6 changes: 6 additions & 0 deletions tests/test_butlerSubset.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ def testSingleIteration(self):
self.assertEqual(type(image), list)
self.assertEqual(image, inputList)

# Tests for new getUri
imageUri = iterator.getUri(self.calexpTypeName)
fileName = 'calexp_v%(visit)d_R%(raft)s_S%(sensor)s.pickle' % iterator.dataId
self.assertEqual(imageUri, os.path.join(self.tmpRoot, fileName))
self.assertEqual(os.path.isfile(imageUri), True)

for fileName in inputList:
os.unlink(os.path.join(self.tmpRoot, fileName))

Expand Down
12 changes: 12 additions & 0 deletions tests/test_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,18 @@ def testGet(self):
# in this case the width is known to be 1026:
self.assertEqual(raw_image[1].header["NAXIS1"], 1026)

def testGetUri(self):
raw_uri = self.butler.getUri('raw', {'visit': '2', 'filter': 'g'})
self.assertEqual(raw_uri,
os.path.join(ROOT, 'butlerAlias', 'data', 'input', 'raw', 'raw_v2_fg.fits.gz'))
self.assertEqual(os.path.isfile(raw_uri), True)

def testGetUriWrite(self):
raw_uri = self.butler.getUri('raw', {'visit': '9', 'filter': 'g'}, write=True)
self.assertEqual(raw_uri,
os.path.join(self.testDir, 'repoA', 'raw', 'raw_v9_fg.fits.gz'))
self.assertEqual(os.path.isfile(raw_uri), False)

def testSubset(self):
subset = self.butler.subset('raw')
self.assertEqual(len(subset), 3)
Expand Down