Beispiel #1
0
    def parallelStart_splitVol(self,
                               job,
                               splitX,
                               splitY,
                               splitZ,
                               verbose=True):
        """
        """

        self.parallelInit()

        import pytom_mpi
        mpi_myid = pytom_mpi.rank()
        if mpi_myid == 0:  # manager
            # distribute the job to the workers and get the original size of the volume
            self.splitVolumes(job, splitX, splitY, splitZ, verbose)

            [vsizeX, vsizeY, vsizeZ] = self.jobInfo["originalSize"]

            # gather results and post processing
            from pytom_volume import vol
            volume = vol(vsizeX, vsizeY, vsizeZ)
            volume.setAll(0)
            orient = vol(vsizeX, vsizeY, vsizeZ)
            orient.setAll(0)

            i = 0
            while i < splitX * splitY * splitZ:
                mpi_msgString = getMsgStr()
                msg = self.getResMsg(mpi_msgString)
                resFromWorker = self.resFromMsg(msg)

                if verbose == True:
                    print("Manager: processing result from worker " +
                          msg.getSender())

                resV = resFromWorker.result.getVolume()
                resO = resFromWorker.orient.getVolume()
                jobID = resFromWorker.jobID

                [sizeX, sizeY, sizeZ] = self.jobInfo["splitSize"]

                [sub_start, start] = self.jobInfo[jobID]

                from pytom_volume import subvolume, putSubVolume
                sub_resV = subvolume(resV, sub_start[0], sub_start[1],
                                     sub_start[2], sizeX, sizeY, sizeZ)
                sub_resO = subvolume(resO, sub_start[0], sub_start[1],
                                     sub_start[2], sizeX, sizeY, sizeZ)

                putSubVolume(sub_resV, volume, start[0], start[1], start[2])
                putSubVolume(sub_resO, orient, start[0], start[1], start[2])

                i = i + 1

            # write the final result back to the disk
            volume.write(self.name + '_res.em')
            orient.write(self.name + '_orient.em')

            # delete the temporary files on the disk
            import os
            files = os.listdir('.')
            for name in files:
                if 'job' in name and '.em' in name and not 'sum' in name and not 'sqr' in name:
                    os.remove(name)

            # rename the result files name
            os.rename('node_0_res.em', 'scores{}{}.em'.format(suffix))
            os.rename('node_0_orient.em', 'angles{}{}.em'.format(suffix))

            # finishing, stop all workers
            self.parallelEnd(verbose)

            if verbose == True:
                print("Manager: end")

        else:  # worker
            worker = PeakWorker()
            worker.parallelRun(verbose)

        pytom_mpi.finalise()
    def maskOut(self, mask, center, size):
        """
        maskOut: Set part of mask volume to all zero. The region is specified by center and size.
        @param mask: volume that you handle with
        @type mask: L{pytom_volume.vol}
        @param center: center of the region
        @type center: [x,y,z]
        @param size: size of the region
        @type size: [sizeX, sizeY, sizeZ] or radius
        """

        from pytom_volume import vol, putSubVolume

        if size.__class__ == list:
            p_sizeX = size[0]
            p_sizeY = size[1]
            p_sizeZ = size[2]
        elif size.__class__ == vol:
            mm = size
            p_sizeX = mm.sizeX()
            p_sizeY = mm.sizeY()
            p_sizeZ = mm.sizeZ()
        else:
            radius = size
            p_sizeX = radius * 2
            p_sizeY = radius * 2
            p_sizeZ = radius * 2

        maskSize = [mask.sizeX(), mask.sizeY(), mask.sizeZ()]

        if maskSize < center:
            raise RuntimeError('Center out of range!')

        # [)
        # mask out double size. CHANGED!!!
        startX = int(center[0] - p_sizeX / 2)
        endX = int(center[0] + p_sizeX / 2)
        startY = int(center[1] - p_sizeY / 2)
        endY = int(center[1] + p_sizeY / 2)
        startZ = int(center[2] - p_sizeZ / 2)
        endZ = int(center[2] + p_sizeZ / 2)

        # only used for radius
        sub_startX = 0
        sub_startY = 0
        sub_startZ = 0

        if startX < 0:
            sub_startX = -startX
            startX = 0
        if endX > maskSize[0]:
            endX = maskSize[0]
        if startY < 0:
            sub_startY = -startY
            startY = 0
        if endY > maskSize[1]:
            endY = maskSize[1]
        if startZ < 0:
            sub_startZ = -startZ
            startZ = 0
        if endZ > maskSize[2]:
            endZ = maskSize[2]

        sizeX = endX - startX
        sizeY = endY - startY
        sizeZ = endZ - startZ

        if size.__class__ == list:
            subV = vol(sizeX, sizeY, sizeZ)
            subV.setAll(0)
        elif size.__class__ == vol:
            from pytom_volume import limit, subvolume
            subV = (mm - 1) / -1
            limit(subV, 0.999, 0, 0, 0, True, False)
            subV = subvolume(subV, sub_startX, sub_startY, sub_startZ, sizeX,
                             sizeY, sizeZ)
            tempV = subvolume(mask, startX, startY, startZ, sizeX, sizeY,
                              sizeZ)
            subV = subV * tempV  # AND operation
        else:
            from pytom_volume import initSphere, subvolume
            subV = vol(radius * 2, radius * 2, radius * 2)
            initSphere(subV, radius, 0, 0, radius, radius, radius)
            tempV = vol(radius * 2, radius * 2, radius * 2)
            tempV.setAll(1)
            subV = tempV - subV
            subV = subvolume(subV, sub_startX, sub_startY, sub_startZ, sizeX,
                             sizeY, sizeZ)
            tempV = subvolume(mask, startX, startY, startZ, sizeX, sizeY,
                              sizeZ)
            subV = subV * tempV  # AND operation

        putSubVolume(subV, mask, startX, startY, startZ)
Beispiel #3
0
    def summarize(self, result, jobID, verbose=True):
        """
        summarize: Get the result and do the summarization accordingly.\
        (Send back, or update result, or write to the disk).

        @param result: result
        @type result: L{pytom.localization.peak_job.PeakResult}
        @param jobID: ID of job
        @type jobID: integer
        """
        resV = result[0]
        orientV = result[1]

        if self.jobInfoPool == {}:  # leaf node
            assert self.backTo != None

            #self.parallelEnd(verbose)
            if not self.backTo is None:
                result = self.writeRes(resV, orientV, jobID)
                result.send(self.mpi_id, self.backTo)
            else:
                self.writeRes(resV, orientV, None)
                self.parallelEnd(verbose)
            return

        # non leaf node, update the result
        if self.jobInfoPool[jobID].splitType == "Ang":
            self.jobInfoPool[
                "numDoneJobsA"] = self.jobInfoPool["numDoneJobsA"] + 1
            offset = self.jobInfoPool[jobID].angleOffset
            #            print self.name + ': JobID ' + str(jobID) + ' Offset ' + str(offset)
            orientV = orientV + offset

            if self.resVolA == None or self.resOrientA == None:
                from pytom_volume import vol
                self.resVolA = vol(resV.sizeX(), resV.sizeY(), resV.sizeZ())
                self.resOrientA = vol(orientV.sizeX(), orientV.sizeY(),
                                      orientV.sizeZ())
                self.resVolA.copyVolume(resV)
                self.resOrientA.copyVolume(orientV)
            else:
                from pytom_volume import updateResFromVol
                updateResFromVol(self.resVolA, resV, self.resOrientA, orientV)

            if self.jobInfoPool["numDoneJobsA"] == self.jobInfoPool[
                    "numJobsA"] and self.jobInfoPool["numJobsV"] > 0:
                self.summarize([self.resVolA, self.resOrientA],
                               self.jobInfoPool[jobID].originalJobID, verbose)
                return
        elif self.jobInfoPool[jobID].splitType == "Vol":
            self.jobInfoPool[
                "numDoneJobsV"] = self.jobInfoPool["numDoneJobsV"] + 1
            [originX, originY, originZ] = self.jobInfoPool[jobID].origin
            if self.resVol == None or self.resOrient == None:
                from pytom_volume import vol
                [vsizeX, vsizeY, vsizeZ] = self.jobInfoPool[jobID].originalSize

                self.resVol = vol(vsizeX, vsizeY, vsizeZ)
                self.resVol.setAll(0)
                self.resOrient = vol(vsizeX, vsizeY, vsizeZ)
                self.resOrient.setAll(0)

            [vsizeX, vsizeY, vsizeZ] = self.jobInfoPool[jobID].originalSize
            [sizeX, sizeY, sizeZ] = self.jobInfoPool[jobID].splitSize
            sub_start = self.jobInfoPool[jobID].sub_start
            start = self.jobInfoPool[jobID].whole_start

            stepSizeX = min(vsizeX - sub_start[0], sizeX)
            stepSizeY = min(vsizeY - sub_start[1], sizeY)
            stepSizeZ = min(vsizeZ - sub_start[2], sizeZ)

            from pytom_volume import subvolume, putSubVolume
            sub_resV = subvolume(resV, sub_start[0], sub_start[1],
                                 sub_start[2], stepSizeX, stepSizeY, stepSizeZ)
            sub_resO = subvolume(orientV, sub_start[0], sub_start[1],
                                 sub_start[2], stepSizeX, stepSizeY, stepSizeZ)

            putSubVolume(sub_resV, self.resVol, start[0] - originX,
                         start[1] - originY, start[2] - originZ)
            putSubVolume(sub_resO, self.resOrient, start[0] - originX,
                         start[1] - originY, start[2] - originZ)
        else:
            raise RuntimeError("Unclear split type!")

        # if all results are there, write back to disk and return to high level
        if self.jobInfoPool["numDoneJobsA"] + self.jobInfoPool[
                "numDoneJobsV"] == self.jobInfoPool[
                    "numJobsA"] + self.jobInfoPool["numJobsV"]:
            if self.jobInfoPool["numJobsV"] == 0:
                self.resVol = self.resVolA
                self.resOrient = self.resOrientA

            if self.backTo != None:
                result = self.writeRes(self.resVol, self.resOrient,
                                       self.jobInfoPool[jobID].originalJobID)
                if verbose == True:
                    print(self.name + ': sending back result to ' +
                          str(self.backTo))
                result.send(self.mpi_id, self.backTo)
            else:
                # write the final result to the disk
                self.writeRes(self.resVol, self.resOrient)
                self.parallelEnd(verbose)
    def findParticles(self,
                      sizeParticle,
                      maxNumParticle=0,
                      minScore=-1,
                      write2disk=0,
                      margin=None,
                      offset=[0, 0, 0]):
        """
        findParticles: Find particles in target volume according to the result volume.
        @param sizeParticle: size or radius of searched particle
        @type sizeParticle: [x,y,z] or integer
        @param maxNumParticle: maximal number of particles you want to pick
        @type maxNumParticle: integer
        @param minScore: minimal score as threshold
        @type minScore: float 
        @param write2disk: write the found particles to the disk or not (0: do not write, otherwise the length of each dimension)
        @type write2disk: integer
        @param margin: set the margin of the score volume
        @param margin: [x,y,z] or integer
        
        @return: list of found particles
        @rtype: L{pytom.localization.structures.FoundParticle}
        """
        from pytom_volume import vol, peak, putSubVolume, read
        from pytom.localization.structures import FoundParticle

        # prepare the mask
        x = self.result.sizeX()
        y = self.result.sizeY()
        z = self.result.sizeZ()

        if sizeParticle.__class__ == list:
            xP = sizeParticle[0]
            yP = sizeParticle[1]
            zP = sizeParticle[2]
        elif sizeParticle.__class__ == vol:
            xP = sizeParticle.sizeX()
            yP = sizeParticle.sizeY()
            zP = sizeParticle.sizeZ()
        else:
            radius = sizeParticle
            xP = 2 * sizeParticle
            yP = 2 * sizeParticle
            zP = 2 * sizeParticle

        if margin:
            if margin.__class__ == list:
                marginX, marginY, marginZ = margin
            else:
                marginX = marginY = marginZ = margin
        else:  # no margin given, set automatically
            marginX = int(xP / 2)
            marginY = int(yP / 2)
            marginZ = int(zP / 2)

        mask = vol(x, y, z)
        mask.setAll(0)

        maskIn = vol(x - 2 * marginX, y - 2 * marginY, z - 2 * marginZ)
        maskIn.setAll(1)
        putSubVolume(maskIn, mask, marginX, marginY, marginZ)

        # progress bar
        from pytom.tools.ProgressBar import FixedProgBar
        prog = FixedProgBar(0, maxNumParticle - 1, '')

        # find the particles
        resList = []
        for i in range(maxNumParticle):
            prog.update(i)

            try:
                posV = peak(self.result, mask)
            except:
                break  # the mask is all zero

            [scoreV, orientV] = self.get(posV[0], posV[1], posV[2])
            # test if the peak score is bigger than minimal threshold
            if scoreV > minScore:
                particleFilename = 'particle_' + str(i) + '.em'
                if write2disk:
                    # write the found particle to the disk
                    l = write2disk
                    v = read(self.volFilename, posV[0] - l / 2,
                             posV[1] - l / 2, posV[2] - l / 2, l, l, l, 0, 0,
                             0, 0, 0, 0)
                    v.write(particleFilename)

                score = self.score()
                score.setValue(scoreV)
                from pytom.basic.structures import PickPosition, Rotation
                pos = PickPosition(posV, originFilename=self.volFilename)
                pos + offset
                orientation = Rotation(orientV)
                p = FoundParticle(pos, orientation, score, particleFilename)

                resList.append(p)

                if sizeParticle.__class__ == list:
                    self.maskOut(mask, posV, [xP, yP, zP])
                elif sizeParticle.__class__ == vol:
                    self.maskOut(mask, posV, sizeParticle)
                else:
                    self.maskOut(mask, posV, radius)
            else:
                break

        return resList