def classifyStep(self):

        listNumImgs = []
        listNameImgs = []
        change = False

        level=0
        while len(listNumImgs) is not self.numberOfClasses.get() \
                or change is True:

            if self.useReferenceImages and self.numberOfClasses.get() \
                    == getSize(self.refSet):
                if not exists(join(self._getExtraPath(), 'level%03d' % level)):
                    mkdir(join(self._getExtraPath(), 'level%03d' % level))
                copy(self.refSet, self._getExtraPath(join('level%03d' % level,
                                                'intermediate_classes.xmd')))
            else:
                self.splitStep(level)

                #######################################
                if not self.useAttraction:
                    self.attractionSplitStep(level)
                #######################################

                self.generateMetadata(listNameImgs, listNumImgs, level)

            self.ref = self._getExtraPath(join('level%03d' % level,
                                               'intermediate_classes.xmd'))
            lengthMd = getSize(self.ref)
            if lengthMd==self.numberOfClasses.get():
                self.classifyWholeSetStep(level)
                #######################################################
                if not self.useAttraction:
                    change, listNumImgs, listNameImgs = \
                        self.attractionGeneralStep(level)
                    if change:
                        level = level + 1
                        continue
                #######################################################
                copy(self._getExtraPath(join('level%03d' % level,
                                             'general_level%03d' % level
                                             + '_classes.xmd')),
                     self._getExtraPath('last_classes.xmd'), )
                if exists(self._getExtraPath(join('level%03d' % level,
                                                  'general_images_level%03d'
                                                  % level + '.xmd'))):
                    copy(self._getExtraPath(join('level%03d' % level,
                                                 'general_images_level%03d'
                                                 % level + '.xmd')),
                         self._getExtraPath('last_images.xmd'), )
                return

            listNumImgs, listNameImgs = self.checkOutput(level)
            self.cleaningPath(level)
            level = level + 1
 def _runClassifSteps(self, fnOut, fnBlock, fnDir,
                      imgNo, fnGallery, callbackMethod=None):
     nop = self.noOfParticles.get()
     if callbackMethod and not exists(fnOut):
         if md.getSize(fnBlock) > nop:
             # try:
             callbackMethod(fnOut, fnBlock, fnDir, imgNo, fnGallery)
Esempio n. 3
0
    def _evalStop(self):
        noOfLevRuns = self._getLevRuns(self._level)

        if self.IS_3D and self.useReslog:
            slope, y0, err = self._getReslogVars()

        for rLev in noOfLevRuns:
            iters = self._lastIter(rLev)
            modelFn = self._getFileName('model', iter=iters,
                                        lev=self._level, rLev=rLev)
            modelMd = md.MetaData('model_classes@' + modelFn)
            partMdFn = "particles@" + self._getFileName('input_star',
                                                        lev=self._level,
                                                        rLev=rLev)
            partSize = md.getSize(partMdFn)
            clsId = 1
            for row in md.iterRows(modelMd):
                fn = row.getValue(md.RLN_MLMODEL_REF_IMAGE)
                clasDist = row.getValue('rlnClassDistribution')
                classSize = int(clasDist * partSize)

                if self._getClasDistCond(clasDist):
                    mapId = self._mapsDict[fn]
                    ptcStop = self.minPartsToStop.get()
                    if classSize < int(0.95*partSize):
                        if self.IS_3D and self.useReslog:
                            suffixSsnr = 'model_class_%d@' % clsId
                            ssnrMd = md.MetaData(suffixSsnr + modelFn)
                            f = self._getFunc(ssnrMd)
                            ExpcVal = slope*np.math.log10(classSize) + y0
                            val = f(1) + (2*err)
                            clsId += 1
                            print("StopValues: \n"
                                  "Val SSnr=1: %0.4f, parts %d, ExpcVal "
                                  "%0.4f" % (val, classSize, ExpcVal))
                            evalSlope = val < ExpcVal and self._level > 2
                        else:
                            evalSlope = False
                    else:
                        evalSlope = True

                    print("Values to stop the classification: ")
                    print("Lev: ", self._level, "rLev: ", rLev)
                    print("partSize: ", partSize)
                    print("class size: ", classSize)
                    print("min parts to stop: ", ptcStop)
                    print("evalSlope: ", evalSlope)
                    if classSize < ptcStop or evalSlope:
                        self.stopDict[mapId] = True
                        if not bool(self._clsIdDict):
                            self._clsIdDict[mapId] = 1
                        else:
                            classId = sorted(self._clsIdDict.values())[-1] + 1
                            self._clsIdDict[mapId] = classId
                    else:
                        self.stopDict[mapId] = False
Esempio n. 4
0
    def splitStep(self, expImgMd):
        i = 0
        classesOut = None
        while i < self.numberOfSplitIterations:
            outImgs, classesOut = self.iterationStep(classesOut, expImgMd, i,
                                                     True)
            i += 1
            length = md.getSize(classesOut)
            if length == 1:
                i = 0

        self.generateMdForClassification(classesOut)
    def sortImagesStep(self):
        args = "-i Particles@%s -o %s --addToInput " % (self.fnInputMd,
                                                        self.fnOutputMd)
        if os.path.exists(self.fnInputOldMd):
            args += "-t Particles@%s " % self.fnInputOldMd

        if self.autoParRejection == self.REJ_MAXZSCORE:
            args += "--zcut " + str(self.maxZscore.get())
        elif self.autoParRejection == self.REJ_PERCENTAGE:
            args += "--percent " + str(self.percentage.get())

        if self.addFeatures:
            args += "--addFeatures "

        self.runJob("xmipp_image_sort_by_statistics", args)

        args = "-i Particles@%s -o %s" % (self.fnInputMd, self.fnOutputMd)
        if self.autoParRejectionSSNR == self.REJ_PERCENTAGE_SSNR:
            args += " --ssnrpercent " + str(self.percentageSSNR.get())
        self.runJob("xmipp_image_ssnr", args)

        if self.autoParRejectionVar != self.REJ_NONE:
            print('Rejecting by variance:')
            if self.outputSize == 0:
                varList = []
                giniList = []
                print('  - Reading metadata')
                mdata = emlib.MetaData(self.fnInputMd)
                for objId in mdata:
                    varList.append(mdata.getValue(emlib.MDL_SCORE_BY_VAR, objId))
                    giniList.append(mdata.getValue(emlib.MDL_SCORE_BY_GINI, objId))

                if self.autoParRejectionVar == self.REJ_VARIANCE:
                    valuesList = varList
                    self.mdLabels = [emlib.MDL_SCORE_BY_VAR]
                else:  # not working pretty well
                    valuesList = [var*(1-gini) for var, gini in zip(varList, giniList)]
                    self.mdLabels = [emlib.MDL_SCORE_BY_VAR, emlib.MDL_SCORE_BY_GINI]

                self.varThreshold.set(histThresholding(valuesList))
                print('  - Variance threshold: %f' % self.varThreshold)

            rejectByVariance(self.fnInputMd, self.fnOutputMd, self.varThreshold,
                             self.autoParRejectionVar)

        # update the processed particles
        self.outputSize += getSize(self.fnInputMd)
 def _createAngDist2D(self, it, heatmap):
     fnDir = self.protocol._getExtraPath("Iter%03d"%it)
     fnAngles = join(fnDir,"angles.xmd")
     view=None
     if exists(fnAngles):
         fnAnglesSqLite = join(fnDir,"angles.sqlite")
         from pwem.viewers import EmPlotter
         if not exists(fnAnglesSqLite):
             from pwem.emlib.metadata import getSize
             self.createAngDistributionSqlite(fnAnglesSqLite, getSize(fnAngles), itemDataIterator=self._iterAngles(fnAngles))
         view = EmPlotter(x=1, y=1, mainTitle="Iteration %d" % it, windowTitle="Angular distribution")
         if heatmap:
             axis = view.plotAngularDistributionFromMd(fnAnglesSqLite, '', histogram=True)
             view.getFigure().colorbar(axis)
         else:
             view.plotAngularDistributionFromMd(fnAnglesSqLite, '')
     return view
Esempio n. 7
0
    def _createFinalMetadata(self):
        fnClasses = self._getExtraPath('last_classes.xmd')
        numClasses = md.getSize(fnClasses)

        for i in range(numClasses):
            num = i + 1
            fn = self._getExtraPath('dataClass%06d.xmd' % num)
            if exists(fn):
                line = ""
                numLine = 0
                while not line.startswith('    '):
                    numLine += 1
                    line = popen('sed -n %ip %s' % (numLine, fn)).read()
                aux = self._getExtraPath('aux.xmd')
                system('head -%i %s >> %s' % (numLine - 1, fn, aux))

                dataHeader = self._getExtraPath('dataHeader.xmd')
                fp = open(aux, 'r')
                fout = open(dataHeader, 'w')
                for i, line in enumerate(fp):
                    if i < 2:
                        continue
                    if not line.startswith('data_noname'):
                        fout.write(line)
                    else:
                        line = line.replace('noname', 'class%06d_images' % num)
                        fout.write(line)
                fp.close()
                fout.close()
                cleanPath(aux)
                fnOut = self._getExtraPath('dataImages%06d.xmd' % num)
                system('tail -n +%i %s >> %s' % (i + 2, fn, aux))
                system('cat %s %s >> %s' % (dataHeader, aux, fnOut))
                if num == 1:
                    system('cat %s >> %s' %
                           (fn, self._getExtraPath('last_images.xmd')))
                else:
                    system('cat %s >> %s' %
                           (aux, self._getExtraPath('last_images.xmd')))
                cleanPath(aux)
                cleanPath(dataHeader)
                system('cat %s >> %s' %
                       (fnOut, self._getExtraPath('last_classes.xmd')))
Esempio n. 8
0
    def reconstructStep(self, fnRoot):
        from pwem.emlib.metadata import getSize
        if os.path.exists(fnRoot+".xmd"):
            Nimages=getSize(fnRoot+".xmd")
            if Nimages>0:
                if self.useGpu.get():
                    # protocol will run several reconstructions at once, so execute each reconstruction separately
                    args = "-i %s.xmd -o %s.vol --sym %s --thr %s --fast"\
                           % (fnRoot, fnRoot, self.symmetryGroup.get(), self.numberOfThreads.get())

                    #AJ to make it work with and without queue system
                    if self.numberOfMpi.get()>1:
                        N_GPUs = len((self.gpuList.get()).split(','))
                        args += ' -gpusPerNode %d' % N_GPUs
                        args += ' -threadsPerGPU %d' % max(self.numberOfThreads.get(),4)
                    count=0
                    GpuListCuda=''
                    if self.useQueueForSteps() or self.useQueue():
                        GpuList = os.environ["CUDA_VISIBLE_DEVICES"]
                        GpuList = GpuList.split(",")
                        for elem in GpuList:
                            GpuListCuda = GpuListCuda+str(count)+' '
                            count+=1
                    else:
                        GpuListAux = ''
                        for elem in self.getGpuList():
                            GpuListCuda = GpuListCuda+str(count)+' '
                            GpuListAux = GpuListAux+str(elem)+','
                            count+=1
                        os.environ["CUDA_VISIBLE_DEVICES"] = GpuListAux
                    if self.numberOfMpi.get()==1:
                        args += " --device %s" %GpuListCuda
                    if self.numberOfMpi.get()>1:
                        self.runJob('xmipp_cuda_reconstruct_fourier', args, numberOfMpi=len((self.gpuList.get()).split(','))+1)
                    else:
                        self.runJob('xmipp_cuda_reconstruct_fourier', args)
                else:
                    self.runJob("xmipp_reconstruct_fourier_accel","-i %s.xmd -o %s.vol --sym %s "
                                %(fnRoot,fnRoot,self.symmetryGroup.get()))
                self.runJob("xmipp_transform_mask","-i %s.vol --mask circular -%d "%(fnRoot,self.Xdim2/2))
        else:
            print(fnRoot+".xmd is empty. The corresponding volume is not generated.")
    def _createAngDistChimera(self, it):
        fnDir = self.protocol._getExtraPath("Iter%03d"%it)
        fnAngles = join(fnDir,"angles.xmd")
        view=None
        if exists(fnAngles):
            fnAnglesSqLite = join(fnDir,"angles.sqlite")
            from pwem.emlib.metadata import getSize
            self.createAngDistributionSqlite(fnAnglesSqLite, getSize(fnAngles),
                                             itemDataIterator=self._iterAngles(fnAngles))
            vol = os.path.join(fnDir, "volumeAvg.mrc")
            extraFilesPath = self.protocol._getExtraPath()
            volOrigin = self.protocol.outputVolume.getShiftsFromOrigin()
            radius = self.spheresScale.get()
            view = ChimeraAngDist(vol, extraFilesPath,
                                  angularDistFile=fnAngles,
                                  spheresDistance=radius,
                                  voxelSize=self.protocol.outputVolume.getSamplingRate(),
                                  volOrigin=volOrigin,
                                  showProjection=True)

        return view
    def homogeneizeStep(self):
        minClass = self.homogeneize.get()
        fnNeighbours = self._getExtraPath("neighbours.xmd")

        # Look for the block with the minimum number of images
        if minClass == 0:
            minClass = 1e38
            for block in emlib.getBlocksInMetaDataFile(fnNeighbours):
                projNumber = int(block.split("_")[1])
                fnDir = self._getExtraPath("direction_%d" % projNumber,
                                           "level_00", "class_classes.xmd")
                if exists(fnDir):
                    blockSize = md.getSize("class000001_images@" + fnDir)
                    if blockSize < minClass:
                        minClass = blockSize

        # Construct the homogeneized metadata
        mdAll = emlib.MetaData()
        mdSubset = emlib.MetaData()
        mdRandom = emlib.MetaData()
        for block in emlib.getBlocksInMetaDataFile(fnNeighbours):
            projNumber = int(block.split("_")[1])
            fnDir = self._getExtraPath("direction_%d" % projNumber, "level_00",
                                       "class_classes.xmd")
            if exists(fnDir):
                mdDirection = emlib.MetaData("class000001_images@" + fnDir)
                mdRandom.randomize(mdDirection)
                mdSubset.selectPart(mdRandom, 0, min(mdRandom.size(),
                                                     minClass))
                mdAll.unionAll(mdSubset)
        mdAll.removeDuplicates(md.MDL_ITEM_ID)
        mdAll.sort(md.MDL_ITEM_ID)
        mdAll.fillConstant(md.MDL_PARTICLE_ID, 1)
        fnHomogeneous = self._getExtraPath("images_homogeneous.xmd")
        mdAll.write(fnHomogeneous)
        self.runJob("xmipp_metadata_utilities",
                    '-i %s --operate modify_values "particleId=itemId"' %
                    fnHomogeneous,
                    numberOfMpi=1)
    def significantStep(self, iterNumber, alpha):
        iterDir = self._getTmpPath('iter%03d' % iterNumber)
        makePath(iterDir)
        prevVolFn = self.getIterVolume(iterNumber - 1)
        volFn = self.getIterVolume(iterNumber)
        anglesFn = self._getExtraPath('angles_iter%03d.xmd' % iterNumber)

        t = Timer()
        t.tic()
        if self.useGpu.get() and iterNumber > 1:
            # Generate projections
            fnGalleryRoot = join(iterDir, "gallery")
            args = "-i %s -o %s.stk --sampling_rate %f --sym %s " \
                   "--compute_neighbors --angular_distance -1 " \
                   "--experimental_images %s --min_tilt_angle %f " \
                   "--max_tilt_angle %f -v 0 --perturb %f " % \
                   (prevVolFn, fnGalleryRoot, self.angularSampling.get(),
                    self.symmetryGroup, self.imgsFn, self.minTilt, self.maxTilt,
                    math.sin(self.angularSampling.get()) / 4)
            self.runJob("xmipp_angular_project_library ", args, numberOfMpi=1)

            if self.trueSymsNo != 0:
                alphaApply = (alpha * self.trueSymsNo) / 2
            else:
                alphaApply = alpha / 2
            from pwem.emlib.metadata import getSize
            N = int(getSize(fnGalleryRoot + '.doc') * alphaApply * 2)

            count = 0
            GpuListCuda = ''
            if self.useQueueForSteps() or self.useQueue():
                GpuList = os.environ["CUDA_VISIBLE_DEVICES"]
                GpuList = GpuList.split(",")
                for elem in GpuList:
                    GpuListCuda = GpuListCuda + str(count) + ' '
                    count += 1
            else:
                GpuList = ' '.join([str(elem) for elem in self.getGpuList()])
                GpuListAux = ''
                for elem in self.getGpuList():
                    GpuListCuda = GpuListCuda + str(count) + ' '
                    GpuListAux = GpuListAux + str(elem) + ','
                    count += 1
                os.environ["CUDA_VISIBLE_DEVICES"] = GpuListAux

            args = '-i %s -r %s.doc -o %s --keepBestN %f --dev %s ' % \
                   (self.imgsFn, fnGalleryRoot, anglesFn, N, GpuListCuda)
            self.runJob(CUDA_ALIGN_SIGNIFICANT, args, numberOfMpi=1)

            cleanPattern(fnGalleryRoot + "*")
        else:
            args = self.getSignificantArgs(self.imgsFn)
            args += ' --odir %s' % iterDir
            args += ' --alpha0 %f --alphaF %f' % (alpha, alpha)
            args += ' --dontCheckMirrors '

            if iterNumber == 1:
                if self.thereisRefVolume:
                    args += " --initvolumes " + \
                            self._getExtraPath('input_volumes.xmd')
                else:
                    args += " --numberOfVolumes 1"
            else:
                args += " --initvolumes %s" % prevVolFn

            self.runJob("xmipp_reconstruct_significant", args)
            moveFile(os.path.join(iterDir, 'angles_iter001_00.xmd'), anglesFn)
        t.toc('Significant took: ')

        reconsArgs = ' -i %s --fast' % anglesFn
        reconsArgs += ' -o %s' % volFn
        reconsArgs += ' --weight -v 0  --sym %s ' % self.symmetryGroup

        print("Number of images for reconstruction: ",
              metadata.getSize(anglesFn))
        t.tic()
        if self.useGpu.get():
            cudaReconsArgs = reconsArgs
            #AJ to make it work with and without queue system
            if self.numberOfMpi.get() > 1:
                N_GPUs = len((self.gpuList.get()).split(','))
                cudaReconsArgs += ' -gpusPerNode %d' % N_GPUs
                cudaReconsArgs += ' -threadsPerGPU %d' % max(
                    self.numberOfThreads.get(), 4)
            count = 0
            GpuListCuda = ''
            if self.useQueueForSteps() or self.useQueue():
                GpuList = os.environ["CUDA_VISIBLE_DEVICES"]
                GpuList = GpuList.split(",")
                for elem in GpuList:
                    GpuListCuda = GpuListCuda + str(count) + ' '
                    count += 1
            else:
                GpuListAux = ''
                for elem in self.getGpuList():
                    GpuListCuda = GpuListCuda + str(count) + ' '
                    GpuListAux = GpuListAux + str(elem) + ','
                    count += 1
                os.environ["CUDA_VISIBLE_DEVICES"] = GpuListAux
            cudaReconsArgs += ' --thr %s' % self.numberOfThreads.get()
            if self.numberOfMpi.get() == 1:
                cudaReconsArgs += ' --device %s' % (GpuListCuda)
            if self.numberOfMpi.get() > 1:
                self.runJob('xmipp_cuda_reconstruct_fourier',
                            cudaReconsArgs,
                            numberOfMpi=len(
                                (self.gpuList.get()).split(',')) + 1)
            else:
                self.runJob('xmipp_cuda_reconstruct_fourier', cudaReconsArgs)
        else:
            self.runJob("xmipp_reconstruct_fourier_accel", reconsArgs)
        t.toc('Reconstruct fourier took: ')

        # Center the volume
        fnSym = self._getExtraPath('volumeSym_%03d.vol' % iterNumber)
        self.runJob("xmipp_transform_mirror",
                    "-i %s -o %s --flipX" % (volFn, fnSym),
                    numberOfMpi=1)
        self.runJob("xmipp_transform_mirror",
                    "-i %s --flipY" % fnSym,
                    numberOfMpi=1)
        self.runJob("xmipp_transform_mirror",
                    "-i %s --flipZ" % fnSym,
                    numberOfMpi=1)
        self.runJob("xmipp_image_operate",
                    "-i %s --plus %s" % (fnSym, volFn),
                    numberOfMpi=1)
        self.runJob("xmipp_volume_align",
                    '--i1 %s --i2 %s --local --apply' % (fnSym, volFn),
                    numberOfMpi=1)
        cleanPath(fnSym)

        # To mask the volume
        xdim = self.inputSet.get().getDimensions()[0]
        maskArgs = "-i %s --mask circular %d -v 0" % (volFn, -xdim / 2)
        self.runJob('xmipp_transform_mask', maskArgs, numberOfMpi=1)
        # TODO mask the final volume in some smart way...

        # To filter the volume
        if self.useMaxRes:
            self.runJob('xmipp_transform_filter',
                        '-i %s --fourier low_pass %f --sampling %f' % \
                        (volFn, self.maxResolution.get(), self.TsCurrent),
                        numberOfMpi=1)

        if not self.keepIntermediate:
            cleanPath(prevVolFn, iterDir)

        if self.thereisRefVolume:
            cleanPath(self._getExtraPath('filteredVolume.vol'))
Esempio n. 12
0
    def iterationStep(self, refSet, imgsExp, iter, flag_split):

        if flag_split:
            outImgs, classesOut = self._getOutputSplitFn()
        else:
            outImgs, classesOut = self._getOutputClassFn()

        outDirName = splitext(imgsExp)[0]
        if iter == 0 and flag_split == True:

            # First step: divide the metadata input file to generate
            # a couple of references
            self._params = {'imgsExp': imgsExp, 'outDir': outDirName}
            args = ('-i %(imgsExp)s -n 2 --oroot %(outDir)s')
            self.runJob("xmipp_metadata_split",
                        args % self._params,
                        numberOfMpi=1)

            # Second step: calculate the means of the previous metadata
            expSet1 = outDirName + '000001.xmd'
            avg1 = outDirName + '_000001'
            expSet2 = outDirName + '000002.xmd'
            avg2 = outDirName + '_000002'
            self._params = {'imgsSet': expSet1, 'outputAvg': avg1}
            args = ('-i %(imgsSet)s --save_image_stats %(outputAvg)s -v 0')
            self.runJob("xmipp_image_statistics",
                        args % self._params,
                        numberOfMpi=1)

            self._params = {'imgsSet': expSet2, 'outputAvg': avg2}
            args = ('-i %(imgsSet)s --save_image_stats %(outputAvg)s -v 0')
            self.runJob("xmipp_image_statistics",
                        args % self._params,
                        numberOfMpi=1)

            # Third step: generate a single metadata with the two previous avgs
            refSet = self._getExtraPath('refSet.xmd')
            self._params = {
                'avg1': avg1 + 'average.xmp',
                'avg2': avg2 + 'average.xmp',
                'outputMd': refSet
            }
            args = ('-i %(avg1)s --set union %(avg2)s -o %(outputMd)s')
            self.runJob("xmipp_metadata_utilities",
                        args % self._params,
                        numberOfMpi=1)

        # Fourth step: calling program xmipp_cuda_align_significant
        metadataRef = md.MetaData(refSet)
        if metadataRef.containsLabel(md.MDL_REF) is False:
            args = ('-i %(outputMd)s --fill ref lineal 1 1 -o %(outputMd)s')
            self.runJob("xmipp_metadata_utilities",
                        args % self._params,
                        numberOfMpi=1)

        count = 0
        GpuListCuda = ''
        if self.useQueueForSteps() or self.useQueue():
            GpuList = os.environ["CUDA_VISIBLE_DEVICES"]
            GpuList = GpuList.split(",")
            for elem in GpuList:
                GpuListCuda = GpuListCuda + str(count) + ' '
                count += 1
        else:
            GpuListAux = ''
            for elem in self.getGpuList():
                GpuListCuda = GpuListCuda + str(count) + ' '
                GpuListAux = GpuListAux + str(elem) + ','
                count += 1
            os.environ["CUDA_VISIBLE_DEVICES"] = GpuListAux

        if flag_split:
            fileTocopy = classesOut.replace('.xmd', '_classes.xmd')
            fileTocopy = fileTocopy.replace('extra/', 'extra/level_00/')
            self._params = {
                'imgsRef': refSet,
                'imgsExp': imgsExp,
                'maxshift': self.maximumShift,
                'Nrefs': md.getSize(refSet),
                'outDir': self._getExtraPath(),
                'outImgCuda': self._getExtraPath("images.xmd"),
                'rootFn': classesOut.split('/')[-1].replace('.xmd', ''),
                'keepBest': self.keepBest.get(),
                'outClassesCuda': fileTocopy,
            }

            args = '-i %(imgsExp)s --ref0 %(imgsRef)s --nref %(Nrefs)d ' \
                   '--iter 1 --distance correlation --classicalMultiref ' \
                   '--maxShift %(maxshift)d --odir %(outDir)s --oroot %(' \
                   'rootFn)s --dontMirrorImages '
            self.runJob("xmipp_classify_CL2D",
                        args % self._params,
                        numberOfMpi=self.numberOfMpi.get())
            copy(fileTocopy, classesOut)
            copy(self._getExtraPath("images.xmd"), outImgs)

        else:
            self._params = {
                'imgsRef': refSet,
                'imgsExp': imgsExp,
                'outputFile': outImgs,
                'keepBest': self.keepBest.get(),
                'maxshift': self.maximumShift,
                'outputClassesFile': classesOut,
                'device': GpuListCuda,
                'outputClassesFileNoExt': splitext(classesOut)[0],
                'auxOut': self._getExtraPath('flipReferences%06d.xmd' % iter),
            }

            args = '-i %(imgsExp)s -r %(imgsRef)s -o %(outputFile)s ' \
                   '--keepBestN 1 --oUpdatedRefs %(outputClassesFileNoExt)s --dev %(device)s '
            self.runJob(CUDA_ALIGN_SIGNIFICANT,
                        args % self._params,
                        numberOfMpi=1)

        if exists(outDirName + '000001.xmd'):
            cleanPath(expSet1)
            cleanPath(expSet2)
            cleanPath(avg1 + 'average.xmp')
            cleanPath(avg2 + 'average.xmp')
            cleanPath(avg1 + 'stddev.xmp')
            cleanPath(avg2 + 'stddev.xmp')

        return outImgs, classesOut
    def generateMetadata(self, listNameImgs, listNumImgs, level):

        # Renumerate unchanged classes
        listNewNumImages = [-1] * len(listNumImgs)
        count = 1
        for i in range(len(listNumImgs)):
            if listNumImgs[i] != -1:
                listNewNumImages[i] = count
                count += 1

        # Construct the new classes with the renumerated old classes
        mdNewClasses = md.MetaData()
        for i in range(len(listNumImgs)):
            if listNumImgs[i] != -1:
                name = listNameImgs[i]
                fn = name[name.find('@') + 1:-4] + '.xmd'
                numRef = int(name[0:6])

                mdClass = md.MetaData("classes@" + fn)
                for row in iterRows(mdClass):
                    if mdClass.getValue(md.MDL_REF, row.getObjId()) == numRef:
                        row.setValue(md.MDL_REF, listNewNumImages[i])
                        row.addToMd(mdNewClasses)

        # Add the two new classes to the list of renumerated classes
        outSet = self._getExtraPath(join('level%03d' % level, 'level%03d' %
                                         level + '_classes.xmd'))
        mdClass = md.MetaData("classes@" + outSet)
        rows = iterRows(mdClass)
        for row in rows:
            row.setValue(md.MDL_REF, count)
            row.addToMd(mdNewClasses)
            count = count + 1
        mdNewClasses.write('classes@' + self._getExtraPath(join('level%03d'
                                        % level,'intermediate_classes.xmd')),
                           MD_APPEND)

        # Generate the intermediate images and the blocks of the intermediate
        # classes for the unchanged classes
        for i in range(len(listNumImgs)):
            if listNumImgs[i] != -1:
                name = listNameImgs[i]
                fn = name[name.find('@') + 1:-4] + '.xmd'
                numRef = int(name[0:6])

                # Read the list of images in this class
                mdImgsInClass = md.MetaData(
                    'class%06d_images@%s' % (numRef, fn))
                mdImgsInClass.fillConstant(md.MDL_REF, listNewNumImages[i])
                mdImgsInClass.write('class%06d' % (listNewNumImages[i])
                                    + '_images@' + self._getExtraPath(join(
                                    'level%03d' % level,
                                    'intermediate_classes.xmd')),
                                    MD_APPEND)

        # Add the two new classes
        if len(listNumImgs) == 0:
            count = 1
        else:
            count = len(listNumImgs)
        for newRef in range(getSize(outSet)):
            mdImgsInClass = md.MetaData('class%06d_images@%s' % (newRef + 1, outSet))
            mdImgsInClass.fillConstant(md.MDL_REF, count)
            mdImgsInClass.write('class%06d' % (count) + '_images@'
                                + self._getExtraPath(join('level%03d' %
                                level,'intermediate_classes.xmd')),
                                MD_APPEND)
            count = count + 1
    def iterationStep (self, refSet, imgsExp, iter, useReferenceImages,
                       level, flag_split, flag_attraction):

        if not exists(join(self._getExtraPath(), 'level%03d' % level)):
            mkdir(join(self._getExtraPath(), 'level%03d' % level))

        if not useReferenceImages and iter==0 and flag_split==True:

            # First step: divide the metadata input file to generate
            # a couple of references
            if level==0:
                if not flag_attraction:
                    outDirName = imgsExp[0:imgsExp.find('extra')+6] +  \
                                 'level%03d' % level +  imgsExp[imgsExp.find(
                        'extra')+5:-4]
                else:
                    outDirName = imgsExp[0:imgsExp.find('extra') + 6] +  \
                                 'level%03d' % level +  imgsExp[imgsExp.find(
                        'level%03d' % level) + 8:-4]
            else:
                if not flag_attraction:
                    outDirName = imgsExp[0:imgsExp.find('extra') + 6] +  \
                                 'level%03d' % level +  imgsExp[imgsExp.find(
                        'level%03d' % (level-1)) + 8:-4]
                else:
                    outDirName = imgsExp[0:imgsExp.find('extra') + 6] +  \
                                 'level%03d' % level +  imgsExp[imgsExp.find(
                        'level%03d' % level) + 8:-4]
            self._params = {'imgsExp': imgsExp,
                            'outDir': outDirName}
            args = ('-i %(imgsExp)s -n 2 --oroot %(outDir)s')
            self.runJob("xmipp_metadata_split", args % self._params,
                        numberOfMpi=1)

            # Second step: calculate the means of the previous metadata
            expSet1 = outDirName + '000001.xmd'
            avg1 = outDirName + '_000001'
            expSet2 = outDirName + '000002.xmd'
            avg2 = outDirName + '_000002'
            self._params = {'imgsSet': expSet1,
                            'outputAvg': avg1}
            args = ('-i %(imgsSet)s --save_image_stats %(outputAvg)s -v 0')
            self.runJob("xmipp_image_statistics", args % self._params,
                        numberOfMpi=1)

            self._params = {'imgsSet': expSet2,
                            'outputAvg': avg2}
            args = ('-i %(imgsSet)s --save_image_stats %(outputAvg)s -v 0')
            self.runJob("xmipp_image_statistics", args % self._params,
                        numberOfMpi=1)

            # Third step: generate a single metadata with the two previous
            # averages
            refSet = self._getExtraPath(join('level%03d' % level,'refSet.xmd'))
            self._params = {'avg1': avg1 + 'average.xmp',
                            'avg2': avg2 + 'average.xmp',
                            'outputMd': refSet}
            args = ('-i %(avg1)s --set union %(avg2)s -o %(outputMd)s')
            self.runJob("xmipp_metadata_utilities", args % self._params,
                        numberOfMpi=1)

        # Fourth step: calling program xmipp_cuda_align_significant
        metadataRef = md.MetaData(refSet)
        if metadataRef.containsLabel(md.MDL_REF) is False:
            args = ('-i %s --fill ref lineal 1 1 -o %s'%(refSet, refSet))
            self.runJob("xmipp_metadata_utilities", args,
                        numberOfMpi=1)

        count = 0
        GpuListCuda = ''
        if self.useQueueForSteps() or self.useQueue():
            GpuList = environ["CUDA_VISIBLE_DEVICES"]
            GpuList = GpuList.split(",")
            for elem in GpuList:
                GpuListCuda = GpuListCuda + str(count) + ' '
                count += 1
        else:
            GpuListAux = ''
            for elem in self.getGpuList():
                GpuListCuda = GpuListCuda + str(count) + ' '
                GpuListAux = GpuListAux + str(elem) + ','
                count += 1
            environ["CUDA_VISIBLE_DEVICES"] = GpuListAux

        if flag_split:
            filename = 'level%03d' % level+'_classes.xmd'
            self._params = {'imgsRef': refSet,
                            'imgsExp': imgsExp,
                            'outputFile': 'images_level%03d' % level+'.xmd',
                            'tmpDir': join(self._getExtraPath(),'level%03d'
                                           % level),
                            'keepBest': self.keepBest.get(),
                            'maxshift': self.maximumShift,
                            'outputClassesFile': filename,
                            'device': GpuListCuda,
                            'outputClassesFileNoExt': splitext(filename)[0],
                            }
        else:
            filename = 'general_level%03d' % level + '_classes.xmd'
            self._params = {'imgsRef': refSet,
                            'imgsExp': imgsExp,
                            'outputFile': 'general_images_level%03d' % level
                                          + '.xmd',
                            'tmpDir': join(self._getExtraPath(),'level%03d'
                                           % level),
                            'keepBest': self.keepBest.get(),
                            'maxshift': self.maximumShift,
                            'outputClassesFile': filename,
                            'device': GpuListCuda,
                            'outputClassesFileNoExt': splitext(filename)[0],
                            }
        Nrefs = getSize(refSet)
        if Nrefs>2:

                args = '-i %(imgsExp)s -r %(imgsRef)s -o %(outputFile)s ' \
                       '--keepBestN 1 --oUpdatedRefs %(outputClassesFileNoExt)s ' \
                       '--odir %(tmpDir)s --dev %(device)s'
                self.runJob(CUDA_ALIGN_SIGNIFICANT, args % self._params, numberOfMpi=1)

        else:
            self._params['Nrefs'] = Nrefs
            self._params['cl2dDir'] = self._getExtraPath(join('level%03d' % level))
            self._params['cl2dDirNew'] = self._getExtraPath(join('level%03d' % level, "level_00"))
            args='-i %(imgsExp)s --ref0 %(imgsRef)s --nref %(Nrefs)d '\
                 '--iter 1 --distance correlation --classicalMultiref '\
                 '--maxShift %(maxshift)d --odir %(cl2dDir)s --dontMirrorImages '
            self.runJob("xmipp_classify_CL2D",
                        args % self._params, numberOfMpi=self.numberOfMpi.get())

            if flag_split:
                copy(self._getExtraPath(join('level%03d' % level,
                                             "level_00","class_classes.xmd")),
                     self._getExtraPath(join('level%03d' % level,
                                             'level%03d' % level
                                             + '_classes.xmd')))
                copy(self._getExtraPath(join('level%03d' % level,"images.xmd")),
                     self._getExtraPath(join('level%03d' % level,
                                             'images_level%03d' % level +
                                             '.xmd')))
            else:
                copy(self._getExtraPath(join('level%03d' % level,
                                             "level_00", "class_classes.xmd")),
                     self._getExtraPath(join('level%03d' % level,
                                             'general_level%03d' % level +
                                             '_classes.xmd')))
                copy(self._getExtraPath(join('level%03d' % level,
                                             "images.xmd")),
                     self._getExtraPath(join('level%03d' % level,
                                             'general_images_level%03d' %
                                             level + '.xmd')))
    def classifyOneGroup(self, projNumber, projMdBlock, projRef, mdClasses,
                         mdImages):
        """ Classify one of the neighbourhood groups if not empty.
         Class information will be stored in output metadata: mdOut
        """
        blockSize = md.getSize(projMdBlock)
        Nclasses = self.directionalClasses.get()
        Nlevels = int(math.ceil(math.log(Nclasses) / math.log(2)))

        # Skip projection directions with not enough images to
        # create a given number of classes
        if blockSize / Nclasses < 10:
            return

        fnDir = self._getExtraPath("direction_%s" % projNumber)
        makePath(fnDir)

        # Run CL2D classification for the images assigned to one direction
        args = "-i %s " % projMdBlock
        args += "--odir %s " % fnDir
        args += "--ref0 %s --iter %d --nref %d " % (
            projRef, self.cl2dIterations, Nclasses)
        args += "--distance correlation --classicalMultiref "
        args += "--maxShift %f " % self.maxShift
        try:
            self.runJob("xmipp_classify_CL2D", args)
        except:
            return

        # After CL2D the stk and xmd files should be produced
        classesXmd = join(fnDir, "level_%02d/class_classes.xmd" % Nlevels)
        classesStk = join(fnDir, "level_%02d/class_classes.stk" % Nlevels)

        # Let's check that the output was produced
        if not exists(classesStk):
            return

        # Run align of the class average and the projection representative
        fnAlignRoot = join(fnDir, "classes")
        args = "-i %s " % classesStk
        args += "--ref %s " % projRef
        args += " --oroot %s --iter 1" % fnAlignRoot
        self.runJob("xmipp_image_align", args, numberOfMpi=1)

        # Apply alignment
        args = "-i %s_alignment.xmd --apply_transform" % fnAlignRoot
        self.runJob("xmipp_transform_geometry", args, numberOfMpi=1)

        for classNo in range(1, Nclasses + 1):
            localImagesMd = emlib.MetaData("class%06d_images@%s" %
                                           (classNo, classesXmd))

            # New class detected
            self.classCount += 1
            # Check which images have not been assigned yet to any class
            # and assign them to this new class
            for objId in localImagesMd:
                imgId = localImagesMd.getValue(emlib.MDL_ITEM_ID, objId)
                # Add images not classify yet and store their class number
                if imgId not in self.classImages:
                    self.classImages.add(imgId)
                    newObjId = mdImages.addObject()
                    mdImages.setValue(emlib.MDL_ITEM_ID, imgId, newObjId)
                    mdImages.setValue(emlib.MDL_REF2, self.classCount,
                                      newObjId)

            newClassId = mdClasses.addObject()
            mdClasses.setValue(emlib.MDL_REF, projNumber, newClassId)
            mdClasses.setValue(emlib.MDL_REF2, self.classCount, newClassId)
            mdClasses.setValue(emlib.MDL_IMAGE,
                               "%d@%s" % (classNo, classesStk), newClassId)
            mdClasses.setValue(emlib.MDL_IMAGE1, projRef, newClassId)
            mdClasses.setValue(emlib.MDL_CLASS_COUNT, localImagesMd.size(),
                               newClassId)
Esempio n. 16
0
    def classifyOneGroup(self, projNumber, projMdBlock, projRef, mdClasses,
                         mdImages):
        """ Classify one of the neighbourhood groups if not empty.
         Class information will be stored in output metadata: mdOut
        """
        blockSize = md.getSize(projMdBlock)
        fnToUse = projMdBlock
        if self.maxCLimgs > 0 and blockSize > self.maxCLimgs:
            fnToUSe = self._getTmpPath("coneImages.xmd")
            self.runJob("xmipp_metadata_utilities","-i %s -o %s --operate random_subset %d"\
                        %(projMdBlock,fnToUSe,self.maxCLimgs),numberOfMpi=1)
        Nclasses = self.directionalClasses.get()
        Nlevels = int(math.ceil(math.log(Nclasses) / math.log(2)))

        # Skip projection directions with not enough images to
        # create a given number of classes
        if blockSize / Nclasses < 10:
            return

        if self.useGpu.get():
            count = 0
            GpuListCuda = ''
            if self.useQueueForSteps() or self.useQueue():
                GpuList = os.environ["CUDA_VISIBLE_DEVICES"]
                GpuList = GpuList.split(",")
                for elem in GpuList:
                    GpuListCuda = GpuListCuda + str(count) + ' '
                    count += 1
            else:
                GpuList = ' '.join([str(elem) for elem in self.getGpuList()])
                GpuListAux = ''
                for elem in self.getGpuList():
                    GpuListCuda = GpuListCuda + str(count) + ' '
                    GpuListAux = GpuListAux + str(elem) + ','
                    count += 1
                os.environ["CUDA_VISIBLE_DEVICES"] = GpuListAux

            fnDir = self._getExtraPath("direction_%s" % projNumber)
            if not exists(fnDir):
                makePath(fnDir)

            for i in range(self.class2dIterations.get()):
                mdRefName = join(fnDir, 'reference.xmd')
                if i == 0:
                    mdRef = md.MetaData()
                    for j in range(2):
                        row = md.Row()
                        row.setValue(md.MDL_REF, j + 1)
                        row.setValue(md.MDL_IMAGE, projRef)
                        row.addToMd(mdRef)
                    mdRef.write(mdRefName, emlib.MD_APPEND)
                else:
                    mdRefName = join(fnDir, "level_%02d" % (i - 1),
                                     "class_classes.xmd")
                if not exists(join(fnDir, "level_%02d" % i)):
                    makePath(join(fnDir, "level_%02d" % i))
                args = '-i %s -r %s -o images.xmd --odir %s' \
                       ' --keepBestN 1 --oUpdatedRefs %s ' % (fnToUse, mdRefName, join(fnDir,"level_%02d"%i), 'class_classes')
                args += ' --dev %s ' % GpuListCuda
                self.runJob(CUDA_ALIGN_SIGNIFICANT, args, numberOfMpi=1)
            copy(
                join(fnDir, "level_%02d" % (self.class2dIterations.get() - 1),
                     "images.xmd"), join(fnDir, "images.xmd"))

            # After classification the stk and xmd files should be produced
            classesXmd = join(
                fnDir, "level_%02d/class_classes.xmd" %
                (self.class2dIterations.get() - 1))
            classesStk = join(
                fnDir, "level_%02d/class_classes.stk" %
                (self.class2dIterations.get() - 1))

        else:
            fnDir = self._getExtraPath("direction_%s" % projNumber)
            if not exists(join(fnDir, "level_00")):
                makePath(fnDir)
                # Run CL2D classification for the images assigned to one direction
                args = "-i %s " % fnToUse
                args += "--odir %s " % fnDir
                args += "--ref0 %s --iter %d --nref %d " % \
                        (projRef, self.class2dIterations, Nclasses)
                args += "--distance correlation --classicalMultiref "
                args += "--maxShift %f " % self.maxShift
                try:
                    self.runJob("xmipp_classify_CL2D",
                                args,
                                numberOfMpi=self.numberOfMpi.get() *
                                self.numberOfThreads.get())
                except:
                    return

            # After CL2D the stk and xmd files should be produced
            classesXmd = join(fnDir, "level_%02d/class_classes.xmd" % Nlevels)
            classesStk = join(fnDir, "level_%02d/class_classes.stk" % Nlevels)

        # Let's check that the output was produced
        if not exists(classesStk):
            return

        # Run align of the class average and the projection representative
        fnAlignRoot = join(fnDir, "classes")
        args = "-i %s " % classesStk
        args += "--ref %s " % projRef
        args += " --oroot %s --iter 1" % fnAlignRoot
        self.runJob("xmipp_image_align", args, numberOfMpi=1)

        # Apply alignment
        args = "-i %s_alignment.xmd --apply_transform" % fnAlignRoot
        self.runJob("xmipp_transform_geometry", args, numberOfMpi=1)

        for classNo in range(1, Nclasses + 1):
            localImagesMd = emlib.MetaData("class%06d_images@%s" %
                                           (classNo, classesXmd))

            # New class detected
            self.classCount += 1
            # Check which images have not been assigned yet to any class
            # and assign them to this new class
            for objId in localImagesMd:
                imgId = localImagesMd.getValue(emlib.MDL_ITEM_ID, objId)
                # Add images not classify yet and store their class number
                if imgId not in self.classImages:
                    self.classImages.add(imgId)
                    newObjId = mdImages.addObject()
                    mdImages.setValue(emlib.MDL_ITEM_ID, imgId, newObjId)
                    mdImages.setValue(emlib.MDL_REF2, self.classCount,
                                      newObjId)

            newClassId = mdClasses.addObject()
            mdClasses.setValue(emlib.MDL_REF, projNumber, newClassId)
            mdClasses.setValue(emlib.MDL_REF2, self.classCount, newClassId)
            mdClasses.setValue(emlib.MDL_IMAGE,
                               "%d@%s" % (classNo, classesStk), newClassId)
            mdClasses.setValue(emlib.MDL_IMAGE1, projRef, newClassId)
            mdClasses.setValue(emlib.MDL_CLASS_COUNT, localImagesMd.size(),
                               newClassId)