def test_execute_ControlDozor_eiger4m(self):
     referenceDataPath = self.dataPath / "ControlDozor_eiger4m.json"
     self.inData = UtilsTest.loadAndSubstitueTestData(referenceDataPath)
     controlDozor = ControlDozor(inData=self.inData)
     controlDozor.execute()
     self.assertTrue(controlDozor.isSuccess())
     outData = controlDozor.outData
     self.assertEqual(len(outData["imageQualityIndicators"]), 4)
예제 #2
0
 def test_execute_ControlDozor_wedgeNumber(self):
     referenceDataPath = self.dataPath / 'ControlDozor_wedgeNumber.json'
     self.inData = UtilsTest.loadAndSubstitueTestData(referenceDataPath)
     controlDozor = ControlDozor(inData=self.inData)
     controlDozor.execute()
     self.assertTrue(controlDozor.isSuccess())
     outData = controlDozor.outData
     self.assertEqual(len(outData['imageQualityIndicators']), 740)
예제 #3
0
 def test_execute_ControlDozor_ispyb_h5(self):
     currentSite = UtilsConfig.getSite()
     referenceDataPath = self.dataPath / 'ControlDozor_ispyb_hdf5.json'
     self.inData = UtilsTest.loadAndSubstitueTestData(referenceDataPath)
     controlDozor = ControlDozor(inData=self.inData)
     controlDozor.execute()
     UtilsConfig.setSite(currentSite)
     self.assertTrue(controlDozor.isSuccess())
     outData = controlDozor.outData
     self.assertEqual(len(outData['imageQualityIndicators']), 51)
예제 #4
0
    def testCreateListOfBatches(self):
        self.assertEqual([[1], [2], [3], [4], [5]],
                         ControlDozor.createListOfBatches(range(1, 6), 1))

        self.assertEqual([[1, 2], [3, 4], [5]],
                         ControlDozor.createListOfBatches(range(1, 6), 2))

        self.assertEqual([[1, 2, 3], [4, 5]],
                         ControlDozor.createListOfBatches(range(1, 6), 3))

        self.assertEqual([[1, 2, 3, 4], [5]],
                         ControlDozor.createListOfBatches(range(1, 6), 4))

        self.assertEqual([[1, 2, 3, 4, 5]],
                         ControlDozor.createListOfBatches(range(1, 6), 5))

        self.assertEqual(
            [[1], [2], [4], [5], [6]],
            ControlDozor.createListOfBatches(
                list(range(4, 7)) + list(range(1, 3)), 1),
        )

        self.assertEqual(
            [[1, 2], [4, 5], [6]],
            ControlDozor.createListOfBatches(
                list(range(4, 7)) + list(range(1, 3)), 2),
        )

        self.assertEqual(
            [[1, 2], [4, 5, 6]],
            ControlDozor.createListOfBatches(
                list(range(4, 7)) + list(range(1, 3)), 3),
        )
예제 #5
0
 def synchronizeDozor(self, listDozorTask, listDistlResult):
     listImageQualityIndicators = []
     listControlDozorAllFile = []
     for (
         controlDozor,
         inDataControlDozor,
         listBatch,
     ) in listDozorTask:
         controlDozor.join()
         # Check that we got at least one result
         if len(controlDozor.outData["imageQualityIndicators"]) == 0:
             # Run the dozor plugin again, this time synchronously
             firstImage = listBatch[0]
             lastImage = listBatch[-1]
             logger.warning(
                 "No dozor results! Re-executing Dozor for"
                 + " images {0} to {1}".format(firstImage, lastImage)
             )
             time.sleep(5)
             controlDozor = ControlDozor(inDataControlDozor)
             controlDozor.execute()
         listOutDataControlDozor = list(
             controlDozor.outData["imageQualityIndicators"]
         )
         if self.doDistlSignalStrength:
             for outDataControlDozor in listOutDataControlDozor:
                 for distlResult in listDistlResult:
                     if outDataControlDozor["image"] == distlResult["image"]:
                         imageQualityIndicators = dict(outDataControlDozor)
                         imageQualityIndicators.update(distlResult)
                         listImageQualityIndicators.append(imageQualityIndicators)
         else:
             listImageQualityIndicators += listOutDataControlDozor
         # Check if dozorm
         if self.doDozorM:
             listControlDozorAllFile.append(controlDozor.outData["dozorAllFile"])
     return listImageQualityIndicators, listControlDozorAllFile
예제 #6
0
 def test_makePlot(self):
     workingDirectory = UtilsTest.getTestRunPath()
     dataCollectionId = 123456
     outDataPath = self.dataPath / "outDataControlDozor.json"
     with open(str(outDataPath)) as f:
         outData = json.load(f)
     controlDozor = ControlDozor(inData={})
     controlDozor.template = "mesh-test_1_%4d.cbf"
     controlDozor.directory = UtilsTest.getTestImageDirPath().as_posix()
     controlDozor.makePlot(dataCollectionId, outData, workingDirectory)
예제 #7
0
class ControlDozorUnitTest(unittest.TestCase):
    def setUp(self):
        self.dataPath = os.path.join(os.path.dirname(__file__), "data")
        referenceDataPath = os.path.join(self.dataPath, "ControlDozor.json")
        with open(referenceDataPath) as f:
            self.inData = json.loads(f.read())
        self.controlDozor = ControlDozor(inData=self.inData)

    def testCreateDict(self):
        dictImage = self.controlDozor.createImageDict(self.inData)
        self.assertEqual(True, isinstance(dictImage, dict))

    def testCreateListOfBatches(self):
        self.assertEqual([[1], [2], [3], [4], [5]],
                         ControlDozor.createListOfBatches(range(1, 6), 1))

        self.assertEqual([[1, 2], [3, 4], [5]],
                         ControlDozor.createListOfBatches(range(1, 6), 2))

        self.assertEqual([[1, 2, 3], [4, 5]],
                         ControlDozor.createListOfBatches(range(1, 6), 3))

        self.assertEqual([[1, 2, 3, 4], [5]],
                         ControlDozor.createListOfBatches(range(1, 6), 4))

        self.assertEqual([[1, 2, 3, 4, 5]],
                         ControlDozor.createListOfBatches(range(1, 6), 5))

        self.assertEqual(
            [[1], [2], [4], [5], [6]],
            ControlDozor.createListOfBatches(
                list(range(4, 7)) + list(range(1, 3)), 1),
        )

        self.assertEqual(
            [[1, 2], [4, 5], [6]],
            ControlDozor.createListOfBatches(
                list(range(4, 7)) + list(range(1, 3)), 2),
        )

        self.assertEqual(
            [[1, 2], [4, 5, 6]],
            ControlDozor.createListOfBatches(
                list(range(4, 7)) + list(range(1, 3)), 3),
        )
예제 #8
0
 def runControlDozor(listSubWedge):
     listControlDozor = []
     listOutDataControlDozor = []
     for subWedge in listSubWedge:
         listSubWedgeImage = subWedge["image"]
         for image in listSubWedgeImage:
             # listImage.append(image['path'])
             inDataControlDozor = {"image": [image["path"]]}
             controlDozor = ControlDozor(
                 inData=inDataControlDozor,
                 workingDirectorySuffix=UtilsImage.getPrefixNumber(
                     image["path"]),
             )
             listControlDozor.append(controlDozor)
             controlDozor.start()
     for controlDozor in listControlDozor:
         controlDozor.join()
         if controlDozor.isSuccess():
             listOutDataControlDozor.append(controlDozor.outData)
     return listOutDataControlDozor
예제 #9
0
 def setUp(self):
     self.dataPath = os.path.join(os.path.dirname(__file__), "data")
     referenceDataPath = os.path.join(self.dataPath, "ControlDozor.json")
     with open(referenceDataPath) as f:
         self.inData = json.loads(f.read())
     self.controlDozor = ControlDozor(inData=self.inData)
예제 #10
0
 def runDozorAndDistl(self, listOfBatches):
     #
     # Loop over batches:
     # - Wait for all files in batch
     # - Run Dozor and DistlSignalStrength (if required) in parallel
     #
     listDistlTask = []
     listDozorTask = []
     template4d = re.sub("#+", "{0:04d}", self.template)
     for listOfImagesInBatch in listOfBatches:
         listOfH5FilesInBatch = []
         imageNo = listOfImagesInBatch[-1]
         # Wait for last image
         imagePath = self.directory / template4d.format(imageNo)
         logger.debug("Waiting for path: {0}".format(imagePath))
         self.waitForImagePath(
             imagePath=imagePath,
             batchSize=self.batchSize,
             isFastMesh=self.isFastMesh,
             minImageSize=self.minImageSize,
             waitFileTimeOut=self.waitFileTimeOut,
             listofH5FilesInBatch=listOfH5FilesInBatch,
         )
         logger.debug("Done waiting for path: {0}".format(imagePath))
         if not self.isFailure():
             # Determine start and end image no
             batchStartNo = listOfImagesInBatch[0]
             batchEndNo = listOfImagesInBatch[-1]
             dozorTemplate = self.template
             logger.debug("Before sleeping 2 s, start no = {0}".format(batchStartNo))
             time.sleep(2)
             logger.debug("After sleeping 2 s, start no = {0}".format(batchStartNo))
             # Run Control Dozor
             inDataControlDozor = {
                 "template": dozorTemplate,
                 "directory": self.directory,
                 "startNo": batchStartNo,
                 "endNo": batchEndNo,
                 "batchSize": self.batchSize,
                 "doSubmit": self.doSubmit,
                 "doDozorM": self.doDozorM,
                 "doIspybUpload": self.doIspybUpload,
                 "dataCollectionId": self.dataCollectionId
             }
             if self.beamline is not None:
                 inDataControlDozor["beamline"] = self.beamline
             controlDozor = ControlDozor(
                 inDataControlDozor,
                 workingDirectorySuffix="{0:04d}_{1:04d}".format(
                     batchStartNo, batchEndNo
                 ),
             )
             controlDozor.start()
             listDozorTask.append(
                 (controlDozor, inDataControlDozor, list(listOfImagesInBatch))
             )
             # Check if we should run distl.signalStrength
             if self.doDistlSignalStrength:
                 for imageNo in listOfImagesInBatch:
                     imagePath = self.directory / template4d.format(imageNo)
                     inDataDistl = {"referenceImage": str(imagePath)}
                     distlTask = DistlSignalStrengthTask(
                         inData=inDataDistl,
                         workingDirectorySuffix=imageNo,
                     )
                     distlTask.start()
                     listDistlTask.append((imagePath, distlTask))
     return listDozorTask, listDistlTask
예제 #11
0
    def run(self, inData):
        beamline = inData.get('beamline', None)
        doSubmit = inData.get('doSubmit', False)
        doDozorm = inData.get('doDozorm', False)
        batchSize = inData.get('batchSize', 1)
        doDistlSignalStrength = inData.get('doDistlSignalStrength', False)
        doIndexing = inData.get('doIndexing', False)
        if crystFelImportFailed:
            doCrystfel = False
        else:
            doCrystfel = inData.get('doCrystfel', True)
        isFastMesh = inData.get('fastMesh', False)
        # Loop through all the incoming reference images
        listImage = inData.get('image', [])
        if len(listImage) == 0:
            directory = pathlib.Path(inData['directory'])
            template = inData['template']
            startNo = inData['startNo']
            endNo = inData['endNo']
            listImage = []
            for index in range(startNo, endNo + 1):
                imageName = template.replace("####", "{0:04d}".format(index))
                imagePath = directory / imageName
                listImage.append(str(imagePath))
        else:
            firstImage = listImage[0]
            lastImage = listImage[-1]
            directory = pathlib.Path(firstImage).parent
            template = UtilsImage.getTemplate(firstImage)
            startNo = UtilsImage.getImageNumber(firstImage)
            endNo = UtilsImage.getImageNumber(lastImage)
        outData = dict()
        listImageQualityIndicators = []
        listcrystfel_output = []
        inDataWaitFile = {}
        listDistlTask = []
        listDozorTask = []
        listCrystFELTask = []
        listOfImagesInBatch = []
        listOfAllBatches = []
        listOfAllH5Files = []
        listControlDozorAllFile = []
        indexBatch = 0
        self.listH5FilePath = []
        detectorType = None
        # Configurations
        minImageSize = UtilsConfig.get(
            self, 'minImageSize', defaultValue=DEFAULT_MIN_IMAGE_SIZE)
        waitFileTimeOut = UtilsConfig.get(
            self, 'waitFileTimeOut', defaultValue=DEFAULT_WAIT_FILE_TIMEOUT)
        # Process data in batches
        for image in listImage:
            listOfImagesInBatch.append(pathlib.Path(image))
            if len(listOfImagesInBatch) == batchSize:
                listOfAllBatches.append(listOfImagesInBatch)
                listOfImagesInBatch = []
        if len(listOfImagesInBatch) > 0:
            listOfAllBatches.append(listOfImagesInBatch)
            listOfImagesInBatch = []
        if UtilsImage.getSuffix(pathlib.Path(listImage[0])) == 'h5':
            for image in listImage:
                listOfAllH5Files.append(pathlib.Path(image))
        #
        # Loop over batches:
        # - Wait for all files in batch
        # - Run Dozor and Crystfel (if required) in parallel
        #
        # Check if we should run CrystFEL:

        for listOfImagesInBatch in listOfAllBatches:
            listOfH5FilesInBatch = []
            for imagePath in listOfImagesInBatch:
                # First wait for images
                self.waitForImagePath(
                    imagePath=imagePath,
                    batchSize=batchSize,
                    isFastMesh=isFastMesh,
                    minImageSize=minImageSize,
                    waitFileTimeOut=waitFileTimeOut,
                    listofH5FilesInBatch=listOfH5FilesInBatch
                )
            if not self.isFailure():
                # Determine start and end image no
                pathToFirstImage = listOfImagesInBatch[0]
                pathToLastImage = listOfImagesInBatch[-1]
                batchStartNo = UtilsImage.getImageNumber(pathToFirstImage)
                batchEndNo = UtilsImage.getImageNumber(pathToLastImage)
                # Run Control Dozor
                inDataControlDozor = {
                    'template': template,
                    'directory': directory,
                    'startNo': batchStartNo,
                    'endNo': batchEndNo,
                    'batchSize': batchSize,
                    'doSubmit': doSubmit,
                    'doDozorm': doDozorm
                }
                if beamline is not None:
                    inDataControlDozor["beamline"] = beamline
                controlDozor = ControlDozor(
                    inDataControlDozor,
                    workingDirectorySuffix='{0:04d}_{1:04d}'.format(batchStartNo, batchEndNo))
                controlDozor.start()
                listDozorTask.append((controlDozor, inDataControlDozor,
                                      list(listOfImagesInBatch), listOfH5FilesInBatch))
                # Check if we should run distl.signalStrength
                if doDistlSignalStrength:
                    for image in listOfImagesInBatch:
                        inDataDistl = {
                            'referenceImage': str(image)
                        }
                        distlTask = DistlSignalStrengthTask(
                            inData=inDataDistl,
                            workingDirectorySuffix=UtilsImage.getImageNumber(image))
                        distlTask.start()
                        listDistlTask.append((image, distlTask))

        if not self.isFailure():
            # listIndexing = []
            listDistlResult = []
            # Synchronize all image quality indicator plugins and upload to ISPyB
            for (image, distlTask) in listDistlTask:
                imageQualityIndicators = {}
                if distlTask is not None:
                    distlTask.join()
                    if distlTask.isSuccess():
                        outDataDistl = distlTask.outData
                        if outDataDistl is not None:
                            imageQualityIndicators = outDataDistl['imageQualityIndicators']
                imageQualityIndicators['image'] = str(image)
                listDistlResult.append(imageQualityIndicators)
                # self.xsDataResultControlImageQualityIndicators.addImageQualityIndicators(xsDataImageQualityIndicators)
            for (controlDozor, inDataControlDozor, listBatch, listH5FilePath) in listDozorTask:
                controlDozor.join()
                # Check that we got at least one result
                if len(controlDozor.outData['imageQualityIndicators']) == 0:
                    # Run the dozor plugin again, this time synchronously
                    firstImage = listBatch[0].name
                    lastImage = listBatch[-1].name
                    logger.warning("No dozor results! Re-executing Dozor for" +
                                   " images {0} to {1}".format(firstImage, lastImage))
                    time.sleep(5)
                    controlDozor = ControlDozor(inDataControlDozor)
                    controlDozor.execute()
                listOutDataControlDozor = list(controlDozor.outData['imageQualityIndicators'])
                if detectorType is None:
                    detectorType = controlDozor.outData['detectorType']
                if doDistlSignalStrength:
                    for outDataControlDozor in listOutDataControlDozor:
                        for distlResult in listDistlResult:
                            if outDataControlDozor['image'] == distlResult['image']:
                                imageQualityIndicators = dict(outDataControlDozor)
                                imageQualityIndicators.update(distlResult)
                                listImageQualityIndicators.append(imageQualityIndicators)
                else:
                    listImageQualityIndicators += listOutDataControlDozor
                # Check if dozorm
                if doDozorm:
                    listControlDozorAllFile.append(controlDozor.outData['dozorAllFile'])

        if not self.isFailure() and doCrystfel:
            # Select only the strongest images to be run by CrystFEL
            listIndicatorsSorted = sorted(listImageQualityIndicators, key=lambda k: k['dozorScore'])[::-1]
            listForCrystFEL = [k['image'] for k in listIndicatorsSorted[0:min(200, len(listIndicatorsSorted))]]
            batchSize = 20
            if len(listForCrystFEL) % batchSize == 0:
                file_chunk = int(len(listForCrystFEL) / batchSize)
            else:
                file_chunk = int(len(listForCrystFEL) / batchSize) + 1
            for jj in range(file_chunk):
                start = batchSize * jj
                stop = batchSize * (jj + 1)
                try:
                    images = listForCrystFEL[start:stop]
                except IndexError:
                    stop = start + (len(listForCrystFEL) - stop)
                    images = listForCrystFEL[start:stop]

                inDataCrystFEL = {
                    'doCBFtoH5': False,
                    'cbfFileInfo': {
                        'directory': directory,
                        'template': template,
                        'batchSize': batchSize,
                        'listofImages': images
                    },
                    'doSubmit': doSubmit
                }
                crystfel = ExeCrystFEL(inData=inDataCrystFEL)
                crystfel.start()
                listCrystFELTask.append(crystfel)

            masterstream = str(self.getWorkingDirectory() / 'alltogether.stream')
            if not self.isFailure():
                for crystfel in listCrystFELTask:
                    crystfel.join()
                    if crystfel.isSuccess():
                        catcommand = "cat %s >> %s" % (crystfel.outData['streamfile'], masterstream)
                        AutoCrystFEL.run_as_command(catcommand)

            if not self.isFailure() and os.path.exists(masterstream):
                crystfel_outdata = AutoCrystFEL.report_stats(masterstream)
                crystfel_outdata['number of DozorHits'] = len(listForCrystFEL)
                AutoCrystFEL.write_cell_file(crystfel_outdata)
                listcrystfel_output.append(crystfel_outdata)
            else:
                logger.error("CrystFEL did not run properly")
        # Assemble all controlDozorAllFiles into one
        if doDozorm:
            imageQualityIndicatorsDozorAllFile = str(self.getWorkingDirectory() / "dozor_all")
            os.system('touch {0}'.format(imageQualityIndicatorsDozorAllFile))
            for controlDozorAllFile in listControlDozorAllFile:
                command = 'cat ' + controlDozorAllFile + ' >> ' + imageQualityIndicatorsDozorAllFile
                os.system(command)
            outData["dozorAllFile"] = imageQualityIndicatorsDozorAllFile

        outData['imageQualityIndicators'] = listImageQualityIndicators
        outData['crystfel_results'] = listcrystfel_output
        return outData