diff --git a/plasmid/source/core-plugins/stellingmigration/1/dss/drop-boxes/stellingmigration/managed.py b/plasmid/source/core-plugins/stellingmigration/1/dss/drop-boxes/stellingmigration/managed.py new file mode 100644 index 0000000000000000000000000000000000000000..b915eedfbc305a9f4c43a2a787f4fe9a6d3c566a --- /dev/null +++ b/plasmid/source/core-plugins/stellingmigration/1/dss/drop-boxes/stellingmigration/managed.py @@ -0,0 +1,167 @@ +from ch.systemsx.cisd.openbis.generic.server import CommonServiceProvider + +## +## Configuration +## + +# This needs to be edited for each sample type to match the Profile.js ANNOTATION_PROPERTIES map. +configuration = {} + +configuration["GENERAL_PROTOCOL"] = { + "CHEMICALS" : {"QUANTITY" : False, "CHEMICAL_NAME" : False }, + }; + +#Global Variables +annotableType = "<REPLACE_WITH_ANNOTABLE_TYPE>" +server = CommonServiceProvider.getCommonServer() +contextOrNull = server.tryToAuthenticateAsSystem() +propertyTypes = server.listPropertyTypes(contextOrNull.getSessionToken(), False) + +## +## Help Methods +## +def getAllAnnotableSampleTypesForType(fromAnnotableType): + allTypes = {}; + for sampleTypeWithAnnotations in configuration: + if (fromAnnotableType == None) or (fromAnnotableType == sampleTypeWithAnnotations): + for sampleTypeWithAnnotationsForType in configuration[sampleTypeWithAnnotations]: + allTypes[sampleTypeWithAnnotationsForType] = True; + return allTypes; + +def getPropertyTypesForSampleTypeFromAnnotableType(sampleTypeCodeToFind, fromAnnotableType): + for sampleTypeWithAnnotations in configuration: + if (fromAnnotableType == None) or (fromAnnotableType == sampleTypeWithAnnotations): + for sampleTypeWithAnnotationsForType in configuration[sampleTypeWithAnnotations]: + if sampleTypeWithAnnotationsForType == sampleTypeCodeToFind: + return configuration[sampleTypeWithAnnotations][sampleTypeWithAnnotationsForType]; + return None; + +def getPropertyType(propertyTypeCode): + for propertyType in propertyTypes: + if propertyType.code == propertyTypeCode: + return propertyType + return None; + +def createAnnotationsFor(identifier, annotations): + permId = entityInformationProvider().getSamplePermId(identifier); + newAnnotation = elementFactory().createSampleLink(permId) + + newAnnotation.addAttribute("identifier", identifier) + for annotation in annotations: + newAnnotation.addAttribute(annotation, annotations[annotation]) + return newAnnotation + +def getWidgetForAdd(sampleTypeCode, annotableType): + widgets = [] + widgetIdentifier = inputWidgetFactory().createTextInputField("identifier")\ + .setMandatory(True)\ + .setValue("")\ + .setDescription("") + widgets.append(widgetIdentifier) + for propertyTypeCode in getPropertyTypesForSampleTypeFromAnnotableType(sampleTypeCode, annotableType): + propertyType = getPropertyType(propertyTypeCode) + widget = inputWidgetFactory().createTextInputField(propertyType.label)\ + .setMandatory(getPropertyTypesForSampleTypeFromAnnotableType(sampleTypeCode, annotableType)[propertyTypeCode])\ + .setValue("")\ + .setDescription(propertyType.description) + widgets.append(widget) + return widgets; + +def isValid(dataType, value): + return True +## +## Main Methods +## +def configureUI(): + # Add Headers + tableBuilder = createTableBuilder() + tableBuilder.addHeader("identifier") + usedTableHeaders = {"identifier" : True } + for sampleTypeCode in getAllAnnotableSampleTypesForType(annotableType): + for propertyTypeCode in getPropertyTypesForSampleTypeFromAnnotableType(sampleTypeCode, annotableType): + if propertyTypeCode not in usedTableHeaders: + tableBuilder.addHeader(propertyTypeCode) + usedTableHeaders[propertyTypeCode] = True + + property.setOwnTab(True) + uiDescription = property.getUiDescription() + uiDescription.useTableOutput(tableBuilder.getTableModel()) + + # Add Rows + samples = list(propertyConverter().convertToElements(property)) + for sample in samples: + row = tableBuilder.addRow() + for annotation in sample.getAttributes(): + if annotation != "permId": + row.setCell(annotation, sample.getAttribute(annotation)) + + # Add Create buttons + for sampleTypeCode in getAllAnnotableSampleTypesForType(annotableType): + title = "Add " + sampleTypeCode; + addAction = uiDescription.addTableAction(title).setDescription(title) + widgets = getWidgetForAdd(sampleTypeCode, annotableType) + addAction.addInputWidgets(widgets) + + # Add Delete button + deleteAction = uiDescription.addTableAction("Delete")\ + .setDescription('Are you sure you want to delete selected annotation?') + deleteAction.setRowSelectionRequired() # Delete is enabled when at least 1 row is selected. + +def updateFromUI(action): + converter = propertyConverter() + elements = list(converter.convertToElements(property)) + + if action.name.startswith("Add"): + sampleTypeCode = action.name[4:] + identifier = action.getInputValue("identifier") + annotations = {} + for propertyTypeCode in getPropertyTypesForSampleTypeFromAnnotableType(sampleTypeCode, annotableType): + propertyType = getPropertyType(propertyTypeCode) + propertyTypeValue = action.getInputValue(propertyType.label) + if not isValid(propertyType.dataType, propertyTypeValue): + raise ValidationException("Property " + str(propertyType.label) + " with invalid value " + str(propertyTypeValue)) + annotations[propertyTypeCode] = propertyTypeValue + newAnnotation = createAnnotationsFor(identifier, annotations) + elements.append(newAnnotation) + + if action.name.startswith("Delete"): + rowIds = list(action.getSelectedRows()) + rowIds.reverse() + for rowId in rowIds: + elements.pop(rowId) + + property.value = converter.convertToString(elements) + +## +## Batch Import Methods +## +def batchColumnNames(): + allTypes = [] + for sampleTypeCode in getAllAnnotableSampleTypesForType(annotableType): + allTypes.append(sampleTypeCode) + return allTypes + +def updateFromBatchInput(bindings): + elements = [] + for annotableSampleType in getAllAnnotableSampleTypesForType(annotableType): + annotatedSamples = bindings.get(annotableSampleType) + if annotatedSamples != None and annotatedSamples != "": + for sampleLine in annotatedSamples.split("\\"): + foundIdentifier = False + propertyTypes = getPropertyTypesForSampleTypeFromAnnotableType(annotableSampleType, annotableType) + sampleLink = None + for sampleProperty in sampleLine.split(";"): + propertyName = sampleProperty.split(":")[0] + propertyValue = sampleProperty.split(":")[1] + if propertyName == "identifier": + foundIdentifier = True + permId = entityInformationProvider().getSamplePermId(propertyValue) + sampleLink = elementFactory().createSampleLink(permId) + sampleLink.addAttribute(propertyName, propertyValue) + elif propertyTypes[propertyName] != None: + sampleLink.addAttribute(propertyName, propertyValue) + else: + raise NameError('Found invalid property: ' + propertyName + " on type " + annotableSampleType) + if foundIdentifier: + elements.append(sampleLink) + property.value = propertyConverter().convertToString(elements) \ No newline at end of file diff --git a/plasmid/source/core-plugins/stellingmigration/1/dss/drop-boxes/stellingmigration/migration.py b/plasmid/source/core-plugins/stellingmigration/1/dss/drop-boxes/stellingmigration/migration.py index b69fde97a07a698fb80faff75cf2b3c27ca372fb..be137f8d901c281b0d4821a819354818673ef936 100644 --- a/plasmid/source/core-plugins/stellingmigration/1/dss/drop-boxes/stellingmigration/migration.py +++ b/plasmid/source/core-plugins/stellingmigration/1/dss/drop-boxes/stellingmigration/migration.py @@ -3,6 +3,7 @@ from datetime import datetime from ch.systemsx.cisd.openbis.generic.shared.api.v1.dto import SearchCriteria, SearchSubCriteria import ch.systemsx.cisd.openbis.generic.server.jython.api.v1.DataType as DataType import xml.etree.ElementTree as ET + ## ## Generic Process Method ## @@ -60,39 +61,34 @@ def translate(tr, sample, properties): # Create new annotations from scratch newAnnotations = sample.getPropertyValue("ANNOTATIONS_STATE") newAnnotationsRoot = None -# if (newAnnotations is not None) and (newAnnotations is not ""): -# newAnnotationsRoot = ET.fromstring(newAnnotations) -# if (newAnnotations is None) or (newAnnotations is ""): newAnnotationsRoot = ET.Element("root") # Read old annotations for property in properties: - if property == "CHEMICALS": - oldAnnotationsRoot = None - try: - propertyValue = unicode(sample.getPropertyValue(property), "utf-8") - oldAnnotationsRoot = ET.fromstring(propertyValue) - except Exception: - print "Exception on " + sample.code + " " + property - - if oldAnnotationsRoot is not None: - for child in oldAnnotationsRoot: - newAnnotationsNode = ET.SubElement(newAnnotationsRoot, "Sample") - permId = child.attrib["permId"] - print sample.code + " " + permId - newAnnotationsNode.attrib["permId"] = permId - linkedSample = getSampleByPermId(tr, permId) - newAnnotationsNode.attrib["identifier"] = linkedSample.getSampleIdentifier() - - concentration = getValueOrNull(child.attrib, "concentration") - if(concentration is not None): - newAnnotationsNode.attrib["concentration"] = concentration - chemicalName = getValueOrNull(child.attrib, "name") - if(chemicalName is not None): - newAnnotationsNode.attrib["chemicalName"] = chemicalName - - if sampleType == "GENERAL_PROTOCOL": - save(tr, sample, "ANNOTATIONS_STATE", ET.tostring(newAnnotationsRoot, encoding='utf-8')) + oldAnnotationsRoot = None + try: + propertyValue = unicode(sample.getPropertyValue(property), "utf-8") + if '<root>' in propertyValue: + oldAnnotationsRoot = ET.fromstring(propertyValue) + except Exception: + print "Exception on " + sample.code + " " + property + if oldAnnotationsRoot is not None: + for child in oldAnnotationsRoot: + if property == "CHEMICALS": + newAnnotationsNode = ET.SubElement(newAnnotationsRoot, "Sample") + permId = child.attrib["permId"] + print sample.code + " " + permId + newAnnotationsNode.attrib["permId"] = permId + linkedSample = getSampleByPermId(tr, permId) + newAnnotationsNode.attrib["identifier"] = linkedSample.getSampleIdentifier() + + concentration = getValueOrNull(child.attrib, "concentration") + if(concentration is not None): + newAnnotationsNode.attrib["QUANTITY"] = concentration + chemicalName = getValueOrNull(child.attrib, "name") + if(chemicalName is not None): + newAnnotationsNode.attrib["CHEMICAL_NAME"] = chemicalName + save(tr, sample, "ANNOTATIONS_STATE", ET.tostring(newAnnotationsRoot, encoding='utf-8')) def save(tr, sample, property, propertyValue): mutableSample = tr.makeSampleMutable(sample) diff --git a/plasmid/source/core-plugins/stellingmigration/1/dss/drop-boxes/stellingmigration/notes.txt b/plasmid/source/core-plugins/stellingmigration/1/dss/drop-boxes/stellingmigration/notes.txt new file mode 100644 index 0000000000000000000000000000000000000000..314349113314973d49a4e40439ca004f53ba2ee3 --- /dev/null +++ b/plasmid/source/core-plugins/stellingmigration/1/dss/drop-boxes/stellingmigration/notes.txt @@ -0,0 +1,10 @@ +## +## Property Types Created in openBIS for the annotations +## + +# +# CHEMICALS +# + +QUANTITY +CHEMICAL_NAME \ No newline at end of file