diff --git a/sanofi/dist/etc/sanofi-dropbox/sanofi-dropbox.py b/sanofi/dist/etc/sanofi-dropbox/sanofi-dropbox.py index 037baf878d676a6266c86dc4cc6fdf46f5ef6047..cd3f29d742974789eff33232a916ebd040bf951f 100644 --- a/sanofi/dist/etc/sanofi-dropbox/sanofi-dropbox.py +++ b/sanofi/dist/etc/sanofi-dropbox/sanofi-dropbox.py @@ -1,3 +1,5 @@ +import re + from ch.systemsx.cisd.common.mail import From from ch.systemsx.cisd.openbis.generic.shared.api.v1.dto import SearchCriteria @@ -98,14 +100,25 @@ class SanofiMaterial: A data structure class holding compound materials as they exist in the Abase (Sanofi) database. """ def __init__(self, wellCode, materialCode, sanofiId, sanofiBatchId): - self.wellCode = wellCode + self.wellCode = self.normalizeWellCode(wellCode) self.materialCode = materialCode self.sanofiId = sanofiId self.sanofiBatchId = sanofiBatchId + + def normalizeWellCode(self, wellCode): + """ normalizes Sanofi wellCodes openBIS wellCodes e.g. AB007 to AB7 """ + return re.sub("(?<=\w)(0+)(?=\d)", "", wellCode) class PlateInitializer: ABASE_DATA_SOURCE = "abase-datasource" - ABASE_QUERY = "TODO: this a query provided by Matt" + ABASE_QUERY = """select + ptodwellreference WELL_CODE, + translate(objdbatchref,'{/:()+','{_____') MATERIAL_CODE, + objdbatchref ABASE_COMPOUND_BATCH_ID, + objdid ABASE_COMPOUND_ID, + olptid ABASE_PLATE_CODE + from sysadmin.plteobjd + where olptid = ?{1}""" LIBRARY_TEMPLATE_PROPNAME = "LIBRARY_TEMPLATE" @@ -113,10 +126,10 @@ class PlateInitializer: NEGATIVE_CONTROL_TYPE = "NEGATIVE_CONTROL" COMPOUND_WELL_TYPE = "COMPOUND_WELL" - COMPOUND_WELL_CONCENTRATION_PROPNAME = "CONCENTRATION" - COMPOUND_WELL_MATERIAL_PROPNAME = "COMPOUND_BATCH" + COMPOUND_WELL_CONCENTRATION_PROPNAME = "CONCENTRATION_M" + COMPOUND_WELL_MATERIAL_PROPNAME = "COMPOUND" - MATERIAL_TYPE = "COMPOUND_BATCH" + MATERIAL_TYPE = "COMPOUND" MATERIAL_ID_PROPNAME = "COMPOUND_ID" MATERIAL_BATCH_ID_PROPNAME = "COMPOUND_BATCH_ID" @@ -125,9 +138,16 @@ class PlateInitializer: self.plate = plate self.plateCode = plate.getCode() self.experimentId = plate.getExperiment().getExperimentIdentifier() + + def wellColumn(self, x): + numLetters = 26 + if x < numLetters: + return chr(ord('A') + x) + else: + return self.wellColumn((x / numLetters) - 1) + self.wellColumn( x % numLetters) def getWellCode(self, x, y): - return chr(ord('A') + x) + str(y) + return self.wellColumn(x) + str(y + 1) def getPlateDimensions(self): """ @@ -146,14 +166,15 @@ class PlateInitializer: if plateHeight != len(tsvLines) : raise RuntimeError("The geometry property of plate %(plateCode)s (height=%(plateHeight)s)" " does not agree with the value of the %(LIBRARY_TEMPLATE_PROPNAME)s" - " property in experiment %(experimentId)s (height=%(numLines)s)." % vars()) + " property in experiment %(experimentId)s (height=%(numLines)s)." % vars(self)) for i in range(0, len(tsvLines)): lineWidth = len(tsvLines[i]) if plateWidth != lineWidth: - raise RuntimeError("The geometry property of plate %(plateCode)s (width=%(plateWidth)s)" - " does not agree with the value of the %(LIBRARY_TEMPLATE_PROPNAME)s" - " property in experiment %(experimentId)s (line=%(i)s, width=%(lineWidth)s)." % vars()) + raise RuntimeError("The geometry property of plate %s (width=%s)" + " does not agree with the value of the %s" + " property in experiment %s (line=%s, width=%s)." % \ + (plateCode, plateWidth, self.LIBRARY_TEMPLATE_PROPNAME, self.experimentId, i, lineWidth)) def parseLibraryTemplate(self): template = experiment.getPropertyValue(self.LIBRARY_TEMPLATE_PROPNAME) @@ -179,7 +200,7 @@ class PlateInitializer: In case the plate is not found in Abase return None. """ queryService = state.getDataSourceQueryService() - queryResult = queryService.select(self.ABASE_DATA_SOURCE, self.ABASE_QUERY, [plate.code]) + queryResult = queryService.select(self.ABASE_DATA_SOURCE, self.ABASE_QUERY, [self.plateCode]) sanofiMaterials = [] for materialMap in list(queryResult): @@ -240,7 +261,10 @@ class PlateInitializer: controlWellTypes = { "H" : self.POSITIVE_CONTROL_TYPE, \ "L" : self.NEGATIVE_CONTROL_TYPE}; - for wellCode in library: + for wellCode in library: + if not library[wellCode]: + continue + libraryValue = library[wellCode].upper() prefixedWellCode = self.plateCode + ":" + wellCode @@ -255,9 +279,10 @@ class PlateInitializer: try: float(concentration) except ValueError: - raise RuntimeError("The specified value for well %(wellCode)s in the property " - " %(LIBRARY_TEMPLATE_PROPNAME)s of experiment %(experimentId)s is invalid. " - "Allowed values are 'H', 'L' or number, but %(libraryValue)s' was found." % vars()) + raise RuntimeError("The specified value for well %s in the property " + " %s of experiment %s is invalid. Allowed values are 'H', 'L'" + " or number, but '%s' was found." % \ + (wellCode, self.LIBRARY_TEMPLATE_PROPNAME, self.experimentId, libraryValue)) well = self.transaction.createNewSample(prefixedWellCode, self.COMPOUND_WELL_TYPE) well.setContainer(self.plate) diff --git a/sanofi/sourceTest/java/ch/systemsx/cisd/sanofi/dss/test/SanofiDropboxJythonTest.java b/sanofi/sourceTest/java/ch/systemsx/cisd/sanofi/dss/test/SanofiDropboxJythonTest.java index bc56399d187b3231d2c23843443a8e1d2040ab20..de1c95805f0df2a6a3766592b3e2acb6df8fa34d 100644 --- a/sanofi/sourceTest/java/ch/systemsx/cisd/sanofi/dss/test/SanofiDropboxJythonTest.java +++ b/sanofi/sourceTest/java/ch/systemsx/cisd/sanofi/dss/test/SanofiDropboxJythonTest.java @@ -80,7 +80,7 @@ public class SanofiDropboxJythonTest extends AbstractJythonDataSetHandlerTest private static final String[] EXPERIMENT_RECIPIENTS = new String[] { "admin@sanofi.com", "mickey@mouse.org" }; - private static final String MATERIAL_TYPE = "COMPOUND_BATCH"; + private static final String MATERIAL_TYPE = "COMPOUND"; private static final String POSITIVE_CONTROL_TYPE = "POSITIVE_CONTROL"; @@ -88,9 +88,9 @@ public class SanofiDropboxJythonTest extends AbstractJythonDataSetHandlerTest private static final String COMPOUND_WELL_TYPE = "COMPOUND_WELL"; - private static final String COMPOUND_WELL_CONCENTRATION_PROPNAME = "CONCENTRATION"; + private static final String COMPOUND_WELL_CONCENTRATION_PROPNAME = "CONCENTRATION_M"; - private static final String COMPOUND_WELL_MATERIAL_PROPNAME = "COMPOUND_BATCH"; + private static final String COMPOUND_WELL_MATERIAL_PROPNAME = "COMPOUND"; private static final String DATASET_DIR_NAME = "batchNr_plateCode.variant_2011.06.28"; @@ -116,16 +116,15 @@ public class SanofiDropboxJythonTest extends AbstractJythonDataSetHandlerTest createHandler(properties, false, true); createData(); - final String libraryTemplate = "1.45\t20.701\tH\n0.12\t0.002\tL"; + final String libraryTemplate = "1.45\t\tH\n0.12\t0.002\tL"; final Sample plate = createPlate(libraryTemplate, "6_WELLS_2X3"); setUpPlateSearchExpectations(plate); setUpLibraryTemplateExpectations(plate); final MockDataSet<Map<String, Object>> queryResult = new MockDataSet<Map<String, Object>>(); - queryResult.add(createQueryResult("A0")); queryResult.add(createQueryResult("A1")); - queryResult.add(createQueryResult("B0")); queryResult.add(createQueryResult("B1")); + queryResult.add(createQueryResult("B2")); final RecordingMatcher<ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails> atomicatOperationDetails = new RecordingMatcher<ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails>(); @@ -143,7 +142,7 @@ public class SanofiDropboxJythonTest extends AbstractJythonDataSetHandlerTest one(openBisService).listMaterials(with(materialCriteria), with(equal(true))); will(returnValue(Collections.emptyList())); - exactly(6).of(openBisService).createPermId(); + exactly(5).of(openBisService).createPermId(); will(returnValue("well-permId")); one(openBisService).createDataSetCode(); @@ -178,14 +177,13 @@ public class SanofiDropboxJythonTest extends AbstractJythonDataSetHandlerTest List<NewSample> registeredSamples = atomicatOperationDetails.recordedObject().getSampleRegistrations(); - assertEquals(6, registeredSamples.size()); + assertEquals(5, registeredSamples.size()); assertAllSamplesHaveContainer(registeredSamples, plate.getIdentifier()); - assertCompoundWell(registeredSamples, "A0", "1.45"); - assertCompoundWell(registeredSamples, "A1", "20.701"); - assertPositiveControl(registeredSamples, "A2"); - assertCompoundWell(registeredSamples, "B0", "0.12"); - assertCompoundWell(registeredSamples, "B1", "0.002"); - assertNegativeControl(registeredSamples, "B2"); + assertCompoundWell(registeredSamples, "A1", "1.45"); + assertPositiveControl(registeredSamples, "A3"); + assertCompoundWell(registeredSamples, "B1", "0.12"); + assertCompoundWell(registeredSamples, "B2", "0.002"); + assertNegativeControl(registeredSamples, "B3"); List<? extends NewExternalData> dataSetsRegistered = atomicatOperationDetails.recordedObject().getDataSetRegistrations();