Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #42 from DiamondLightSource/objectmodel
- Loading branch information
Showing
5 changed files
with
155 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
ISPyB database access via model objects | ||
======================================= | ||
|
||
*Note: The model object API is not finalized yet and should be treated as | ||
unstable for the time being.* | ||
|
||
Model objects provide a pythonic view on the information stored in ISPyB. | ||
Database records are presented as Python objects and can be chained easily | ||
to access related records. For example: | ||
|
||
```python | ||
import ispyb | ||
with ispyb.open(...) as i: | ||
dc = i.get_data_collection(12345) | ||
dc.image_count # number of images in data collection 12345 | ||
|
||
# To get the orientation of a grid scan data collection: | ||
dc.group.gridinfo.orientation | ||
|
||
# Name of a ProcessingJob | ||
pj = i.get_processing_job(1234) | ||
print(pj.name) | ||
|
||
# A human readable summary of the ProcessingJob | ||
print(pj) | ||
|
||
# A list of parameters for the ProcessingJob | ||
list(pj.parameters) | ||
``` | ||
|
||
Model objects only query the database when necessary and cache results locally | ||
when possible. Every object offers a .reload() method to force loading/updating. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
from __future__ import absolute_import, division, print_function | ||
|
||
import collections | ||
|
||
import ispyb.model | ||
import ispyb.model.processingprogram | ||
|
||
class IntegrationResult(ispyb.model.DBCache): | ||
'''An object representing a data collection integration result database entry. | ||
The object lazily accesses the underlying database when necessary and | ||
exposes record data as python attributes. | ||
''' | ||
|
||
def __init__(self, apiid, db_conn, preload=None): | ||
'''Create a IntegrationResult object for a defined AutoProcIntegrationID. | ||
Requires a database connection object exposing further data access | ||
methods. | ||
:param apiid: AutoProcIntegrationID | ||
:param db_conn: ISPyB database connection object | ||
:return: An IntegrationResult object representing the database entry for | ||
the specified AutoProcIntegrationID | ||
''' | ||
self._cache_dc = None | ||
self._cache_app = None | ||
self._db = db_conn | ||
self._apiid = int(apiid) | ||
if preload: | ||
self._data = preload | ||
|
||
def reload(self): | ||
'''Load/update information from the database.''' | ||
raise NotImplementedError('TODO: Not implemented yet') | ||
|
||
@property | ||
def DCID(self): | ||
'''Returns the main data collection id.''' | ||
dcid = self._data['dataCollectionId'] | ||
if dcid is None: | ||
return None | ||
return int(dcid) | ||
|
||
@property | ||
def data_collection(self): | ||
'''Returns the DataCollection model object for the main data collection of | ||
the ProcessingJob.''' | ||
if self._cache_dc is None: | ||
if self.DCID is None: | ||
return None | ||
self._cache_dc = self._db.get_data_collection(self.DCID) | ||
return self._cache_dc | ||
|
||
@property | ||
def APIID(self): | ||
'''Returns the AutoProcIntegrationID.''' | ||
return self._apiid | ||
|
||
def __repr__(self): | ||
'''Returns an object representation, including the AutoProcIntegrationID, | ||
the database connection interface object, and the cache status.''' | ||
return '<IntegrationResult #%d (%s), %r>' % ( | ||
self._apiid, | ||
'cached' if self.cached else 'uncached', | ||
self._db | ||
) | ||
|
||
def __str__(self): | ||
'''Returns a pretty-printed object representation.''' | ||
if not self.cached: | ||
return 'IntegrationResult #%d (not yet loaded from database)' % self._apiid | ||
return ('\n'.join(( | ||
'IntegrationResult #{ir.APIID}', | ||
' DCID : {ir.DCID}', | ||
' APPID : {ir.APPID}', | ||
' Start Image : {ir.image_start}', | ||
' End Image : {ir.image_end}', | ||
' Detector Distance: {ir.detector_distance}', | ||
' Timestamp : {ir.timestamp}', | ||
))).format(ir=self) | ||
|
||
ispyb.model.add_properties(IntegrationResult, ( | ||
('APPID', 'autoProcProgramId'), | ||
('image_start', 'startImageNumber'), | ||
('image_end', 'endImageNumber'), | ||
('detector_distance', 'refinedDetectorDistance'), | ||
('timestamp', 'recordTimeStamp'), | ||
)) |