Skip to content
Snippets Groups Projects
Commit 7fdef51e authored by juanf's avatar juanf
Browse files

SSDM-1529: PAPER - OPENBIS - Migrate Manage Properties YeastLab Continuation

SVN: 33471
parent 1207ca12
No related branches found
No related tags found
No related merge requests found
def configureUI():
tableBuilder = createTableBuilder()
##
## Headers
##
tableBuilder.addHeader("message")
usedTableHeaders = {"message" : True}
samples = list(propertyConverter().convertToElements(property))
for sample in samples:
for annotation in sample.getAttributes():
if annotation not in usedTableHeaders:
tableBuilder.addHeader(annotation)
usedTableHeaders[annotation] = True
property.setOwnTab(True)
uiDescription = property.getUiDescription()
uiDescription.useTableOutput(tableBuilder.getTableModel())
##
## Data
##
row = tableBuilder.addRow()
row.setCell("message", "Please use the new managed properties annotations, legacy functionality is disabled.")
for sample in samples:
row = tableBuilder.addRow()
for annotation in sample.getAttributes():
row.setCell(annotation, sample.getAttribute(annotation))
def updateFromUI(action):
raise Exception("Please use the new managed properties annotations, legacy functionality is disabled.")
##
## Batch Import Methods
##
def batchColumnNames():
allTypes = []
return allTypes
def updateFromBatchInput(bindings):
elements = []
input = bindings.get('')
if input is not None:
raise Exception("Please use the new managed properties annotations, legacy functionality is disabled.")
\ No newline at end of file
"""
Managed Property Script for handling PLASMID parents of YEAST samples.
@author: Piotr Buczek
"""
import re
print "###################"
"""space that all parents come from (fixed)"""
SPACE = "YEAST_LAB"
"""input pattern matching one plasmid, e.g.:
- 'FRP1 (DEL:URA3)',
- 'FRP2 (INT)',
- 'FRP3(MOD:URA3)',
- 'FRP4'
"""
INPUT_PATTERN = """
# no '^': allow whitespace at the beginning
([^ (]*) # 1st group: match code of a sample, everything before a space or '(' (e.g. 'FRP')
(\ *\( # start of 2nd group (matches an optional relationship type with annotation)
# any spaces followed by a '('
([^:]*) # 3rd group: match relationship type, any character but ':' (e.g. 'DEL', 'INT', 'MOD')
:? # optional ':' separator
(.*) # 4th group: match annotation, any text (e.g. 'URA3')
\))? # end of 2nd (optional) group: closing bracket of relationship details
# no '$': allow whitespace at the end
"""
""" due to some weird jython threading issue, we need to compile the pattern outside the function body """
inputPattern = re.compile(INPUT_PATTERN, re.VERBOSE)
"""relationship types shortcuts"""
DEL_REL_TYPE = 'DEL'
INT_REL_TYPE = 'INT'
MOD_REL_TYPE = 'MOD'
"""tuple of supported relationship types as shortcuts"""
REL_TYPES = (DEL_REL_TYPE, INT_REL_TYPE, MOD_REL_TYPE)
"""dictionary from relationship type shortcut to its 'character' representation"""
REL_TYPE_CHARS = {
DEL_REL_TYPE: u'\u0394', # unicode '∆'
INT_REL_TYPE: '::',
MOD_REL_TYPE: '_'
}
"""dictionary from relationship type shortcut to its full name/label"""
REL_TYPE_LABELS = {
DEL_REL_TYPE: 'deletion',
INT_REL_TYPE: 'integration',
MOD_REL_TYPE: 'modification'
}
REL_TYPE_LABEL_OTHER = '(other)'
REL_TYPE_LABELS_WITH_NONE = tuple([REL_TYPE_LABEL_OTHER] + REL_TYPE_LABELS.values())
"""names of additional sample XML element attributes"""
ATR_CODE = "code"
ATR_RELATIONSHIP = "rel"
ATR_ANNOTATION = "annotation"
"""labels of table columns"""
CONNECTION_LABEL = "connection"
LINK_LABEL = "link"
CODE_LABEL = "code"
RELATIONSHIP_LABEL = "relationship"
ANNOTATION_LABEL = "annotation"
"""action labels"""
ADD_ACTION_LABEL = "Add"
EDIT_ACTION_LABEL = "Edit"
DELETE_ACTION_LABEL = "Delete"
"""helper functions"""
def _group(pattern, input):
"""@return: groups returned by performing pattern search with given @pattern on given @input"""
return pattern.search(input).groups()
def _translateToChar(relationship):
"""
@param relationship: relationship type as a shortcut (@see REL_TYPES), may be null
@return: character representation of given @relationship,
empty string for null
'[<relationship>]' for unknown relationship
"""
if relationship:
if relationship in REL_TYPE_CHARS:
return REL_TYPE_CHARS[relationship]
else:
return "[" + relationship + "]"
else:
return ""
def _translateToLabel(relationship):
"""
@param relationship: relationship type as a shortcut (@see REL_TYPES), may be null
@return: full name of given @relationship,
empty string for null,
'[<relationship>]' for unknown relationship
"""
if relationship:
if relationship in REL_TYPE_LABELS:
return REL_TYPE_LABELS[relationship]
else:
return "[" + relationship + "]"
else:
return REL_TYPE_LABEL_OTHER
def _translateFromLabel(relationshipLabel):
"""
@param relationshipLabel: relationship type as label (@see REL_TYPE_LABELS_WITH_NONE)
@return: type of given @relationshipLabel, None for REL_TYPE_LABEL_OTHER,
"""
if relationshipLabel == REL_TYPE_LABEL_OTHER:
return None
elif relationshipLabel == 'deletion':
return DEL_REL_TYPE
elif relationshipLabel == 'integration':
return INT_REL_TYPE
elif relationshipLabel == 'modification':
return MOD_REL_TYPE
def _createConnectionString(code, relationship, annotation):
"""
@param code: code of a sample
@param relationship: relationship type as a shortcut (@see REL_TYPES), may be null
@param annotation: annotation of the relationship, may be null
@return: string representation of a connection with @relationship translated to a 'character'
"""
result = code
if relationship:
result += _translateToChar(relationship)
if annotation:
result += annotation
return result
def _createSampleLink(code, relationship, annotation):
"""
Creates sample link XML element for sample with specified @code. The element will contain
given @code as 'code' attribute apart from standard 'permId' attribute. If specified
@relationship or @annotation are not null they will also be contained as attributes.
If the sample doesn't exist in DB a fake link will be created with @code as permId.
@param code: code of a sample
@param relationship: relationship type as a shortcut (@see REL_TYPES), may be null
@param annotation: annotation of the relationship, may be null
@return: sample link XML element as string, e.g.:
- '<Sample code="FRP1" permId="20110309154532868-4219"/>'
- '<Sample code="FRP2" permId="20110309154532868-4219" relationship="DEL" annotation="URA3"/>'
- '<Sample code="FAKE_SAMPLE_CODE" permId="FAKE_SAMPLE_CODE"/>
- '<Sample code="FRP4" permId="20110309154532868-4219" relationship="INT"/>'
@raise ValidationException: if the specified relationship type is unknown
"""
permId = entityInformationProvider().getSamplePermId(SPACE, code)
if not permId:
permId = code
sampleLink = elementFactory().createSampleLink(permId)
sampleLink.addAttribute(ATR_CODE, code)
if relationship:
sampleLink.addAttribute(ATR_RELATIONSHIP, relationship)
if relationship in REL_TYPES:
connectionString = _createConnectionString(code, relationship, annotation)
else:
raise ValidationException("Unknown relationship: '" + relationship +
"'. Expected one of: " + REL_TYPES)
if annotation:
sampleLink.addAttribute(ATR_ANNOTATION, annotation)
return sampleLink
""" MAIN FUNCTIONS """
"""Example input:
FRP1 (DEL:URA3), FRP2 (INT), FRP3 (MOD:URA3), FRP4
Relationship types:
- DEL: deletion
- INT: integration
- MOD: modification
"""
#def showRawValueInForms():
# return False
#def batchColumnNames():
# return [CODE_LABEL, RELATIONSHIP_LABEL, ANNOTATION_LABEL]
#def updateFromRegistrationForm(bindings):
# elements = []
# for item in bindings:
# code = item.get("CODE")
# relationship = item.get("RELATIONSHIP")
# annotation=item.get("ANNOTATION")
# print "code is", code
# if code:
# print "bindings", bindings, "+", code, "+", relationship, "+", annotation
# sampleLink = _createSampleLink(code, relationship, annotation)
# elements.append(sampleLink)
# property.value = propertyConverter().convertToString(elements)
def updateFromBatchInput(bindings):
elements = []
input = bindings.get('')
if input is not None:
plasmids = input.split(',')
for p in plasmids:
(code, g, relationship, annotation) = _group(inputPattern, p.strip())
sampleLink = _createSampleLink(code, relationship, annotation)
elements.append(sampleLink)
parentsInput = bindings.get(originalColumnNameBindingKey('YEAST_PARENTS'))
if parentsInput is not None:
parents = parentsInput.split(',')
for parent in parents:
permId = entityInformationProvider().getSamplePermId(SPACE, parent.strip())
parentPlasmids = entityInformationProvider().getSamplePropertyValue(permId, 'PLASMIDS')
if parentPlasmids is None:
continue
parentElements = list(propertyConverter().convertStringToElements(parentPlasmids))
for parentLink in parentElements:
elements.append(parentLink)
property.value = propertyConverter().convertToString(elements)
def configureUI():
"""Create table builder and add columns."""
tableBuilder = createTableBuilder()
tableBuilder.addHeader(LINK_LABEL)
tableBuilder.addHeader(CONNECTION_LABEL)
tableBuilder.addHeader(CODE_LABEL)
tableBuilder.addHeader(RELATIONSHIP_LABEL)
tableBuilder.addHeader(ANNOTATION_LABEL)
"""The property value should contain XML with list of samples. Add a new row for every sample."""
elements = list(propertyConverter().convertToElements(property))
for plasmid in elements:
code = plasmid.getAttribute(ATR_CODE, "")
relationship = plasmid.getAttribute(ATR_RELATIONSHIP, "")
annotation = plasmid.getAttribute(ATR_ANNOTATION, "")
row = tableBuilder.addRow()
row.setCell(CONNECTION_LABEL, _createConnectionString(code, relationship, annotation))
row.setCell(LINK_LABEL, plasmid, code)
row.setCell(CODE_LABEL, code)
row.setCell(RELATIONSHIP_LABEL, _translateToLabel(relationship))
row.setCell(ANNOTATION_LABEL, annotation)
"""Specify that the property should be shown in a tab and set the table output."""
property.setOwnTab(True)
uiDescription = property.getUiDescription()
uiDescription.useTableOutput(tableBuilder.getTableModel())
"""
Define and add actions with input fields used to:
1. specify attributes of new plasmid relationship,
"""
addAction = uiDescription.addTableAction(ADD_ACTION_LABEL)\
.setDescription('Add new plasmid relationship:')
widgets = [
inputWidgetFactory().createTextInputField(CODE_LABEL)\
.setMandatory(True)\
.setValue('FRP')\
.setDescription('Code of plasmid sample, e.g. "FRP1"'),
inputWidgetFactory().createComboBoxInputField(RELATIONSHIP_LABEL, REL_TYPE_LABELS_WITH_NONE)\
.setMandatory(False)\
.setValue(REL_TYPE_LABEL_OTHER),
inputWidgetFactory().createTextInputField(ANNOTATION_LABEL)\
.setMandatory(False)\
.setDescription('Relationship annotation, e.g. "URA3"'),
]
addAction.addInputWidgets(widgets)
"""
2. modify attributes of a selected plasmid relationship,
"""
editAction = uiDescription.addTableAction(EDIT_ACTION_LABEL)\
.setDescription('Edit selected plasmid relationship:')
# Exactly 1 row needs to be selected to enable action.
editAction.setRowSelectionRequiredSingle()
widgets = [
inputWidgetFactory().createTextInputField(CODE_LABEL)\
.setMandatory(True)\
.setDescription('Code of plasmid sample, e.g. "FRP1"'),
inputWidgetFactory().createComboBoxInputField(RELATIONSHIP_LABEL, REL_TYPE_LABELS_WITH_NONE)\
.setMandatory(False),
inputWidgetFactory().createTextInputField(ANNOTATION_LABEL)\
.setMandatory(False)\
.setDescription('Relationship annotation, e.g. "URA3"'),
]
editAction.addInputWidgets(widgets)
# Bind field name with column name.
editAction.addBinding(CODE_LABEL, CODE_LABEL)
editAction.addBinding(RELATIONSHIP_LABEL, RELATIONSHIP_LABEL)
editAction.addBinding(ANNOTATION_LABEL, ANNOTATION_LABEL)
"""
3. delete selected plasmid relationships.
"""
deleteAction = uiDescription.addTableAction(DELETE_ACTION_LABEL)\
.setDescription('Are you sure you want to delete selected plasmid relationships?')
# Delete is enabled when at least 1 row is selected.
deleteAction.setRowSelectionRequired()
def updateFromUI(action):
"""Extract list of elements from old value of the property."""
converter = propertyConverter()
elements = list(converter.convertToElements(property))
"""Implement behaviour of user actions."""
if action.name == ADD_ACTION_LABEL:
"""
For 'add' action create new plasmid relationship element with values from input fields
and add it to existing elements.
"""
code = action.getInputValue(CODE_LABEL)
relationshipLabel = action.getInputValue(RELATIONSHIP_LABEL)
relationship = _translateFromLabel(relationshipLabel)
annotation = action.getInputValue(ANNOTATION_LABEL)
sampleLink = _createSampleLink(code, relationship, annotation)
elements.append(sampleLink)
elif action.name == EDIT_ACTION_LABEL:
"""
For 'edit' action find the plasmid relationship element corresponding to selected row
and replace it with an element with values from input fields.
"""
code = action.getInputValue(CODE_LABEL)
relationshipLabel = action.getInputValue(RELATIONSHIP_LABEL)
relationship = _translateFromLabel(relationshipLabel)
annotation = action.getInputValue(ANNOTATION_LABEL)
sampleLink = _createSampleLink(code, relationship, annotation)
selectedRowId = action.getSelectedRows()[0]
elements[selectedRowId] = sampleLink
elif action.name == DELETE_ACTION_LABEL:
"""
For 'delete' action delete the relationships that correspond to selected rows.
NOTE: As many rows can be deleted at once it is easier to delete them in reversed order.
"""
rowIds = list(action.getSelectedRows())
rowIds.reverse()
for rowId in rowIds:
elements.pop(rowId)
else:
raise ValidationException('action not supported')
"""Update value of the managed property to XML string created from modified list of elements."""
property.value = converter.convertToString(elements)
"""
Managed Property Script for handling YEAST parents of YEAST samples.
@author: Piotr Buczek
"""
import re
""""space that all parents come from (fixed)"""
SPACE = "YEAST_LAB"
"""plasmid_list attribute name"""
ATR_CODE = "code"
"""labels of table columns"""
LINK_LABEL = "link"
CODE_LABEL = "code"
"""action labels"""
ADD_ACTION_LABEL = "Add"
EDIT_ACTION_LABEL = "Edit"
DELETE_ACTION_LABEL = "Delete"
"""helper functions"""
def _createSampleLink(plasmid_list):
"""
Creates sample link XML element for sample with specified 'plasmid_list'. The element will contain
given plasmid_list as 'plasmid_list' attribute apart from standard 'permId' attribute.
If the sample doesn't exist in DB a fake link will be created with the 'plasmid_list' as permId.
@return: sample link XML element as string, e.g.:
- '<Sample plasmid_list="FRP1" permId="20110309154532868-4219"/>'
- '<Sample plasmid_list="FAKE_SAMPLE_CODE" permId="FAKE_SAMPLE_CODE"/>
"""
plasmidPath= "/YEAST_LAB/" + plasmid_list
permId = entityInformationProvider().getSamplePermId(SPACE, plasmid_list)
if not permId:
permId = plasmid_list
sampleLink = elementFactory().createSampleLink(permId)
sampleLink.addAttribute(ATR_CODE, plasmid_list)
return sampleLink
"""
Example input:
FRY1, FRY2, FRY3, FRY4
"""
#def showRawValueInForms():
# return False
#def batchColumnNames():
# return [CODE_LABEL]
#def updateFromRegistrationForm(bindings):
# elements = []
# for item in bindings:
# plasmid_list = item.get('CODE')
# sampleLink = _createSampleLink(plasmid_list)
# elements.append(sampleLink)
# property.value = propertyConverter().convertToString(elements)
def updateFromBatchInput(bindings):
elements = []
input = bindings.get('')
if input is not None:
samples = input.split(',')
for plasmid_list in samples:
sampleLink = _createSampleLink(plasmid_list.strip())
elements.append(sampleLink)
property.value = propertyConverter().convertToString(elements)
def configureUI():
"""Create table builder and add columns."""
tableBuilder = createTableBuilder()
tableBuilder.addHeader(LINK_LABEL)
tableBuilder.addHeader(CODE_LABEL)
"""The property value should contain XML with list of samples. Add a new row for every sample."""
elements = list(propertyConverter().convertToElements(property))
for plasmid in elements:
plasmid_list = plasmid.getAttribute(ATR_CODE, "")
row = tableBuilder.addRow()
row.setCell(LINK_LABEL, plasmid, plasmid_list)
row.setCell(CODE_LABEL, plasmid_list)
"""Specify that the property should be shown in a tab and set the table output."""
property.setOwnTab(True)
uiDescription = property.getUiDescription()
uiDescription.useTableOutput(tableBuilder.getTableModel())
"""
Define and add actions with input fields used to:
1. specify attributes of new yeast parent,
"""
addAction = uiDescription.addTableAction(ADD_ACTION_LABEL)\
.setDescription('Add new plasmid relationship:')
widgets = [
inputWidgetFactory().createTextInputField(CODE_LABEL)\
.setMandatory(True)\
.setValue('FRY')\
.setDescription('Code of yeast parent sample, e.g. "FRY1"')
]
addAction.addInputWidgets(widgets)
"""
2. modify attributes of a selected yeast parent,
"""
editAction = uiDescription.addTableAction(EDIT_ACTION_LABEL)\
.setDescription('Edit selected plasmid relationship:')
# Exactly 1 row needs to be selected to enable action.
editAction.setRowSelectionRequiredSingle()
widgets = [
inputWidgetFactory().createTextInputField(CODE_LABEL)\
.setMandatory(True)\
.setDescription('Code of yeast parent sample, e.g. "FRY1"')
]
editAction.addInputWidgets(widgets)
# Bind field name with column name.
editAction.addBinding(CODE_LABEL, CODE_LABEL)
"""
3. delete selected yeast parents.
"""
deleteAction = uiDescription.addTableAction(DELETE_ACTION_LABEL)\
.setDescription('Are you sure you want to delete selected yeast parent relationships?')
# Delete is enabled when at least 1 row is selected.
deleteAction.setRowSelectionRequired()
def updateFromUI(action):
"""Extract list of elements from old value of the property."""
converter = propertyConverter()
elements = list(converter.convertToElements(property))
"""Implement behaviour of user actions."""
if action.name == ADD_ACTION_LABEL:
"""
For 'add' action create new yeast parent element with values from input fields
and add it to existing elements.
"""
plasmid_list = action.getInputValue(CODE_LABEL)
sampleLink = _createSampleLink(plasmid_list)
elements.append(sampleLink)
elif action.name == EDIT_ACTION_LABEL:
"""
For 'edit' action find the yeast parent element corresponding to selected row
and replace it with an element with values from input fields.
"""
plasmid_list = action.getInputValue(CODE_LABEL)
sampleLink = _createSampleLink(plasmid_list)
selectedRowId = action.getSelectedRows()[0]
elements[selectedRowId] = sampleLink
elif action.name == DELETE_ACTION_LABEL:
"""
For 'delete' action delete yeast parents that correspond to selected rows.
NOTE: As many rows can be deleted at once it is easier to delete them in reversed order.
"""
rowIds = list(action.getSelectedRows())
rowIds.reverse()
for rowId in rowIds:
elements.pop(rowId)
else:
raise ValidationException('action not supported')
"""Update value of the managed property to XML string created from modified list of elements."""
property.value = converter.convertToString(elements)
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment