Пример #1
0
class Angles(EMObject):
    """Represents a triplet of angles"""

    def __init__(self, **args):
        EMObject.__init__(self, **args)
        self._angleY = Float()    
        self._angleY2 = Float()
        self._angleTilt = Float()
        
    def setAngles(self, angleY, angleY2, angleTilt):
        self._angleY.set(angleY)
        self._angleY2.set(angleY2)
        self._angleTilt.set(angleTilt)
        
    def getAngles(self):
        return (self._angleY.get(), self._angleY2.get(), self._angleTilt.get())
    def createOutputStep(self):
        outputVols = self._createSetOfVolumes()

        for vol in self._iterInputVols():
            volume = vol.clone()
            volDir = self._getVolDir(vol.getObjId())
            volPrefix = 'vol%03d_' % (vol.getObjId())
            validationMd = self._getExtraPath(volPrefix + 'validation.xmd')
            moveFile(join(volDir, 'validation.xmd'), validationMd)
            clusterMd = self._getExtraPath(volPrefix +
                                           'clusteringTendency.xmd')
            moveFile(join(volDir, 'clusteringTendency.xmd'), clusterMd)

            mData = md.MetaData(validationMd)
            weight = mData.getValue(md.MDL_WEIGHT, mData.firstObject())
            volume._xmipp_weight = Float(weight)
            volume.clusterMd = String(clusterMd)
            volume.cleanObjId(
            )  # clean objects id to assign new ones inside the set
            outputVols.append(volume)

        outputVols.setSamplingRate(self.partSet.getSamplingRate())
        self._defineOutputs(outputVolumes=outputVols)
        self._defineTransformRelation(self.inputVolumes, outputVols)
Пример #3
0
    def createOutputStep(self, coordinates):
        outSet = self._createSetOfCoordinates3D(coordinates)
        outSet.setPrecedents(coordinates.getPrecedents())
        outSet.setBoxSize(coordinates.getBoxSize())
        outSet.setSamplingRate(coordinates.getSamplingRate())
        scoreCarbon = dict(self.scoreCarbon) if self.carbon.get() else None
        scoreOutliers = dict(
            self.scoreOutliers) if self.outliers.get() else None

        for coord in coordinates.iterCoordinates():
            newCoord = coord.clone()
            newCoord.setBoxSize(outSet.getBoxSize())
            newCoord.setVolume(coord.getVolume())
            scoreCoordOutlier = scoreOutliers[
                coord.getObjId()] if scoreOutliers else None
            scoreCoordCarbon = scoreCarbon[
                coord.getObjId()] if scoreCarbon else None
            if self.filter.get():
                if self.outliers.get() and not self.carbon.get():
                    if self.outliersThreshold.get() >= scoreCoordOutlier:
                        newCoord.outlierScore = Float(scoreCoordOutlier)
                        outSet.append(newCoord)
                elif not self.outliers.get() and self.carbon.get():
                    if self.carbonThreshold.get() <= scoreCoordCarbon:
                        newCoord.carbonScore = Float(scoreCoordCarbon)
                        outSet.append(newCoord)
                elif self.outliers.get() and self.carbon.get():
                    if self.outliersThreshold.get() >= scoreCoordOutlier and \
                       self.carbonThreshold.get() <= scoreCoordCarbon:
                        newCoord.outlierScore = Float(scoreCoordOutlier)
                        newCoord.carbonScore = Float(scoreCoordCarbon)
                        outSet.append(newCoord)
                else:
                    print("All scoring modes are disabled. Exting")
                    break
            else:
                if self.outliers.get():
                    newCoord.outlierScore = Float(scoreCoordOutlier)
                if self.carbon.get():
                    newCoord.carbonScore = Float(scoreCoordCarbon)
                outSet.append(newCoord)
        self._defineOutputs(outputCoordinates=outSet)
        self._defineSourceRelation(coordinates, outSet)
 def _updateZScore(self, img, imgRow):
     zscore = imgRow.getValue(md.RLN_SELECT_PARTICLES_ZSCORE)
     img._rlnSelectParticlesZscore = Float(zscore)
Пример #5
0
    def _initializeZscores(self):

        # Store the set for later access , ;-(
        self.minZScore = Float()
        self.maxZScore = Float()
        self.sumZScore = Float()
Пример #6
0
class XmippProtMonoRes(ProtAnalysis3D):
    """    
    Given a map the protocol assigns local resolutions to each voxel of the map.
    """
    _label = 'local MonoRes'
    _lastUpdateVersion = VERSION_1_1
    
    def __init__(self, **args):
        ProtAnalysis3D.__init__(self, **args)
        self.min_res_init = Float() 
        self.max_res_init = Float() 
        
    
    # --------------------------- DEFINE param functions --------------------------------------------
    def _defineParams(self, form):
        form.addSection(label='Input')

        form.addParam('halfVolumes', BooleanParam, default=False,
                      label="Would you like to use half volumes?",
                      help='The noise estimation for determining the local resolution '
                           'is performed via half volumes.')

        form.addParam('inputVolumes', PointerParam, pointerClass='Volume',
                      label="Input Volume", important=True,
                      condition = 'not halfVolumes',
                      help='Select a volume for determining its local resolution.')

        form.addParam('inputVolume', PointerParam, pointerClass='Volume',
                      label="Volume Half 1", important=True,
                      condition = 'halfVolumes', 
                      help='Select a volume for determining its local resolution.')

        form.addParam('inputVolume2', PointerParam, pointerClass='Volume',
                      label="Volume Half 2", important=True,
                      condition='halfVolumes',
                      help='Select a second volume for determining a local resolution.')

        form.addParam('Mask', PointerParam, pointerClass='VolumeMask', 
                      condition='(halfVolumes) or (not halfVolumes)',
                      label="Binary Mask", important=True,
                      help='The mask determines which points are specimen and which ones not')

        group = form.addGroup('Extra parameters')
        group.addParam('symmetry', StringParam, default='c1',
                      label="Symmetry",
                      help='Symmetry group. By default = c1.'
                      'See [[http://xmipp.cnb.csic.es/twiki/bin/view/Xmipp/Symmetry][Symmetry]]'
                      'for a description of the symmetry groups format, If no symmetry is present, give c1.')

        line = group.addLine('Resolution Range (A)',
                            help="If the user knows the range of resolutions or only a"
                                 " range of frequency needs to be analysed")
        
        group.addParam('significance', FloatParam, default=0.95, expertLevel=LEVEL_ADVANCED,
                      label="Significance",
                      help='Relution is computed using hipothesis tests, this value determines'
                      'the significance of that test')
        
        group.addParam('isPremasked', BooleanParam, default=False,
                      label="Is the original premasked?",
                      help='Sometimes the original volume is masked inside a spherical mask. In this case'
                      'please select yes')
        
        form.addParam('noiseonlyinhalves', BooleanParam, expertLevel=LEVEL_ADVANCED,
                      default=True,
                      label="Use noise outside the mask?", 
                      condition = 'halfVolumes',
                      help='Select yes if the volume present noise outside the mask.'
                      ' Otherwise, select No.')
        
        group.addParam('volumeRadius', FloatParam, default=-1,
                      label="Spherical mask radius (px)",
                      condition = 'isPremasked and not halfVolumes', 
                      help='When the original volume is originally premasked, the noise estimation ought'
                      'to be performed inside that premask, and out of the provieded mask asked in the previus'
                      'box. The radius value, determines the radius of the spherical premask. By default'
                      'radius = -1 use the half of the volume size as radius')
        
        group.addParam('volumeRadiusHalf', FloatParam, default=-1,
                      label="Spherical mask radius (px)",
                      condition = 'halfVolumes and isPremasked',
                      help='When the origianl volume is originally premasked,'
                      'the noise estimation ought to be performed inside that'
                      'premask, and out of the provieded mask asked in the previus'
                      'box. The radius value, determines the radius in pixels of '
                      'the spherical premask. By default radius = -1 use the half'
                      'of the volume size as radius')

        line.addParam('minRes', FloatParam, default=1, label='High')
        line.addParam('maxRes', FloatParam, default=30, label='Low')
        line.addParam('stepSize', FloatParam, allowsNull=True,
                      expertLevel=LEVEL_ADVANCED, label='Step')

        group.addParam('filterInput', BooleanParam, default=False, 
                      label="Filter input volume with local resolution?",
                      help='The input map is locally filtered at the local resolution map.')

    # --------------------------- INSERT steps functions --------------------------------------------

    def _insertAllSteps(self):
        
        self.micsFn = self._getPath()

        if self.halfVolumes:
            self.vol1Fn = self.inputVolume.get().getFileName()
            self.vol2Fn = self.inputVolume2.get().getFileName()
            self.maskFn = self.Mask.get().getFileName()

            self.inputVolumes.set(None)

        else:
            self.vol0Fn = self.inputVolumes.get().getFileName()
            self.maskFn = self.Mask.get().getFileName()
            self.inputVolume.set(None)
            self.inputVolume2.set(None)

            # Convert input into xmipp Metadata format
        convertId = self._insertFunctionStep('convertInputStep', )

        MS = self._insertFunctionStep('resolutionMonogenicSignalStep',
                                      prerequisites=[convertId])

        self._insertFunctionStep('createOutputStep', prerequisites=[MS])

        self._insertFunctionStep("createHistrogram")

    def convertInputStep(self):
        """ Read the input volume.
        """
        if (self.halfVolumes.get() is False):
            extVol0 = getExt(self.vol0Fn)
            if (extVol0 == '.mrc') or (extVol0 == '.map'):
                self.vol0Fn = self.vol0Fn + ':mrc'

        if self.halfVolumes.get() is True:
            extVol1 = getExt(self.vol1Fn)
            extVol2 = getExt(self.vol2Fn)
            if (extVol1 == '.mrc') or (extVol1 == '.map'):
                self.vol1Fn = self.vol1Fn + ':mrc'
            if (extVol2 == '.mrc') or (extVol2 == '.map'):
                self.vol2Fn = self.vol2Fn + ':mrc'

        extMask = getExt(self.maskFn)
        if (extMask == '.mrc') or (extMask == '.map'):
            self.maskFn = self.maskFn + ':mrc'

    def resolutionMonogenicSignalStep(self):

        # Number of frequencies
        if self.stepSize.hasValue():
            Nfreqs = round((self.maxRes.get() - self.minRes.get())/self.stepSize.get())
        else:
            Nfreqs = 50
  
        if self.halfVolumes:
            if self.isPremasked:
                if self.volumeRadiusHalf == -1:
                    xdim, _ydim, _zdim = self.inputVolume.get().getDim()
                    xdim = xdim*0.5
                else:
                    xdim = self.volumeRadiusHalf.get()
            else:
                xdim, _ydim, _zdim = self.inputVolume.get().getDim()
                xdim = xdim*0.5
        else:
            if self.isPremasked:
                if self.volumeRadius == -1:
                    xdim, _ydim, _zdim = self.inputVolumes.get().getDim()
                    xdim = xdim*0.5
                else:
                    xdim = self.volumeRadius.get()
            else:
                xdim, _ydim, _zdim = self.inputVolumes.get().getDim()
                xdim = xdim*0.5
                
        if self.halfVolumes.get() is False:
            params = ' --vol %s' % self.vol0Fn
            params += ' --mask %s' % self.maskFn
        else:
            params = ' --vol %s' % self.vol1Fn
            params += ' --vol2 %s' % self.vol2Fn
            params += ' --meanVol %s' % self._getExtraPath(FN_MEAN_VOL)
            params += ' --mask %s' % self.maskFn
        params += ' --mask_out %s' % self._getExtraPath(OUTPUT_MASK_FILE)
        params += ' -o %s' % self._getExtraPath(OUTPUT_RESOLUTION_FILE)
        if (self.halfVolumes):
            params += ' --sampling_rate %f' % self.inputVolume.get().getSamplingRate()
            if (self.noiseonlyinhalves is False):
                params += ' --noiseonlyinhalves'
        else:
            params += ' --sampling_rate %f' % self.inputVolumes.get().getSamplingRate()
        params += ' --number_frequencies %f' % Nfreqs
        params += ' --minRes %f' % self.minRes.get()
        params += ' --maxRes %f' % self.maxRes.get()
        params += ' --volumeRadius %f' % xdim
        params += ' --chimera_volume %s' % self._getExtraPath(OUTPUT_RESOLUTION_FILE_CHIMERA)
        params += ' --sym %s' % self.symmetry.get()
        params += ' --significance %f' % self.significance.get()
        params += ' --md_outputdata %s' % self._getExtraPath('mask_data.xmd')  
        if self.filterInput.get():
            params += ' --filtered_volume %s' % self._getExtraPath(FN_FILTERED_MAP)
        else:
            params += ' --filtered_volume %s' % ''

        self.runJob('xmipp_resolution_monogenic_signal', params)


    def createHistrogram(self):

        params = ' -i %s' % self._getExtraPath(OUTPUT_RESOLUTION_FILE)
        params += ' --mask binary_file %s' % self._getExtraPath(OUTPUT_MASK_FILE)
        params += ' --steps %f' % 30
        params += ' --range %f %f' % (self.min_res_init, self.max_res_init)#(self.minRes.get(), self.maxRes.get())
        params += ' -o %s' % self._getExtraPath('hist.xmd')

        self.runJob('xmipp_image_histogram', params)
        
        
    def readMetaDataOutput(self):
        mData = md.MetaData(self._getExtraPath(METADATA_MASK_FILE))
        NvoxelsOriginalMask = float(mData.getValue(md.MDL_COUNT, mData.firstObject()))
        NvoxelsOutputMask = float(mData.getValue(md.MDL_COUNT2, mData.firstObject()))
        nvox = int(round(((NvoxelsOriginalMask-NvoxelsOutputMask)/NvoxelsOriginalMask)*100))
        return nvox

    def getMinMax(self, imageFile):
        img = ImageHandler().read(imageFile)
        imgData = img.getData()
        min_res = round(np.amin(imgData) * 100) / 100
        max_res = round(np.amax(imgData) * 100) / 100
        return min_res, max_res

    def createOutputStep(self):
        volume_path = self._getExtraPath(OUTPUT_RESOLUTION_FILE)
        self.volumesSet = self._createSetOfVolumes('resolutionVol')
        if (self.halfVolumes):
            self.volumesSet.setSamplingRate(self.inputVolume.get().getSamplingRate())
        else:
            self.volumesSet.setSamplingRate(self.inputVolumes.get().getSamplingRate())
        readSetOfVolumes(volume_path, self.volumesSet)
        self._defineOutputs(outputVolume=self.volumesSet)
        if (self.halfVolumes):
            self._defineSourceRelation(self.inputVolume, self.volumesSet)
        else:
            self._defineSourceRelation(self.inputVolumes, self.volumesSet)
            
        #Setting the min max for the summary
        imageFile = self._getExtraPath(OUTPUT_RESOLUTION_FILE_CHIMERA)
        min_, max_ = self.getMinMax(imageFile)
        self.min_res_init.set(round(min_*100)/100)
        self.max_res_init.set(round(max_*100)/100)
        self._store(self.min_res_init)
        self._store(self.max_res_init)

        if self.filterInput.get():
            print 'Saving filtered map'
            volume_filtered_path = self._getExtraPath(FN_FILTERED_MAP)
            self.volumesSet2 = self._createSetOfVolumes('filteredVol')
            if (self.halfVolumes):
                self.volumesSet2.setSamplingRate(self.inputVolume.get().getSamplingRate())
            else:
                self.volumesSet2.setSamplingRate(self.inputVolumes.get().getSamplingRate())
            readSetOfVolumes(volume_filtered_path, self.volumesSet2)
            self._defineOutputs(outputVolume_Filtered=self.volumesSet2)
            if (self.halfVolumes):
                self._defineSourceRelation(self.inputVolume, self.volumesSet2)
            else:
                self._defineSourceRelation(self.inputVolumes, self.volumesSet2)

    # --------------------------- INFO functions ------------------------------

    def _methods(self):
        messages = []
        if hasattr(self, 'outputVolume'):
            messages.append(
                'Information about the method/article in ' + MONORES_METHOD_URL)
        return messages
    
    def _summary(self):
        summary = []
        summary.append("Highest resolution %.2f Å,   "
                       "Lowest resolution %.2f Å. \n" % (self.min_res_init,
                                                         self.max_res_init))
        Nvox = self.readMetaDataOutput()

        if (Nvox>10):
            summary.append("The resolution of %i %% of the mask voxels could not be computed. Maybe the mask was"
            "not correctly created, it is too wide or the resolution range does not cover the resolution at those voxels. "
            "If it is not the problem, decrease the significance in the advaced parameters can be an alternative" % Nvox)

        return summary

    def _citations(self):
        return ['Vilas2017']
Пример #7
0
 def __init__(self, **args):
     EMObject.__init__(self, **args)
     self._angleY = Float()
     self._angleY2 = Float()
     self._angleTilt = Float()
class XmippProtMonoRes(ProtAnalysis3D):
    """    
    Given a map the protocol assigns local resolutions to each voxel of the map.
    """
    _label = 'local MonoRes'
    _lastUpdateVersion = VERSION_1_1
    
    def __init__(self, **args):
        ProtAnalysis3D.__init__(self, **args)
        self.min_res_init = Float() 
        self.max_res_init = Float()
       
    
    # --------------------------- DEFINE param functions ----------------------
    def _defineParams(self, form):
        form.addSection(label='Input')

        form.addParam('halfVolumes', BooleanParam, default=False,
                      label="Would you like to use half volumes?",
                      help='The noise estimation for determining the '
                      'local resolution is performed via half volumes.')

        form.addParam('inputVolumes', PointerParam, pointerClass='Volume',
                      label="Input Volume", important=True,
                      condition = 'not halfVolumes',
                      help='Select a volume for determining its '
                      'local resolution.')

        form.addParam('inputVolume', PointerParam, pointerClass='Volume',
                      label="Volume Half 1", important=True,
                      condition = 'halfVolumes', 
                      help='Select a volume for determining its '
                      'local resolution.')

        form.addParam('inputVolume2', PointerParam, pointerClass='Volume',
                      label="Volume Half 2", important=True,
                      condition='halfVolumes',
                      help='Select a second volume for determining a '
                      'local resolution.')

        form.addParam('Mask', PointerParam, pointerClass='VolumeMask', 
                      condition='(halfVolumes) or (not halfVolumes)',
                      allowsNull=True,
                      label="Binary Mask", 
                      help='The mask determines which points are specimen'
                      ' and which are not')

        group = form.addGroup('Extra parameters')
#         group.addParam('symmetry', StringParam, default='c1',
#                       label="Symmetry",
#                       help='Symmetry group. By default = c1.'
#                       'See [[http://xmipp.cnb.csic.es/twiki/bin/view/Xmipp/Symmetry][Symmetry]]'
#                       'for a description of the symmetry groups format,' 
#                       'If no symmetry is present, give c1.')

        line = group.addLine('Resolution Range (Å)',
                            help='If the user knows the range of resolutions or'
                                'only a range of frequencies needs to be analysed.' 
                                'If Low is empty MonoRes will try to estimate the range. '
                                'it should be better if a range is provided')
        
        group.addParam('significance', FloatParam, default=0.95, 
                       expertLevel=LEVEL_ADVANCED,
                      label="Significance",
                      help='Relution is computed using hipothesis tests, '
                      'this value determines the significance of that test')
        
        group.addParam('maskthreshold', FloatParam, default=0.5, 
                       expertLevel=LEVEL_ADVANCED,
                      label="Mask threshold",
                      help='If the provided mask is not binary. Then, MonoRes'
                      'will try to binarize it. Bmask values below the threshold'
                      'will be change to 0 and above the thresthol will be 1')
        
        group.addParam('isPremasked', BooleanParam, default=False,
                      label="Is the original premasked?",
                      help='Sometimes the original volume is masked inside '
                      'a spherical mask. In this case please select yes')
        
        form.addParam('noiseonlyinhalves', BooleanParam, expertLevel=LEVEL_ADVANCED,
                      default=True,
                      label="Use noise outside the mask?", 
                      condition = 'halfVolumes',
                      help='Select yes if the volume present noise outside the mask.'
                      ' Otherwise, select No.')
        
        group.addParam('volumeRadius', FloatParam, default=-1,
                      label="Spherical mask radius (px)",
                      condition = 'isPremasked and not halfVolumes', 
                      help='When the original volume is originally premasked,'
                      'the noise estimation ought to be performed inside'
                      'that premask, and out of the provieded mask asked in'
                      'the previus box. The radius value, determines the'
                      'radius of the spherical premask. '
                      'By default radius = -1 use the half of the '
                      'volume size as radius')
        
        group.addParam('volumeRadiusHalf', FloatParam, default=-1,
                      label="Spherical mask radius (px)",
                      condition = 'halfVolumes and isPremasked',
                      help='When the origianl volume is originally premasked,'
                      'the noise estimation ought to be performed inside that'
                      'premask, and out of the provieded mask asked in the previus'
                      'box. The radius value, determines the radius in pixels of '
                      'the spherical premask. By default radius = -1 use the half'
                      'of the volume size as radius')

        line.addParam('minRes', FloatParam, default=0, label='High')
        line.addParam('maxRes', FloatParam, default=12, allowsNull=True, label='Low')
        line.addParam('stepSize', FloatParam, allowsNull=True,
                      expertLevel=LEVEL_ADVANCED, label='Step')

        group.addParam('filterInput', BooleanParam, default=False, 
                      label="Filter input volume with local resolution?",
                      help='The input map is locally filtered at'
                      'the local resolution map.')
        
        form.addParallelSection(threads = 4, mpi = 0)

    # --------------------------- INSERT steps functions --------------------------------------------

    def _createFilenameTemplates(self):
        """ Centralize how files are called """
        myDict = {
                 FN_MEAN_VOL: self._getExtraPath('mean_volume.vol'),
                 OUTPUT_MASK_FILE: self._getExtraPath("output_Mask.vol"),
                 OUTPUT_RESOLUTION_FILE_CHIMERA: self._getExtraPath(CHIMERA_RESOLUTION_VOL),
                 FN_FILTERED_MAP: self._getExtraPath('filteredMap.vol'),
                 OUTPUT_RESOLUTION_FILE: self._getExtraPath('mgresolution.vol'),
                 METADATA_MASK_FILE: self._getExtraPath('mask_data.xmd'),
                 FN_METADATA_HISTOGRAM: self._getExtraPath('hist.xmd'),
                 BINARY_MASK: self._getExtraPath('binarized_mask.vol'),
                 FN_GAUSSIAN_MAP: self._getExtraPath('gaussianfilted.vol')
                 }
        self._updateFilenamesDict(myDict)

    def _insertAllSteps(self):
            # Convert input into xmipp Metadata format
        self._createFilenameTemplates() 
        self._insertFunctionStep('convertInputStep', )
        self._insertFunctionStep('resolutionMonogenicSignalStep')
        self._insertFunctionStep('createOutputStep')
        self._insertFunctionStep("createHistrogram")

    def convertInputStep(self):
        """ Read the input volume.
        """
        
        self.micsFn = self._getPath()

        if self.halfVolumes:
            self.vol1Fn = self.inputVolume.get().getFileName()
            self.vol2Fn = self.inputVolume2.get().getFileName()
            extVol1 = getExt(self.vol1Fn)
            extVol2 = getExt(self.vol2Fn)
            if (extVol1 == '.mrc') or (extVol1 == '.map'):
                self.vol1Fn = self.vol1Fn + ':mrc'
            if (extVol2 == '.mrc') or (extVol2 == '.map'):
                self.vol2Fn = self.vol2Fn + ':mrc'
                
            if not self.Mask.hasValue():
                self.ifNomask(self.vol1Fn)
            else:
                self.maskFn = self.Mask.get().getFileName()

            self.inputVolumes.set(None)
        else:
            self.vol0Fn = self.inputVolumes.get().getFileName()
            extVol0 = getExt(self.vol0Fn)
            if (extVol0 == '.mrc') or (extVol0 == '.map'):
                self.vol0Fn = self.vol0Fn + ':mrc'
                
            if not self.Mask.hasValue():
                self.ifNomask(self.vol0Fn)
            else:
                self.maskFn = self.Mask.get().getFileName()
            
            print self.maskFn
            
            self.inputVolume.set(None)
            self.inputVolume2.set(None)


        extMask = getExt(self.maskFn)
        if (extMask == '.mrc') or (extMask == '.map'):
            self.maskFn = self.maskFn + ':mrc'
            
        if self.Mask.hasValue():
            params = ' -i %s' % self.maskFn
            params += ' -o %s' % self._getFileName(BINARY_MASK)
            params += ' --select below %f' % self.maskthreshold.get()
            params += ' --substitute binarize'
             
            self.runJob('xmipp_transform_threshold', params)

    def ifNomask(self, fnVol):
        if self.halfVolumes:
            xdim, _ydim, _zdim = self.inputVolume.get().getDim()
            params = ' -i %s' % fnVol
        else:
            xdim, _ydim, _zdim = self.inputVolumes.get().getDim()
            params = ' -i %s' % fnVol
        params += ' -o %s' % self._getFileName(FN_GAUSSIAN_MAP)
        setsize = 0.02*xdim
        params += ' --fourier real_gaussian %f' % (setsize)
     
        self.runJob('xmipp_transform_filter', params)
        img = ImageHandler().read(self._getFileName(FN_GAUSSIAN_MAP))
        imgData = img.getData()
        max_val = np.amax(imgData)*0.05
         
        params = ' -i %s' % self._getFileName(FN_GAUSSIAN_MAP)
        params += ' --select below %f' % max_val
        params += ' --substitute binarize'
        params += ' -o %s' % self._getFileName(BINARY_MASK)
     
        self.runJob('xmipp_transform_threshold', params)
        
        self.maskFn = self._getFileName(BINARY_MASK)

    def maskRadius(self, halfmaps, premaskedmap):
        if halfmaps:
            if premaskedmap:
                if self.volumeRadiusHalf == -1:
                    xdim, _ydim, _zdim = self.inputVolume.get().getDim()
                    xdim = xdim*0.5
                else:
                    xdim = self.volumeRadiusHalf.get()
            else:
                xdim, _ydim, _zdim = self.inputVolume.get().getDim()
                xdim = xdim*0.5
        else:
            if premaskedmap:
                if self.volumeRadius == -1:
                    xdim, _ydim, _zdim = self.inputVolumes.get().getDim()
                    xdim = xdim*0.5
                else:
                    xdim = self.volumeRadius.get()
            else:
                xdim, _ydim, _zdim = self.inputVolumes.get().getDim()
                xdim = xdim*0.5
        return xdim
    
    def resolutionMonogenicAuto(self):
        freq_step = 1

        xdim = self.maskRadius(self.halfVolumes, self.isPremasked)


        if self.halfVolumes:
            params = ' --vol %s' % self.vol1Fn
            params += ' --vol2 %s' % self.vol2Fn
            params += ' --meanVol %s' % self._getFileName(FN_MEAN_VOL)
            params += ' --mask %s' % self._getFileName(BINARY_MASK)
            params += ' --sampling_rate %f' % self.inputVolume.get().getSamplingRate()
            if (self.noiseonlyinhalves is False):
                params += ' --noiseonlyinhalves'
        else:
            params = ' --vol %s' % self.vol0Fn
            params += ' --mask %s' % self._getFileName(BINARY_MASK)
            params += ' --sampling_rate %f' % self.inputVolumes.get().getSamplingRate()

        params += ' --automatic '
        params += ' --step %f' % freq_step
        params += ' --mask_out %s' % self._getFileName(OUTPUT_MASK_FILE)
        params += ' -o %s' % self._getFileName(OUTPUT_RESOLUTION_FILE)
        params += ' --volumeRadius %f' % xdim
        params += ' --chimera_volume %s' % self._getFileName(
                                                    OUTPUT_RESOLUTION_FILE_CHIMERA)
        params += ' --sym %s' % 'c1'#self.symmetry.get()
        params += ' --significance %f' % self.significance.get()
        params += ' --md_outputdata %s' % self._getFileName(METADATA_MASK_FILE)  
        params += ' --filtered_volume %s' % ''
        params += ' --threads %i' % self.numberOfThreads.get()

        self.runJob('xmipp_resolution_monogenic_signal', params)

    def resolutionMonogenicSignalStep(self):
        # Number of frequencies
        if (not self.maxRes.hasValue()):
            self.resolutionMonogenicAuto()
            imageFile = self._getFileName(OUTPUT_RESOLUTION_FILE)
            min_, max_ = self.getMinMax(imageFile)
        else:    
            max_ = self.maxRes.get()

        if self.stepSize.hasValue():
            freq_step = self.stepSize.get()
        else:
            freq_step = 0.25
  
        xdim = self.maskRadius(self.halfVolumes, self.isPremasked)

        if self.halfVolumes:
            params = ' --vol %s' % self.vol1Fn
            params += ' --vol2 %s' % self.vol2Fn
            params += ' --meanVol %s' % self._getFileName(FN_MEAN_VOL)
            params += ' --mask %s' % self._getFileName(BINARY_MASK)
            params += ' --sampling_rate %f' % self.inputVolume.get().getSamplingRate()
            if (self.noiseonlyinhalves is False):
                params += ' --noiseonlyinhalves'
        else:
            params = ' --vol %s' % self.vol0Fn
            params += ' --mask %s' % self._getFileName(BINARY_MASK)
            params += ' --sampling_rate %f' % self.inputVolumes.get().getSamplingRate()

        params += ' --minRes %f' % self.minRes.get()
        params += ' --maxRes %f' % max_
            
        params += ' --step %f' % freq_step
        params += ' --mask_out %s' % self._getFileName(OUTPUT_MASK_FILE)
        params += ' -o %s' % self._getFileName(OUTPUT_RESOLUTION_FILE)
        params += ' --volumeRadius %f' % xdim
        params += ' --exact'
        params += ' --chimera_volume %s' % self._getFileName(
                                                    OUTPUT_RESOLUTION_FILE_CHIMERA)
        params += ' --sym %s' % 'c1'#self.symmetry.get()
        params += ' --significance %f' % self.significance.get()
        params += ' --md_outputdata %s' % self._getFileName(METADATA_MASK_FILE)
        params += ' --threads %i' % self.numberOfThreads.get()
        if self.filterInput.get():
            params += ' --filtered_volume %s' % self._getFileName(FN_FILTERED_MAP)
        else:
            params += ' --filtered_volume %s' % ''

        self.runJob('xmipp_resolution_monogenic_signal', params)



    def createHistrogram(self):

        M = float(self.max_res_init)
        m = float(self.min_res_init)
        range_res = round((M - m)*4.0)

        params = ' -i %s' % self._getFileName(OUTPUT_RESOLUTION_FILE)
        params += ' --mask binary_file %s' % self._getFileName(OUTPUT_MASK_FILE)
        params += ' --steps %f' % (range_res)
        params += ' --range %f %f' % (self.min_res_init, self.max_res_init)
        params += ' -o %s' % self._getFileName(FN_METADATA_HISTOGRAM)

        self.runJob('xmipp_image_histogram', params)
        
        
    def readMetaDataOutput(self):
        mData = md.MetaData(self._getFileName(METADATA_MASK_FILE))
        NvoxelsOriginalMask = float(mData.getValue(md.MDL_COUNT, mData.firstObject()))
        NvoxelsOutputMask = float(mData.getValue(md.MDL_COUNT2, mData.firstObject()))
        nvox = int(round(
                ((NvoxelsOriginalMask-NvoxelsOutputMask)/NvoxelsOriginalMask)*100))
        return nvox

    def getMinMax(self, imageFile):
        img = ImageHandler().read(imageFile)
        imgData = img.getData()
        min_res = round(np.amin(imgData) * 100) / 100
        max_res = round(np.amax(imgData) * 100) / 100
        return min_res, max_res

    def createOutputStep(self):
        volume=Volume()
        volume.setFileName(self._getFileName(OUTPUT_RESOLUTION_FILE))
        if (self.halfVolumes):
            volume.setSamplingRate(self.inputVolume.get().getSamplingRate())
            self._defineOutputs(resolution_Volume=volume)
            self._defineSourceRelation(self.inputVolume, volume)
        else:
            volume.setSamplingRate(self.inputVolumes.get().getSamplingRate())
            self._defineOutputs(resolution_Volume=volume)
            self._defineSourceRelation(self.inputVolumes, volume)
            
            
        #Setting the min max for the summary
        imageFile = self._getFileName(OUTPUT_RESOLUTION_FILE_CHIMERA)
        min_, max_ = self.getMinMax(imageFile)
        self.min_res_init.set(round(min_*100)/100)
        self.max_res_init.set(round(max_*100)/100)
        self._store(self.min_res_init)
        self._store(self.max_res_init)

        if self.filterInput.get():
            print 'Saving filtered map'
            volume.setFileName(self._getFileName(FN_FILTERED_MAP))
            if (self.halfVolumes):
                volume.setSamplingRate(self.inputVolume.get().getSamplingRate())
                self._defineOutputs(outputVolume_Filtered=volume)
                self._defineSourceRelation(self.inputVolume, volume)
            else:
                volume.setSamplingRate(self.inputVolumes.get().getSamplingRate())
                self._defineOutputs(outputVolume_Filtered=volume)
                self._defineSourceRelation(self.inputVolumes, volume)
            

                

    # --------------------------- INFO functions ------------------------------

    def _methods(self):
        messages = []
        if hasattr(self, 'resolution_Volume'):
            messages.append(
                'Information about the method/article in ' + MONORES_METHOD_URL)
        return messages
    
    def _summary(self):
        summary = []
        summary.append("Highest resolution %.2f Å,   "
                       "Lowest resolution %.2f Å. \n" % (self.min_res_init,
                                                         self.max_res_init))
        return summary

    def _citations(self):
        return ['Vilas2018']
Пример #9
0
    def createAnalyzeFilesStep(self):
        """ This method will create two sqlite files that 
        will be used in by the viewer in the 'Analyze result' action.
        ctfSet: a table with average ctf values between all methods.
        ctfSetPair: a table where each row is a pair between two methods
        """
        ctfSetFn, ctfSetPairFn = self._getAnalyzeFiles()

        cleanPath(ctfSetFn, ctfSetPairFn)

        ctfSet = Set(filename=ctfSetFn)
        ctfSetPair = em.SetOfCTF(filename=ctfSetPairFn)
        #import pdb
        #pdb.set_trace()
        minimumResolution = {}
        maximumResolution = {}
        averageResolution = {}
        averageDefocusU = {}
        averageDefocusV = {}
        averageDefocusAngle = {}

        for ctf in self.setOfCTF:
            micFileName = self._getMicName(ctf)
            minimumResolution[micFileName] = 0.
            maximumResolution[micFileName] = 0.
            averageResolution[micFileName] = 0.
            averageDefocusU[micFileName] = 0.
            averageDefocusV[micFileName] = 0.
            averageDefocusAngle[micFileName] = 0.

        for method1, method2, ctfId in self._freqResol:
            ctf = em.CTFModel()
            ctf1 = self.inputCTFs[method1].get()[ctfId]
            ctf2 = self.inputCTFs[method2].get()[ctfId]
            ctf.setDefocusU((ctf1.getDefocusU() + ctf2.getDefocusU()) / 2.)
            ctf.setDefocusV((ctf1.getDefocusV() + ctf2.getDefocusV()) / 2.)
            ctf.setDefocusAngle(
                (ctf1.getDefocusAngle() + ctf2.getDefocusAngle()) / 2.)
            ctf.setMicrograph(ctf1.getMicrograph())

            #Clean objId since we can have ctf from the same micrograph
            # and by default it is set to micrograph id
            ctf.cleanObjId()
            resolution = self._freqResol[(method1, method2, ctfId)]
            ctf.resolution = Float(resolution)
            ctf.method1 = String(self.methodNames[method1])
            ctf.method2 = String(self.methodNames[method2])
            # save the values of defocus for each micrograph in a list
            ctfSetPair.append(ctf)

            micFileName = self._getMicName(ctf1)

            if (not micFileName in minimumResolution
                    or not micFileName in maximumResolution):
                pass

            if resolution < minimumResolution[micFileName]:
                minimumResolution[micFileName] = resolution

            if resolution > maximumResolution[micFileName]:
                maximumResolution[micFileName] = resolution

            averageResolution[micFileName] += resolution
            averageDefocusU[micFileName] += ctf.getDefocusU()
            averageDefocusV[micFileName] += ctf.getDefocusV()
            averageDefocusAngle[micFileName] += ctf.getDefocusAngle()

        size = float(len(self.setOfCTF))

        for ctf in self.setOfCTF:
            ctfAvg = Object()
            micFileName = self._getMicName(ctf)
            ctfAvg._micObj = ctf.getMicrograph()
            ctfAvg.averageDefocusU = Float(averageDefocusU[micFileName] / size)
            ctfAvg.averageDefocusV = Float(averageDefocusV[micFileName] / size)
            ctfAvg.averageDefocusAngle = Float(
                averageDefocusAngle[micFileName] / size)
            ctfAvg.averageResolution = Float(averageResolution[micFileName] /
                                             size)
            ctfSet.append(ctfAvg)

        ctfSetPair.write()
        ctfSet.write()
Пример #10
0
 def __init__(self, imag=0., real=0., **args):
     Object.__init__(self, **args)
     self.imag = Float(imag)
     self.real = Float(real)
class XmippProtDeepRes(ProtAnalysis3D):
    """    
    Given a map the protocol assigns local resolutions to each voxel of the map.
    """
    _label = 'local deepRes'
    _lastUpdateVersion = VERSION_2_0

    #RESOLUTION RANGE
    LOW_RESOL = 0
    HIGH_RESOL = 1

    def __init__(self, **args):
        ProtAnalysis3D.__init__(self, **args)
        self.min_res_init = Float()
        self.max_res_init = Float()
        self.median_res_init = Float()

    # --------------------------- DEFINE param functions ----------------------
    def _defineParams(self, form):
        form.addSection(label='Input')

        form.addHidden(GPU_LIST,
                       StringParam,
                       default='0',
                       label="Choose GPU ID",
                       help="GPU may have several cores. Set it to zero"
                       " if you do not know what we are talking about."
                       " First core index is 0, second 1 and so on.")

        form.addParam('inputVolume',
                      PointerParam,
                      pointerClass='Volume',
                      label="Input Volume",
                      help='Select a volume for determining its '
                      'local resolution.')

        form.addParam('Mask',
                      PointerParam,
                      pointerClass='VolumeMask',
                      allowsNull=True,
                      label="Mask",
                      help='The mask determines which points are specimen'
                      ' and which are not')

        form.addParam('range',
                      EnumParam,
                      choices=[u'2.5Å - 13.0Å', u'1.5Å - 6.0Å'],
                      label="Expected resolutions range",
                      default=self.LOW_RESOL,
                      display=EnumParam.DISPLAY_HLIST,
                      help='The program uses a trained network to determine'
                      ' resolutions between 2.5Å-13.0Å  or'
                      ' resolutions between 1.5Å-6.0Å')

    # --------------------------- INSERT steps functions --------------------------------------------

    def _createFilenameTemplates(self):
        """ Centralize how files are called """
        myDict = {
            MASK_DILATE:
            self._getTmpPath('Mask_dilate.vol'),
            OPERATE_VOL:
            self._getTmpPath('operateVolume.vol'),
            RESIZE_MASK:
            self._getExtraPath('binaryMask.vol'),
            RESIZE_VOL:
            self._getExtraPath('originalVolume.vol'),
            OUTPUT_RESOLUTION_FILE_CHIMERA:
            self._getExtraPath('chimera_resolution.vol'),
            #                 OUTPUT_RESOLUTION_FILE_CHIMERA: self._getExtraPath(CHIMERA_RESOLUTION_VOL),
            OUTPUT_RESOLUTION_FILE:
            self._getExtraPath('deepRes_resolution.vol'),
            FN_METADATA_HISTOGRAM:
            self._getExtraPath('hist.xmd')
        }
        self._updateFilenamesDict(myDict)

    def _insertAllSteps(self):
        # Convert input into xmipp Metadata format

        updateEnviron(self.gpuList.get())

        self._createFilenameTemplates()
        self._insertFunctionStep('convertInputStep')
        self._insertFunctionStep('transformStep')
        self._insertFunctionStep('resizeStep')
        self._insertFunctionStep('resolutionStep')
        self._insertFunctionStep('createOutputStep')
        self._insertFunctionStep("createHistrogram")

    def convertInputStep(self):
        """ Read the input volume.
        """
        self.micsFn = self._getPath()

        self.volFn = self.inputVolume.get().getFileName()
        self.maskFn = self.Mask.get().getFileName()

        extVol = getExt(self.volFn)
        if (extVol == '.mrc') or (extVol == '.map'):
            self.volFn = self.volFn + ':mrc'

        extMask = getExt(self.maskFn)
        if (extMask == '.mrc') or (extMask == '.map'):
            self.maskFn = self.maskFn + ':mrc'

    def transformStep(self):
        params = ' -i %s' % self.maskFn
        params += ' -o %s' % self._getFileName(MASK_DILATE)
        params += '  --binaryOperation dilation --size 1 '

        self.runJob('xmipp_transform_morphology', params)

        params2 = ' -i %s' % self.volFn
        params2 += ' --mult %s' % self._getFileName(MASK_DILATE)
        params2 += ' -o %s' % self._getFileName(OPERATE_VOL)

        self.runJob('xmipp_image_operate', params2)

    def resizeStep(self):

        if self.range == self.LOW_RESOL:
            sampling_new = 1.0
        else:
            sampling_new = 0.5

        samplingFactor = float(
            self.inputVolume.get().getSamplingRate()) / sampling_new
        fourierValue = float(
            self.inputVolume.get().getSamplingRate()) / (2 * sampling_new)

        if self.inputVolume.get().getSamplingRate() > sampling_new:
            #mask with sampling=1.0
            paramsResizeMask = ' -i %s' % self.maskFn
            paramsResizeMask += ' -o %s' % self._getFileName(RESIZE_MASK)
            paramsResizeMask += ' --factor %s' % samplingFactor
            self.runJob('xmipp_image_resize', paramsResizeMask)
            #Original volume with sampling=1.0
            paramsResizeVol = ' -i %s' % self._getFileName(OPERATE_VOL)
            paramsResizeVol += ' -o %s' % self._getFileName(RESIZE_VOL)
            paramsResizeVol += ' --factor %s' % samplingFactor
            self.runJob('xmipp_image_resize', paramsResizeVol)
        else:
            #mask with sampling=1.0
            paramsFilterMask = ' -i %s' % self.maskFn
            paramsFilterMask += ' -o %s' % self._getFileName(RESIZE_MASK)
            paramsFilterMask += ' --fourier low_pass %s' % fourierValue
            paramsResizeMask = ' -i %s' % self._getFileName(RESIZE_MASK)
            paramsResizeMask += ' -o %s' % self._getFileName(RESIZE_MASK)
            paramsResizeMask += ' --factor %s' % samplingFactor
            self.runJob('xmipp_transform_filter', paramsFilterMask)
            self.runJob('xmipp_image_resize', paramsResizeMask)
            #Original volume with sampling=1.0
            paramsFilterVol = ' -i %s' % self._getFileName(OPERATE_VOL)
            paramsFilterVol += ' -o %s' % self._getFileName(RESIZE_VOL)
            paramsFilterVol += ' --fourier low_pass %s' % fourierValue
            paramsResizeVol = ' -i %s' % self._getFileName(RESIZE_VOL)
            paramsResizeVol += ' -o %s' % self._getFileName(RESIZE_VOL)
            paramsResizeVol += ' --factor %s' % samplingFactor
            self.runJob('xmipp_transform_filter', paramsFilterVol)
            self.runJob('xmipp_image_resize', paramsResizeVol)

        params = ' -i %s' % self._getFileName(RESIZE_MASK)
        params += ' -o %s' % self._getFileName(RESIZE_MASK)
        params += ' --select below %f' % 0.15
        params += ' --substitute binarize'

        self.runJob('xmipp_transform_threshold', params)

    def resolutionStep(self):

        if self.range == self.LOW_RESOL:
            #             sampling_new = 1.0
            MODEL_DEEP_1 = xmipp3.Plugin.getModel("deepRes", "model_w13.h5")
            params = ' -dl %s' % MODEL_DEEP_1
        else:
            #             sampling_new = 0.5
            MODEL_DEEP_2 = xmipp3.Plugin.getModel("deepRes", "model_w7.h5")
            params = ' -dl %s' % MODEL_DEEP_2
        params += ' -i  %s' % self._getFileName(RESIZE_VOL)
        params += ' -m  %s' % self._getFileName(RESIZE_MASK)
        params += ' -s  %f' % self.inputVolume.get().getSamplingRate()
        params += ' -o  %s' % self._getFileName(OUTPUT_RESOLUTION_FILE)

        self.runJob("xmipp_deepRes_resolution", params)

    def createHistrogram(self):

        M = float(self.max_res_init)
        m = float(self.min_res_init)
        #         M = 12.5
        #         m = 2.5
        range_res = round((M - m) * 4.0)

        params = ' -i %s' % self._getFileName(OUTPUT_RESOLUTION_FILE)
        params += ' --mask binary_file %s' % self._getFileName(RESIZE_MASK)
        params += ' --steps %f' % (range_res)
        params += ' --range %f %f' % (self.min_res_init, self.max_res_init)
        params += ' -o %s' % self._getFileName(FN_METADATA_HISTOGRAM)

        self.runJob('xmipp_image_histogram', params)

    def getMinMax(self, imageFile):
        img = ImageHandler().read(imageFile)
        imgData = img.getData()
        imgData = imgData[imgData != 0]
        min_res = round(np.amin(imgData) * 100) / 100
        max_res = round(np.amax(imgData) * 100) / 100
        median_res = round(np.median(imgData) * 100) / 100
        return min_res, max_res, median_res

    def createChimeraOutput(self, vol, value):
        Vx = xmipp3.Image(vol)
        V = Vx.getData()
        Zdim, Ydim, Xdim = V.shape
        #        Vout = V

        for z in range(0, Zdim):
            for y in range(0, Ydim):
                for x in range(0, Xdim):
                    if V[z, y, x] == 0:
                        V[z, y, x] = value
        Vx.setData(V)
        #        Vx.write(Vout)
        return Vx

    def createOutputStep(self):
        if self.range == self.LOW_RESOL:
            sampling_new = 1.0
        else:
            sampling_new = 0.5
        volume = Volume()
        volume.setFileName(self._getFileName(OUTPUT_RESOLUTION_FILE))

        volume.setSamplingRate(sampling_new)
        self._defineOutputs(resolution_Volume=volume)
        self._defineTransformRelation(self.inputVolume, volume)

        #Setting the min max and median for the summary
        imageFile = self._getFileName(OUTPUT_RESOLUTION_FILE)
        min_, max_, median_ = self.getMinMax(imageFile)
        self.min_res_init.set(round(min_ * 100) / 100)
        self.max_res_init.set(round(max_ * 100) / 100)
        self.median_res_init.set(round(median_ * 100) / 100)
        self._store(self.min_res_init)
        self._store(self.max_res_init)
        self._store(self.median_res_init)

        #create Resolution Map to visialize in Chimera
        #vol_chimera=Volume()
        vol_chimera = self.createChimeraOutput(
            self._getFileName(OUTPUT_RESOLUTION_FILE), self.median_res_init)
        #        self.createChimeraOutput(self._getFileName(OUTPUT_RESOLUTION_FILE),
        #                                 self.median_res_init,
        #                                 self._getFileName(OUTPUT_RESOLUTION_FILE_CHIMERA))
        vol_chimera.write(self._getFileName(OUTPUT_RESOLUTION_FILE_CHIMERA))
#        vol_chimera.setFileName(self._getFileName(OUTPUT_RESOLUTION_FILE_CHIMERA))
#        self.vol_chimera.setSamplingRate(sampling_new)
#         self._defineOutputs(resolution_Volume=vol_chimera)
#         self._defineTransformRelation(self.inputVolume, vol_chimera)

# --------------------------- INFO functions ------------------------------

    def _methods(self):
        messages = []
        if hasattr(self, 'resolution_Volume'):
            messages.append('Information about the method/article in ' +
                            DEEPRES_METHOD_URL)
        return messages

    def _summary(self):
        summary = []
        summary.append("Median resolution %.2f Å." % (self.median_res_init))
        summary.append("Highest resolution %.2f Å,   "
                       "Lowest resolution %.2f Å. \n" %
                       (self.min_res_init, self.max_res_init))
        return summary

    def _validate(self):
        """ Check if the installation of this protocol is correct.
        Can't rely on package function since this is a "multi package" package
        Returning an empty list means that the installation is correct
        and there are not errors. If some errors are found, a list with
        the error messages will be returned.
        """
        error = validateDLtoolkit(model="deepRes")
        return error

    def _citations(self):
        return ['Ramirez-Aportela-2019']
Пример #12
0
 def __init__(self, **args):
     EMObject.__init__(self, **args)
     self._angleY = Float()    
     self._angleY2 = Float()
     self._angleTilt = Float()
Пример #13
0
    def testMergeAlternateColumn(self):
        """Test that the union operation works as expected.
        Even if the order of the columns do not match.
        That is, M1(a,b,c) U M2(a,c,b)"""
        # Create two sets of particles
        inFileNameMetadata1 = self.proj.getTmpPath('particles1.sqlite')
        inFileNameMetadata2 = self.proj.getTmpPath('particles2.sqlite')
        imgSet1 = SetOfParticles(filename=inFileNameMetadata1)
        imgSet2 = SetOfParticles(filename=inFileNameMetadata2)

        inFileNameData = self.proj.getTmpPath('particles.stk')
        img1 = Particle()
        img2 = Particle()
        attrb1 = [11, 12, 13, 14]
        attrb2 = [21, 22, 23, 24]
        counter = 0

        for i in range(1, 3):
            img1.cleanObjId()
            img1.setLocation(i, inFileNameData)
            img1.setMicId(i % 3)
            img1.setClassId(i % 5)
            img1.setSamplingRate(1.)
            img1._attrb1 = Float(attrb1[counter])
            img1._attrb2 = Float(attrb2[counter])
            imgSet1.append(img1)
            counter += 1

        for i in range(1, 3):
            img2.cleanObjId()
            img2.setLocation(i, inFileNameData)
            img2.setClassId(i % 5)
            img2.setMicId(i % 3)
            img2.setSamplingRate(2.)
            img2._attrb1 = Float(attrb1[counter])
            img2._attrb2 = Float(attrb2[counter])
            imgSet2.append(img2)
            counter += 1

        imgSet1.write()
        imgSet2.write()

        # import them
        protImport1 = self.newProtocol(
            emprot.ProtImportParticles,
            objLabel='import set1',
            importFrom=emprot.ProtImportParticles.IMPORT_FROM_SCIPION,
            sqliteFile=inFileNameMetadata1,
            magnification=10000,
            samplingRate=7.08,
            haveDataBeenPhaseFlipped=True)
        self.launchProtocol(protImport1)

        protImport2 = self.newProtocol(
            emprot.ProtImportParticles,
            objLabel='import set2',
            importFrom=emprot.ProtImportParticles.IMPORT_FROM_SCIPION,
            sqliteFile=inFileNameMetadata2,
            magnification=10000,
            samplingRate=7.08,
            haveDataBeenPhaseFlipped=True)
        self.launchProtocol(protImport2)

        # create merge protocol
        p_union = self.newProtocol(emprot.ProtUnionSet,
                                   objLabel='join diff column order',
                                   ignoreExtraAttributes=True)
        p_union.inputSets.append(protImport1.outputParticles)
        p_union.inputSets.append(protImport2.outputParticles)
        self.proj.launchProtocol(p_union, wait=True)
        # assert
        counter = 0
        for img in p_union.outputSet:
            self.assertAlmostEqual(attrb1[counter], img._attrb1, 4)
            self.assertAlmostEqual(attrb2[counter], img._attrb2, 4)
            counter += 1
Пример #14
0
 def _updateItemCtfBeamTilt(self, particle, row):
     particle.setCTF(convert.rowToCtfModel(row))
     # check if beamtilt is available and save it
     if row.hasLabel('rlnBeamTiltX'):
         particle._rlnBeamTiltX = Float(row.getValue('rlnBeamTiltX', 0))
         particle._rlnBeamTiltY = Float(row.getValue('rlnBeamTiltY', 0))
Пример #15
0
class BsoftProtBlocres(ProtAnalysis3D):
    """ Wrapper around blocres program.
    """
    _label = 'blocres'
    _version = VERSION_1_1

    def __init__(self, **args):
        ProtAnalysis3D.__init__(self, **args)
        self.min_res_init = Float()
        self.max_res_init = Float()
        self.halfVolumes = True

    #--------------------------- DEFINE param functions -----------------------
    def _defineParams(self, form):
        form.addSection(label='Input')
        form.addParam('inputVolume',
                      params.PointerParam,
                      pointerClass='Volume',
                      label="Half 1",
                      help="""Select first half volume to compute the
                      local resolution.
                      """)
        form.addParam('inputVolume2',
                      params.PointerParam,
                      pointerClass='Volume',
                      label="Half 2",
                      help="""Select first half volume to compute the
                      local resolution.
                      """)
        form.addParam('mask',
                      params.PointerParam,
                      allowsNull=True,
                      pointerClass='Volume',
                      label='Mask',
                      help="""Mask file to use for limiting the analysis to a 
                      defined region and level value to use 
                      (optional, default: all but zero).""")

        form.addParam('method',
                      params.BooleanParam,
                      default=True,
                      label='Use Box',
                      help="""The local (box) and shell (shell) resolution 
                      calculations are mutually exclusive.""")

        form.addParam('box',
                      params.IntParam,
                      default=20,
                      condition='(method)',
                      label='Box',
                      help="""Kernel size for determining 
                      local resolution (pixels/voxels)""")
        form.addParam('shell',
                      params.IntParam,
                      default=20,
                      condition='(not method)',
                      label='Shell',
                      help="""Shell width for determining 
                      radial resolution (pixels/voxels).""")

        line = form.addLine('Resolution Criterion')
        line.addParam('resolutionCriterion',
                      params.EnumParam,
                      choices=['FSC', 'DPR', 'SSNR', 'RAB'],
                      default=0,
                      help="""Resolution criterion: 
                            FSC = Fourier Shell Correlation (default),
        	                DPR = Differential Phase Residual, 
        	                SSNR = Spectral Signal-to-Noise Ratio,
        	                RAB = R(A+B) figure of merit.""")

        line.addParam('cutoff',
                      params.FloatParam,
                      default=0.5,
                      label='Cutoff',
                      help="""Resolution cutoff for the criterion chosen
            	                        (default: FSC: 0.5, DPR: 45, 
            	                        SSNR: 1, RAB: 0.5).""")

        form.addSection(label='Parameters')
        form.addParam('step',
                      params.IntParam,
                      default=1,
                      label='Step',
                      help="""Interval between voxel samples or shells for 
                      resolution analysis (pixels, default: 1)""")
        form.addParam(
            'maxresolution',
            params.FloatParam,
            default=2,
            label='Maximum Resolution',
            help="""Maximum frequency available in the data (angstrom)""")
        form.addParam('fill',
                      params.IntParam,
                      allowsNull=True,
                      label='Fill',
                      help="""Value to fill the background 
                      (non-masked regions; default 0).
                          """)
        form.addParam('pad',
                      params.EnumParam,
                      choices=['None', 'Box', 'Shell'],
                      default=1,
                      label='Padding Factor',
                      help="""Resolution box padding factor
                       (0 = none, default: 1 (box) and 0 (shell)).
                          """)
        form.addParam('symmetry',
                      params.StringParam,
                      allowsNull=True,
                      default='',
                      label='Symmetry',
                      help="""Point group symmetry.""")
        form.addParam('smooth',
                      params.BooleanParam,
                      default=True,
                      label='Smooth',
                      help="""Smooth the shell edge.""")

    def _createFilenameTemplates(self):
        """ Centralize how files are called """
        myDict = {
            FN_HALF1: self._getTmpPath("half1.map"),
            FN_HALF2: self._getTmpPath("half2.map"),
            FN_MASKVOL: self._getTmpPath("mask.map"),
            FN_RESOLMAP: self._getExtraPath("resolutionMap.map")
        }
        self._updateFilenamesDict(myDict)

    #--------------------------- INSERT steps functions -----------------------
    def _insertAllSteps(self):
        # Insert processing steps
        self._createFilenameTemplates()
        self._insertFunctionStep('convertInputStep')
        self._insertFunctionStep('resolutionStep')
        self._insertFunctionStep('createOutputStep')

    #--------------------------- STEPS functions -------------------------------
    def convertInputStep(self):
        # blocres works with .map
        vol1Fn = self.inputVolume.get().getFileName()
        vol2Fn = self.inputVolume2.get().getFileName()
        if self.mask.get().getFileName() != '':
            maskFn = self.mask.get().getFileName()

        self.fnvol1 = self._getFileName("half1")
        self.fnvol2 = self._getFileName("half2")
        ImageHandler().convert(vol1Fn, self.fnvol1)
        ImageHandler().convert(vol2Fn, self.fnvol2)
        if self.mask.get().getFileName() != '':
            self.fnmask = self._getFileName("maskvol")
            ImageHandler().convert(maskFn, self.fnmask)
        else:
            self.fnmask = self.maks.get().getFileName()

    def resolutionStep(self):
        """ blocres parameters. """
        sampling = self.inputVolume.get().getSamplingRate()
        #Actions
        params = ' -v 1'  # No Verbose
        params += ' -criterion %s' % self.getEnumText("resolutionCriterion")
        if (self.method):
            params += ' -box %i' % self.box.get()
        else:
            params += ' -shell %i' % self.shell.get()

        #Parameters
        params += ' -sampling %f,%f,%f' % (sampling, sampling, sampling)
        params += ' -step %f' % self.step.get()
        params += ' -maxresolution %f' % self.maxresolution.get()
        params += ' -cutoff %f' % self.cutoff.get()
        if self.fill.get() != '':
            params += ' -fill %i' % self.fill.get()

        #Parameters for local resolution
        params += ' -pad %f' % self.pad.get()
        if self.symmetry.get() != '':
            params += ' -symmetry %s' % self.symmetry.get()
        if self.smooth.get():
            params += ' -smooth'
        if self.mask.get().getFileName() != '':
            params += ' -Mask %s' % self.fnmask

        # Input
        # input halves and output map
        params += ' %s %s %s' % (self.fnvol1, self.fnvol2,
                                 self._getFileName(FN_RESOLMAP))

        self.runJob('blocres', params)

    def createOutputStep(self):
        volume = Volume()
        volume.setFileName(self._getFileName(FN_RESOLMAP))
        volume.setSamplingRate(self.inputVolume.get().getSamplingRate())
        self._defineOutputs(resolution_Volume=volume)
        self._defineSourceRelation(self.inputVolume, volume)

        imageFile = self._getFileName(FN_RESOLMAP)
        min_, max_ = self.getMinMax(imageFile)
        self.min_res_init.set(round(min_ * 100) / 100)
        self.max_res_init.set(round(max_ * 100) / 100)
        self._store(self.min_res_init)
        self._store(self.max_res_init)

    def getMinMax(self, imageFile):
        img = ImageHandler().read(imageFile)
        imgData = img.getData()
        min_res = round(np.amin(imgData) * 100) / 100
        max_res = round(np.amax(imgData) * 100) / 100
        return min_res, max_res

#--------------------------- INFO functions -----------------------------------

    def _validate(self):
        errors = []
        return errors

    def _citations(self):
        cites = ['Cardone2013']
        return cites

    def _summary(self):
        summary = []
        summary.append("Highest resolution %.2f Å,   "
                       "Lowest resolution %.2f Å. \n" %
                       (self.min_res_init, self.max_res_init))

    def _methods(self):
        methods = []
        return methods
class XmippProtScreenParticles(ProtProcessParticles):
    """ Attach different merit values to every particle in order to
        prune the set.
        zScore evaluates the similarity of a particles with an average
        (lower zScore -> high similarity).
        SSNR evaluates the signal/noise ration in the Fourier space.
        Variance evaluates the varaince on the micrographs context where
        the particle was picked.
    """

    _label = 'screen particles'

    # Automatic Particle rejection enum
    ZSCORE_CHOICES = ['None', 'MaxZscore', 'Percentage']
    SSNR_CHOICES = ['None', 'Percentage']
    VAR_CHOICES = ['None', 'Variance', 'Var. and Gini']
    REJ_NONE = 0
    REJ_MAXZSCORE = 1
    REJ_PERCENTAGE = 2
    REJ_PERCENTAGE_SSNR = 1
    REJ_VARIANCE = 1
    REJ_VARGINI = 2

    # --------------------------- DEFINE param functions ---------------------
    def _defineProcessParams(self, form):
        # --- zScore rejection ---
        form.addParam('autoParRejection', EnumParam,
                      choices=self.ZSCORE_CHOICES,
                      label="Automatic rejection by Zscore",
                      default=self.REJ_NONE,
                      display=EnumParam.DISPLAY_COMBO,
                      help='zScore evaluates the similarity of a particles '
                           'with an average. The rejection can be:\n'
                           '  None (no rejection)\n'
                           '  MaxZscore (reject a particle if its zScore '
                           'is larger than this value).\n '
                           '  Percentage (reject a given percentage for '
                           'this criteria).')
        form.addParam('maxZscore', FloatParam, default=3, validators=[Positive],
                      condition='autoParRejection==1', label='zScore threshold',
                      help='Maximum Zscore.')
        form.addParam('percentage', IntParam, default=5, label='Percentage (%)',
                      condition='autoParRejection==2',
                      help='The worse percentage of particles according to '
                           'metadata labels: ZScoreShape1, ZScoreShape2, '
                           'ZScoreSNR1, ZScoreSNR2, ZScoreHistogram are '
                           'automatically disabled.',
                      validators=[Range(0, 100, error="Percentage must be "
                                                      "between 0 and 100.")])
        # --- SSNR rejection ---
        form.addParam('autoParRejectionSSNR', EnumParam,
                      choices=self.SSNR_CHOICES,
                      label="Automatic rejection by SSNR",
                      default=self.REJ_NONE, display=EnumParam.DISPLAY_COMBO,
                      help='SSNR evaluates the signal/noise ration in the '
                           'Fourier space. The rejection can be:\n'
                           '  None (no rejection)\n'
                           '  Percentage (reject a given percentage of the '
                           'lowest SSNRs).')
        form.addParam('percentageSSNR', IntParam, default=5,
                      condition='autoParRejectionSSNR==1',
                      label='Percentage (%)',
                      help='The worse percentage of particles according to '
                           'SSNR are automatically disabled.',
                      validators=[Range(0, 100, error="Percentage must be "
                                                      "between 0 and 100.")])
        # --- Variance rejection ---
        form.addParam('autoParRejectionVar', EnumParam, default=self.REJ_NONE,
                      choices=self.VAR_CHOICES,
                      label='Automatic rejection by Variance',
                      help='Variance evaluates the varaince on the micrographs '
                           'context where the particle was picked. '
                           'The rejection can be:\n'
                           '  None (no rejection)\n'
                           '  Variance (taking into account only the variance)\n'
                           '  Var. and Gini (taking into account also the Gini '
                           'coeff.)')
        # --- Add features ---
        form.addParam('addFeatures', BooleanParam, default=False,
                      label='Add features', expertLevel=LEVEL_ADVANCED,
                      help='Add features used for the ranking to each one '
                           'of the input particles')

        form.addParallelSection(threads=0, mpi=0)

    def _getDefaultParallel(self):
        """This protocol doesn't have mpi version"""
        return (0, 0)

    #--------------------------- INSERT steps functions ----------------------
    def _insertAllSteps(self):
        self._initializeZscores()
        self.outputSize = 0
        self.inputSize = 0
        self.check = None
        self.fnInputMd = self._getExtraPath("input.xmd")
        self.fnInputOldMd = self._getExtraPath("inputOld.xmd")
        self.fnOutputMd = self._getExtraPath("output.xmd")

        self.inputSize, self.streamClosed = self._loadInput()
        partsSteps = self._insertNewPartsSteps()
        self._insertFunctionStep('createOutputStep',
                                 prerequisites=partsSteps, wait=True)

    def _getFirstJoinStep(self):
        for s in self._steps:
            if s.funcName == self._getFirstJoinStepName():
                return s
        return None

    def _getFirstJoinStepName(self):
        # This function will be used for streaming, to check which is
        # the first function that need to wait for all micrographs
        # to have completed, this can be overriden in subclasses
        # (e.g., in Xmipp 'sortPSDStep')
        return 'createOutputStep'

    def createOutputStep(self):
        pass

    def _insertNewPartsSteps(self):
        deps = []
        stepId = self._insertFunctionStep('sortImagesStep', prerequisites=[])
        deps.append(stepId)
        return deps

    def _stepsCheck(self):
        # Input particles set can be loaded or None when checked for new inputs
        # If None, we load it
        self._checkNewInput()
        self._checkNewOutput()

    def _checkNewInput(self):
        # Check if there are new particles to process from the input set
        partsFile = self.inputParticles.get().getFileName()
        mTime = datetime.fromtimestamp(os.path.getmtime(partsFile))
        # If the input movies.sqlite have not changed since our last check,
        # it does not make sense to check for new input data
        if self.lastCheck > mTime:
            return None

        self.inputSize, self.streamClosed = self._loadInput()
        if not isEmpty(self.fnInputMd):
            fDeps = self._insertNewPartsSteps()
            outputStep = self._getFirstJoinStep()
            if outputStep is not None:
                outputStep.addPrerequisites(*fDeps)
            self.updateSteps()

    def _loadInput(self):
        self.lastCheck = datetime.now()
        partsFile = self.inputParticles.get().getFileName()
        inPartsSet = SetOfParticles(filename=partsFile)
        inPartsSet.loadAllProperties()

        check = None
        for p in inPartsSet.iterItems(orderBy='creation', direction='DESC'):
            check = p.getObjCreation()
            break
        if self.check is None:
            writeSetOfParticles(inPartsSet, self.fnInputMd,
                                alignType=ALIGN_NONE, orderBy='creation')
        else:
            writeSetOfParticles(inPartsSet, self.fnInputMd,
                                alignType=ALIGN_NONE, orderBy='creation',
                                where='creation>"' + str(self.check) + '"')
            writeSetOfParticles(inPartsSet, self.fnInputOldMd,
                                alignType=ALIGN_NONE, orderBy='creation',
                                where='creation<"' + str(self.check) + '"')
        self.check = check

        streamClosed = inPartsSet.isStreamClosed()
        inputSize = inPartsSet.getSize()

        inPartsSet.close()

        return inputSize, streamClosed

    def _checkNewOutput(self):
        if getattr(self, 'finished', False):
            return
        self.finished = self.streamClosed and \
                        self.outputSize == self.inputSize

        streamMode = Set.STREAM_CLOSED if self.finished else Set.STREAM_OPEN

        newData = os.path.exists(self.fnOutputMd)
        lastToClose = self.finished and hasattr(self, 'outputParticles')
        if newData or lastToClose:

            outSet = self._loadOutputSet(SetOfParticles, 'outputParticles.sqlite')

            if newData:
                partsSet = self._createSetOfParticles()
                readSetOfParticles(self.fnOutputMd, partsSet)
                outSet.copyItems(partsSet)
                for item in partsSet:
                    self._calculateSummaryValues(item)
                self._store()

                writeSetOfParticles(outSet.iterItems(orderBy='_xmipp_zScore'),
                                    self._getPath("images.xmd"),
                                    alignType=ALIGN_NONE)
                cleanPath(self.fnOutputMd)

            self._updateOutputSet('outputParticles', outSet, streamMode)

        if self.finished:  # Unlock createOutputStep if finished all jobs
            outputStep = self._getFirstJoinStep()
            if outputStep and outputStep.isWaiting():
                outputStep.setStatus(cons.STATUS_NEW)

    def _loadOutputSet(self, SetClass, baseName):
        setFile = self._getPath(baseName)
        if os.path.exists(setFile):
            outputSet = SetClass(filename=setFile)
            outputSet.loadAllProperties()
            outputSet.enableAppend()
        else:
            outputSet = SetClass(filename=setFile)
            outputSet.setStreamState(outputSet.STREAM_OPEN)
            self._store(outputSet)
            self._defineTransformRelation(self.inputParticles, outputSet)

        outputSet.copyInfo(self.inputParticles.get())

        return outputSet

    #--------------------------- STEP functions -----------------------------
    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 _initializeZscores(self):
        # Store the set for later access , ;-(
        self.minZScore = Float()
        self.maxZScore = Float()
        self.sumZScore = Float()
        self.varThreshold = Float()
        self._store()

    def _calculateSummaryValues(self, particle):
        zScore = particle._xmipp_zScore.get()

        self.minZScore.set(min(zScore, self.minZScore.get(1000)))
        self.maxZScore.set(max(zScore, self.maxZScore.get(0)))
        self.sumZScore.set(self.sumZScore.get(0) + zScore)

    # -------------------------- INFO functions ------------------------------
    def _summary(self):
        summary = []

        sumRejMet = {}  # A dict with the form choices
        if self.autoParRejection is not None:
            metStr = self.ZSCORE_CHOICES[self.autoParRejection.get()]
            if self.autoParRejection.get() == self.REJ_MAXZSCORE:
                metStr += " = %.2f" % self.maxZscore.get()
            elif self.autoParRejection.get() == self.REJ_PERCENTAGE:
                metStr += " = %.2f" % self.percentage.get()
            sumRejMet['Zscore'] = ("Zscore rejection method: " + metStr)

        if self.autoParRejectionSSNR is not None:
            metStr = self.SSNR_CHOICES[self.autoParRejectionSSNR.get()]
            if self.autoParRejectionSSNR.get() == self.REJ_PERCENTAGE_SSNR:
                metStr += " = %.2f" % self.percentageSSNR.get()
            sumRejMet['SSNR'] = ("SSNR rejection method: " + metStr)

        if self.autoParRejectionVar is not None:
            sumRejMet['Var'] = ("Variance rejection method: " +
                               self.VAR_CHOICES[self.autoParRejectionVar.get()])

        # If no output yet, just the form choices are shown plus a no-ready text
        if not hasattr(self, 'outputParticles'):
            summary += sumRejMet.values()
            summary.append("Output particles not ready yet.")
        else:
            summary.append(sumRejMet['Zscore'])
            if hasattr(self, 'sumZScore'):
                summary.append(" - The minimum ZScore is %.2f" % self.minZScore)
                summary.append(" - The maximum ZScore is %.2f" % self.maxZScore)
                meanZScore = self.sumZScore.get() * 1.0 / len(self.outputParticles)
                summary.append(" - The mean ZScore is %.2f" % meanZScore)
            else:
                summary.append(
                    "Summary values not calculated during processing.")
            summary.append(sumRejMet['SSNR'])
            summary.append(sumRejMet['Var'])
            if self.autoParRejectionVar != self.REJ_NONE:
                if hasattr(self, 'varThreshold'):
                    summary.append(" - Variance threshold: %.2f" % self.varThreshold)
                else:
                    summary.append(" - Variance threshold not calculed yet.")
        return summary
    
    def _validate(self):
        validateMsgs = []
        if self.autoParRejectionVar != self.REJ_NONE:
            part = self.inputParticles.get().getFirstItem()
            if not part.hasAttribute('_xmipp_scoreByVariance'):
                validateMsgs.append('The auto-rejection by Variance can not be '
                                    'done because the particles have not the '
                                    'scoreByVariance attribute. Use Xmipp to '
                                    'extract the particles.')
        return validateMsgs
        
    def _citations(self):
        return ['Vargas2013b']
    
    def _methods(self):
        methods = []
        if hasattr(self, 'outputParticles'):
            outParticles = (len(self.outputParticles) if self.outputParticles
                                                         is not None else None)
            particlesRejected = (len(self.inputParticles.get())-outParticles
                                 if outParticles is not None else None)
            particlesRejectedText = (' ('+str(particlesRejected)+')' if
                                     particlesRejected is not None else '')
            rejectionText = ['',  # REJ_NONE
                             ' and removing those not reaching %s%s'
                             % (str(self.maxZscore.get()),
                                particlesRejectedText),  # REJ_MAXZSCORE
                             ' and removing worst %s percent %s'
                             % (str(self.percentage.get()),
                                particlesRejectedText)  # REJ_PERCENTAGE
                             ]
            methods.append('Input dataset %s of %s particles was sorted by'
                           ' its ZScore using xmipp_image_sort_by_statistics'
                           ' program%s. '
                           % (self.getObjectTag('inputParticles'),
                              len(self.inputParticles.get()),
                              rejectionText[self.autoParRejection.get()]))
            methods.append('Output set is %s.'
                           % self.getObjectTag('outputParticles'))
        return methods
Пример #17
0
    def _checkNewOutput(self):
        """ Check for already selected CTF and update the output set. """

        # Load previously done items (from text file)
        doneListDiscarded = self._readDoneListDiscarded()
        doneListAccepted = self._readDoneListAccepted()

        # Check for newly done items
        ctfListIdAccepted = self._readtCtfId(True)
        ctfListIdDiscarded = self._readtCtfId(False)

        newDoneAccepted = [ctfId for ctfId in ctfListIdAccepted
                           if ctfId not in doneListAccepted]
        newDoneDiscarded = [ctfId for ctfId in ctfListIdDiscarded
                            if ctfId not in doneListDiscarded]
        firstTimeAccepted = len(doneListAccepted) == 0
        firstTimeDiscarded = len(doneListDiscarded) == 0
        allDone = len(doneListAccepted) + len(doneListDiscarded) +\
                  len(newDoneAccepted) + len(newDoneDiscarded)

        # We have finished when there is not more input ctf (stream closed)
        # and the number of processed ctf is equal to the number of inputs
        self.finished = (self.isStreamClosed and allDone == len(self.allCtf1))

        streamMode = Set.STREAM_CLOSED if self.finished else Set.STREAM_OPEN

        # reading the outputs
        if (len(doneListAccepted) > 0 or len(newDoneAccepted) > 0):
            ctfSet = self._loadOutputSet(em.SetOfCTF, 'ctfs.sqlite')
            micSet = self._loadOutputSet(em.SetOfMicrographs,
                                         'micrographs.sqlite')

        # AJ new subsets with discarded ctfs
        if (len(doneListDiscarded) > 0 or len(newDoneDiscarded) > 0):
            ctfSetDiscarded = \
                self._loadOutputSet(em.SetOfCTF, 'ctfsDiscarded.sqlite')
            micSetDiscarded = \
                self._loadOutputSet(em.SetOfMicrographs,
                                    'micrographsDiscarded.sqlite')

        if newDoneAccepted:
            inputCtfSet = self._loadInputCtfSet()
            for ctfId in newDoneAccepted:
                ctf = inputCtfSet[ctfId].clone()
                mic = ctf.getMicrograph().clone()

                ctf.setEnabled(self._getEnable(ctfId))
                mic.setEnabled(self._getEnable(ctfId))

                if self.calculateConsensus:
                    setattr(ctf, prefixAttribute('consensus_resolution'),
                            Float(self._freqResol[ctfId]))
                    setattr(ctf, prefixAttribute('discrepancy_astigmatism'),
                            Float(ctf.getDefocusU() - ctf.getDefocusV()))

                ctfSet.append(ctf)
                micSet.append(mic)
                self._writeDoneListAccepted(ctfId)

            inputCtfSet.close()

        if newDoneDiscarded:
            inputCtfSet = self._loadInputCtfSet()
            for ctfId in newDoneDiscarded:
                ctf = inputCtfSet[ctfId].clone()
                if self.calculateConsensus:
                    setattr(ctf, prefixAttribute('consensus_resolution'),
                            Float(self._freqResol[ctfId]))
                    setattr(ctf, prefixAttribute('discrepancy_astigmatism'),
                            Float(ctf.getDefocusU() - ctf.getDefocusV()))
                mic = ctf.getMicrograph().clone()
                micSetDiscarded.append(mic)
                ctfSetDiscarded.append(ctf)
                self._writeDoneListDiscarded(ctfId)

            inputCtfSet.close()

        if not self.finished and not newDoneDiscarded and not newDoneAccepted:
            # If we are not finished and no new output have been produced
            # it does not make sense to proceed and updated the outputs
            # so we exit from the function here
            return

        if (os.path.exists(self._getPath('ctfs.sqlite'))):
            self._updateOutputSet('outputCTF', ctfSet, streamMode)
            self._updateOutputSet('outputMicrographs', micSet, streamMode)
        # AJ new subsets with discarded ctfs
        if (os.path.exists(self._getPath('ctfsDiscarded.sqlite'))):
            self._updateOutputSet('outputCTFDiscarded',
                                  ctfSetDiscarded, streamMode)
            self._updateOutputSet('outputMicrographsDiscarded',
                                  micSetDiscarded, streamMode)

        if (os.path.exists(self._getPath('ctfs.sqlite'))):
            if firstTimeAccepted:
                # define relation just once
                self._defineTransformRelation(
                    self.inputCTF.get().getMicrographs(), micSet)
                self._defineTransformRelation(ctfSet, micSet)
                self._defineTransformRelation(self.inputCTF, ctfSet)
                self._defineCtfRelation(micSet, ctfSet)
            else:
                ctfSet.close()
                micSet.close()

        # AJ new subsets with discarded ctfs
        if (os.path.exists(self._getPath('ctfsDiscarded.sqlite'))):
            if firstTimeDiscarded:
                self._defineTransformRelation(
                    self.inputCTF.get().getMicrographs(), micSetDiscarded)
                self._defineTransformRelation(ctfSetDiscarded, micSetDiscarded)
                self._defineTransformRelation(self.inputCTF, ctfSetDiscarded)
                self._defineCtfRelation(micSetDiscarded, ctfSetDiscarded)
            else:
                micSetDiscarded.close()
                ctfSetDiscarded.close()

        if self.finished:  # Unlock createOutputStep if finished all jobs
            outputStep = self._getFirstJoinStep()
            if outputStep and outputStep.isWaiting():
                outputStep.setStatus(STATUS_NEW)

        if (os.path.exists(self._getPath('ctfs.sqlite'))):
            ctfSet.close()
            micSet.close()
        # AJ new subsets with discarded ctfs
        if (os.path.exists(self._getPath('ctfsDiscarded.sqlite'))):
            micSetDiscarded.close()
            ctfSetDiscarded.close()
 def _setWeight(self, item, row):
     item._xmipp_weightClusterability = Float(
         row.getValue(md.MDL_VOLUME_SCORE1))
Пример #19
0
    def testMergeDifferentAttrs(self):
        """ Test merge from subsets with different attritubes.
        That is, M1(a,b,c) U M2(a,b,c,d)"""

        # create two set of particles
        inFileNameMetadata1 = self.proj.getTmpPath('particles11.sqlite')
        inFileNameMetadata2 = self.proj.getTmpPath('particles22.sqlite')
        imgSet1 = SetOfParticles(filename=inFileNameMetadata1)
        imgSet2 = SetOfParticles(filename=inFileNameMetadata2)

        inFileNameData = self.proj.getTmpPath('particles.stk')
        # Start ids 4
        img1 = Particle(objId=4)
        img2 = Particle(objId=4)
        attrb1 = [11, 12, 13, 14]
        attrb2 = [21, 22, 23, 24]
        attrb3 = [31, 32]
        counter = 0
        # Test the join handles different attributes at a second level
        ctf1 = CTFModel(defocusU=1000, defocusV=1000, defocusAngle=0)
        ctf2 = CTFModel(defocusU=2000, defocusV=2000, defocusAngle=0)
        ctf2._myOwnQuality = Float(1.)
        img1.setCTF(ctf1)
        img2.setCTF(ctf2)

        for i in range(1, 3):
            # Increment Id
            img1.setObjId(img1.getObjId() + 1)
            img1.setLocation(i, inFileNameData)
            img1.setMicId(i % 3)
            img1.setClassId(i % 5)
            img1.setSamplingRate(1.)
            img1._attrb1 = Float(attrb1[counter])
            img1._attrb2 = Float(attrb2[counter])
            img1._attrb3 = Float(attrb3[counter])
            imgSet1.append(img1)
            counter += 1

        for i in range(1, 3):
            # Increment Id
            img2.setObjId(img2.getObjId() + 1)
            img2.setLocation(i, inFileNameData)
            img2.setClassId(i % 5)
            img2.setMicId(i % 3)
            img2.setSamplingRate(2.)
            img2._attrb1 = Float(attrb1[counter])
            img2._attrb2 = Float(attrb2[counter])
            imgSet2.append(img2)
            counter += 1

        imgSet1.write()
        imgSet2.write()

        # import them
        protImport1 = self.newProtocol(
            emprot.ProtImportParticles,
            objLabel='import set1',
            importFrom=emprot.ProtImportParticles.IMPORT_FROM_SCIPION,
            sqliteFile=inFileNameMetadata1,
            magnification=10000,
            samplingRate=7.08,
            haveDataBeenPhaseFlipped=True)
        self.launchProtocol(protImport1)

        protImport2 = self.newProtocol(
            emprot.ProtImportParticles,
            objLabel='import set2',
            importFrom=emprot.ProtImportParticles.IMPORT_FROM_SCIPION,
            sqliteFile=inFileNameMetadata2,
            magnification=10000,
            samplingRate=7.08,
            haveDataBeenPhaseFlipped=True)
        self.launchProtocol(protImport2)

        # create merge protocol
        p_union = self.newProtocol(emprot.ProtUnionSet,
                                   objLabel='join different attrs',
                                   ignoreExtraAttributes=True)
        p_union.inputSets.append(protImport1.outputParticles)
        p_union.inputSets.append(protImport2.outputParticles)
        self.proj.launchProtocol(p_union, wait=True)

        counter = 0

        for img in p_union.outputSet:
            self.assertAlmostEqual(attrb1[counter], img._attrb1, 4)
            self.assertAlmostEqual(attrb2[counter], img._attrb2, 4)
            self.assertFalse(hasattr(img, '_attrb3'),
                             "join should not have attrb3")
            self.assertTrue(hasattr(img, '_attrb2'), "join should have attrb2")
            ctf = img.getCTF()
            self.assertIsNotNone(ctf, "Image should have CTF after join")
            self.assertFalse(hasattr(ctf, '_myOwnQuality'),
                             "CTF should not have non common attributes")

            # Assert ids
            self.assertEqual(counter + 5, img.getObjId(),
                             "Object id's not kept.")
            counter += 1
class BsoftProtBlocres(ProtAnalysis3D):
    """
    Bsoft program: blocres
    It calculates the local resolution map from to half maps.
    The method is based on a local measurement inside a mobile window.
    """
    _label = 'blocres'

    def __init__(self, **args):
        ProtAnalysis3D.__init__(self, **args)
        self.min_res_init = Float()
        self.max_res_init = Float()
        self.halfVolumes = True

    # --------------------------- DEFINE param functions -----------------------
    def _defineParams(self, form):
        form.addSection(label='Input')
        form.addParam('inputVolume',
                      params.PointerParam,
                      pointerClass='Volume',
                      label="Half 1",
                      help="Select first half volume to compute the "
                      "local resolution.")
        form.addParam('inputVolume2',
                      params.PointerParam,
                      pointerClass='Volume',
                      label="Half 2",
                      help="Select first half volume to compute the "
                      "local resolution.")
        form.addParam('mask',
                      params.PointerParam,
                      allowsNull=True,
                      pointerClass='Volume',
                      label='Mask',
                      help="Mask file to use for limiting the analysis to a "
                      "defined region and level value to use "
                      "(optional, default: all but zero).")
        form.addParam('method',
                      params.BooleanParam,
                      default=True,
                      label='Use Box',
                      help="The local (box) and shell (shell) resolution "
                      "calculations are mutually exclusive.")
        form.addParam('box',
                      params.IntParam,
                      default=20,
                      condition='method',
                      label='Box',
                      help="Kernel size for determining "
                      "local resolution (pixels/voxels).")
        form.addParam('shell',
                      params.IntParam,
                      default=20,
                      condition='not method',
                      label='Shell',
                      help="Shell width for determining "
                      "radial resolution (pixels/voxels).")

        form.addParam('cutoff',
                      params.FloatParam,
                      default=0.5,
                      label='Cutoff',
                      help="Resolution cutoff for FSC."
                      "(default: 0.5).")

        form.addSection(label='Parameters')
        form.addParam('step',
                      params.IntParam,
                      default=1,
                      label='Step',
                      help="Interval between voxel samples or shells for "
                      "resolution analysis (pixels, default: 1)")
        form.addParam(
            'maxresolution',
            params.FloatParam,
            default=2,
            label='Maximum Resolution',
            help="Maximum frequency available in the data (angstrom).")
        form.addParam('fill',
                      params.IntParam,
                      allowsNull=True,
                      label='Fill',
                      help="Value to fill the background "
                      "(non-masked regions; default 0).")
        form.addParam('pad',
                      params.EnumParam,
                      choices=['None', 'Box', 'Shell'],
                      default=1,
                      label='Padding Factor',
                      help="Resolution box padding factor "
                      "(0 = none, default: 1 (box) and 0 (shell)).")
        form.addParam('symmetry',
                      params.StringParam,
                      allowsNull=True,
                      default='',
                      label='Symmetry',
                      help="Point group symmetry.")
        form.addParam('smooth',
                      params.BooleanParam,
                      default=True,
                      label='Smooth',
                      help="Smooth the shell edge.")

    def _createFilenameTemplates(self):
        """ Centralize how files are called """
        myDict = {
            FN_HALF1: self._getTmpPath("half1.map"),
            FN_HALF2: self._getTmpPath("half2.map"),
            FN_MASKVOL: self._getTmpPath("mask.map"),
            FN_RESOLMAP: self._getExtraPath("resolutionMap.map")
        }
        self._updateFilenamesDict(myDict)

    # --------------------------- INSERT steps functions -----------------------
    def _insertAllSteps(self):
        # Insert processing steps
        self._createFilenameTemplates()
        self._insertFunctionStep('convertInputStep')
        self._insertFunctionStep('resolutionStep')
        self._insertFunctionStep('createOutputStep')

    # --------------------------- STEPS functions ------------------------------
    def convertInputStep(self):
        # blocres works with .map
        vol1Fn = self.inputVolume.get().getFileName()
        vol2Fn = self.inputVolume2.get().getFileName()
        if self.mask.get().getFileName() != '':
            maskFn = self.mask.get().getFileName()

        self.fnvol1 = self._getFileName("half1")
        self.fnvol2 = self._getFileName("half2")
        ImageHandler().convert(vol1Fn, self.fnvol1)
        ImageHandler().convert(vol2Fn, self.fnvol2)
        if self.mask.get().getFileName() != '':
            self.fnmask = self._getFileName("maskvol")
            ImageHandler().convert(maskFn, self.fnmask)
        else:
            self.fnmask = self.maks.get().getFileName()

    def resolutionStep(self):
        """ blocres parameters. """
        sampling = self.inputVolume.get().getSamplingRate()
        # Actions
        params = ' -v 1'  # No Verbose
        if self.method:
            params += ' -box %i' % self.box.get()
        else:
            params += ' -shell %i' % self.shell.get()

        # Parameters
        params += ' -sampling %f,%f,%f' % (sampling, sampling, sampling)
        params += ' -step %f' % self.step.get()
        params += ' -maxresolution %f' % self.maxresolution.get()
        params += ' -cutoff %f' % self.cutoff.get()
        if self.fill.get() != '':
            params += ' -fill %i' % self.fill.get()

        # Parameters for local resolution
        params += ' -pad %f' % self.pad.get()
        if self.symmetry.get() != '':
            params += ' -symmetry %s' % self.symmetry.get()
        if self.smooth.get():
            params += ' -smooth'
        if self.mask.get().getFileName() != '':
            params += ' -Mask %s' % self.fnmask

        # input halves and output map
        params += ' %s %s %s' % (self.fnvol1, self.fnvol2,
                                 self._getFileName(FN_RESOLMAP))

        self.runJob(bsoft.Plugin.getProgram('blocres'),
                    params,
                    env=bsoft.Plugin.getEnviron())

    def createOutputStep(self):
        volume = Volume()
        volume.setFileName(self._getFileName(FN_RESOLMAP))
        volume.setSamplingRate(self.inputVolume.get().getSamplingRate())
        self._defineOutputs(resolution_Volume=volume)
        self._defineSourceRelation(self.inputVolume, volume)

        imageFile = self._getFileName(FN_RESOLMAP)
        min_, max_ = self.getMinMax(imageFile)
        self.min_res_init.set(round(min_ * 100) / 100)
        self.max_res_init.set(round(max_ * 100) / 100)
        self._store(self.min_res_init)
        self._store(self.max_res_init)

    def getMinMax(self, imageFile):
        img = ImageHandler().read(imageFile)
        imgData = img.getData()
        # Remove 0's
        imgData = imgData[np.nonzero(imgData)]
        min_res = round(np.amin(imgData) * 100) / 100
        max_res = round(np.amax(imgData) * 100) / 100
        return min_res, max_res

    # --------------------------- INFO functions -----------------------------------
    def _validate(self):
        errors = []
        return errors

    def _citations(self):
        cites = ['Cardone2013']
        return cites

    def _summary(self):
        summary = []
        summary.append("Highest resolution %.2f A,   "
                       "Lowest resolution %.2f A." %
                       (self.min_res_init.get(), self.max_res_init.get()))

    def _methods(self):
        methods = []
        return methods
class XmippProtMonoRes(ProtAnalysis3D):
    """    
    Given a map the protocol assigns local resolutions to each voxel of the map.
    """
    _label = 'local MonoRes'
    _lastUpdateVersion = VERSION_1_1

    def __init__(self, **args):
        ProtAnalysis3D.__init__(self, **args)
        self.min_res_init = Float()
        self.max_res_init = Float()

    # --------------------------- DEFINE param functions ----------------------
    def _defineParams(self, form):
        form.addSection(label='Input')

        form.addParam('halfVolumes',
                      BooleanParam,
                      default=False,
                      label="Would you like to use half volumes?",
                      help='The noise estimation for determining the '
                      'local resolution is performed via half volumes.')

        form.addParam('inputVolumes',
                      PointerParam,
                      pointerClass='Volume',
                      label="Input Volume",
                      important=True,
                      condition='not halfVolumes',
                      help='Select a volume for determining its '
                      'local resolution.')

        form.addParam('inputVolume',
                      PointerParam,
                      pointerClass='Volume',
                      label="Volume Half 1",
                      important=True,
                      condition='halfVolumes',
                      help='Select a volume for determining its '
                      'local resolution.')

        form.addParam('inputVolume2',
                      PointerParam,
                      pointerClass='Volume',
                      label="Volume Half 2",
                      important=True,
                      condition='halfVolumes',
                      help='Select a second volume for determining a '
                      'local resolution.')

        form.addParam('Mask',
                      PointerParam,
                      pointerClass='VolumeMask',
                      condition='(halfVolumes) or (not halfVolumes)',
                      allowsNull=True,
                      label="Binary Mask",
                      help='The mask determines which points are specimen'
                      ' and which are not')

        group = form.addGroup('Extra parameters')
        #         group.addParam('symmetry', StringParam, default='c1',
        #                       label="Symmetry",
        #                       help='Symmetry group. By default = c1.'
        #                       'See [[http://xmipp.cnb.csic.es/twiki/bin/view/Xmipp/Symmetry][Symmetry]]'
        #                       'for a description of the symmetry groups format,'
        #                       'If no symmetry is present, give c1.')

        line = group.addLine(
            'Resolution Range (Å)',
            help='If the user knows the range of resolutions or'
            'only a range of frequencies needs to be analysed.'
            'If Low is empty MonoRes will try to estimate the range. '
            'it should be better if a range is provided')

        group.addParam('significance',
                       FloatParam,
                       default=0.95,
                       expertLevel=LEVEL_ADVANCED,
                       label="Significance",
                       help='Relution is computed using hipothesis tests, '
                       'this value determines the significance of that test')

        group.addParam(
            'maskthreshold',
            FloatParam,
            default=0.5,
            expertLevel=LEVEL_ADVANCED,
            label="Mask threshold",
            help='If the provided mask is not binary. Then, MonoRes'
            'will try to binarize it. Bmask values below the threshold'
            'will be change to 0 and above the thresthol will be 1')

        group.addParam('isPremasked',
                       BooleanParam,
                       default=False,
                       label="Is the original premasked?",
                       help='Sometimes the original volume is masked inside '
                       'a spherical mask. In this case please select yes')

        form.addParam(
            'noiseonlyinhalves',
            BooleanParam,
            expertLevel=LEVEL_ADVANCED,
            default=True,
            label="Use noise outside the mask?",
            condition='halfVolumes',
            help='Select yes if the volume present noise outside the mask.'
            ' Otherwise, select No.')

        group.addParam('volumeRadius',
                       FloatParam,
                       default=-1,
                       label="Spherical mask radius (px)",
                       condition='isPremasked and not halfVolumes',
                       help='When the original volume is originally premasked,'
                       'the noise estimation ought to be performed inside'
                       'that premask, and out of the provieded mask asked in'
                       'the previus box. The radius value, determines the'
                       'radius of the spherical premask. '
                       'By default radius = -1 use the half of the '
                       'volume size as radius')

        group.addParam(
            'volumeRadiusHalf',
            FloatParam,
            default=-1,
            label="Spherical mask radius (px)",
            condition='halfVolumes and isPremasked',
            help='When the origianl volume is originally premasked,'
            'the noise estimation ought to be performed inside that'
            'premask, and out of the provieded mask asked in the previus'
            'box. The radius value, determines the radius in pixels of '
            'the spherical premask. By default radius = -1 use the half'
            'of the volume size as radius')

        line.addParam('minRes', FloatParam, default=0, label='High')
        line.addParam('maxRes',
                      FloatParam,
                      default=12,
                      allowsNull=True,
                      label='Low')
        line.addParam('stepSize',
                      FloatParam,
                      allowsNull=True,
                      expertLevel=LEVEL_ADVANCED,
                      label='Step')

        group.addParam('filterInput',
                       BooleanParam,
                       default=False,
                       label="Filter input volume with local resolution?",
                       help='The input map is locally filtered at'
                       'the local resolution map.')

        form.addParallelSection(threads=4, mpi=0)

    # --------------------------- INSERT steps functions --------------------------------------------

    def _createFilenameTemplates(self):
        """ Centralize how files are called """
        myDict = {
            FN_MEAN_VOL:
            self._getExtraPath('mean_volume.vol'),
            OUTPUT_MASK_FILE:
            self._getExtraPath("output_Mask.vol"),
            OUTPUT_RESOLUTION_FILE_CHIMERA:
            self._getExtraPath(CHIMERA_RESOLUTION_VOL),
            FN_FILTERED_MAP:
            self._getExtraPath('filteredMap.vol'),
            OUTPUT_RESOLUTION_FILE:
            self._getExtraPath('mgresolution.vol'),
            METADATA_MASK_FILE:
            self._getExtraPath('mask_data.xmd'),
            FN_METADATA_HISTOGRAM:
            self._getExtraPath('hist.xmd'),
            BINARY_MASK:
            self._getExtraPath('binarized_mask.vol'),
            FN_GAUSSIAN_MAP:
            self._getExtraPath('gaussianfilted.vol')
        }
        self._updateFilenamesDict(myDict)

    def _insertAllSteps(self):
        # Convert input into xmipp Metadata format
        self._createFilenameTemplates()
        self._insertFunctionStep('convertInputStep', )
        self._insertFunctionStep('resolutionMonogenicSignalStep')
        self._insertFunctionStep('createOutputStep')
        self._insertFunctionStep("createHistrogram")

    def convertInputStep(self):
        """ Read the input volume.
        """

        self.micsFn = self._getPath()

        if self.halfVolumes:
            self.vol1Fn = self.inputVolume.get().getFileName()
            self.vol2Fn = self.inputVolume2.get().getFileName()
            extVol1 = getExt(self.vol1Fn)
            extVol2 = getExt(self.vol2Fn)
            if (extVol1 == '.mrc') or (extVol1 == '.map'):
                self.vol1Fn = self.vol1Fn + ':mrc'
            if (extVol2 == '.mrc') or (extVol2 == '.map'):
                self.vol2Fn = self.vol2Fn + ':mrc'

            if not self.Mask.hasValue():
                self.ifNomask(self.vol1Fn)
            else:
                self.maskFn = self.Mask.get().getFileName()

            self.inputVolumes.set(None)
        else:
            self.vol0Fn = self.inputVolumes.get().getFileName()
            extVol0 = getExt(self.vol0Fn)
            if (extVol0 == '.mrc') or (extVol0 == '.map'):
                self.vol0Fn = self.vol0Fn + ':mrc'

            if not self.Mask.hasValue():
                self.ifNomask(self.vol0Fn)
            else:
                self.maskFn = self.Mask.get().getFileName()

            print self.maskFn

            self.inputVolume.set(None)
            self.inputVolume2.set(None)

        extMask = getExt(self.maskFn)
        if (extMask == '.mrc') or (extMask == '.map'):
            self.maskFn = self.maskFn + ':mrc'

        if self.Mask.hasValue():
            params = ' -i %s' % self.maskFn
            params += ' -o %s' % self._getFileName(BINARY_MASK)
            params += ' --select below %f' % self.maskthreshold.get()
            params += ' --substitute binarize'

            self.runJob('xmipp_transform_threshold', params)

    def ifNomask(self, fnVol):
        if self.halfVolumes:
            xdim, _ydim, _zdim = self.inputVolume.get().getDim()
            params = ' -i %s' % fnVol
        else:
            xdim, _ydim, _zdim = self.inputVolumes.get().getDim()
            params = ' -i %s' % fnVol
        params += ' -o %s' % self._getFileName(FN_GAUSSIAN_MAP)
        setsize = 0.02 * xdim
        params += ' --fourier real_gaussian %f' % (setsize)

        self.runJob('xmipp_transform_filter', params)
        img = ImageHandler().read(self._getFileName(FN_GAUSSIAN_MAP))
        imgData = img.getData()
        max_val = np.amax(imgData) * 0.05

        params = ' -i %s' % self._getFileName(FN_GAUSSIAN_MAP)
        params += ' --select below %f' % max_val
        params += ' --substitute binarize'
        params += ' -o %s' % self._getFileName(BINARY_MASK)

        self.runJob('xmipp_transform_threshold', params)

        self.maskFn = self._getFileName(BINARY_MASK)

    def maskRadius(self, halfmaps, premaskedmap):
        if halfmaps:
            if premaskedmap:
                if self.volumeRadiusHalf == -1:
                    xdim, _ydim, _zdim = self.inputVolume.get().getDim()
                    xdim = xdim * 0.5
                else:
                    xdim = self.volumeRadiusHalf.get()
            else:
                xdim, _ydim, _zdim = self.inputVolume.get().getDim()
                xdim = xdim * 0.5
        else:
            if premaskedmap:
                if self.volumeRadius == -1:
                    xdim, _ydim, _zdim = self.inputVolumes.get().getDim()
                    xdim = xdim * 0.5
                else:
                    xdim = self.volumeRadius.get()
            else:
                xdim, _ydim, _zdim = self.inputVolumes.get().getDim()
                xdim = xdim * 0.5
        return xdim

    def resolutionMonogenicAuto(self):
        freq_step = 1

        xdim = self.maskRadius(self.halfVolumes, self.isPremasked)

        if self.halfVolumes:
            params = ' --vol %s' % self.vol1Fn
            params += ' --vol2 %s' % self.vol2Fn
            params += ' --meanVol %s' % self._getFileName(FN_MEAN_VOL)
            params += ' --mask %s' % self._getFileName(BINARY_MASK)
            params += ' --sampling_rate %f' % self.inputVolume.get(
            ).getSamplingRate()
            if (self.noiseonlyinhalves is False):
                params += ' --noiseonlyinhalves'
        else:
            params = ' --vol %s' % self.vol0Fn
            params += ' --mask %s' % self._getFileName(BINARY_MASK)
            params += ' --sampling_rate %f' % self.inputVolumes.get(
            ).getSamplingRate()

        params += ' --automatic '
        params += ' --step %f' % freq_step
        params += ' --mask_out %s' % self._getFileName(OUTPUT_MASK_FILE)
        params += ' -o %s' % self._getFileName(OUTPUT_RESOLUTION_FILE)
        params += ' --volumeRadius %f' % xdim
        params += ' --chimera_volume %s' % self._getFileName(
            OUTPUT_RESOLUTION_FILE_CHIMERA)
        params += ' --sym %s' % 'c1'  #self.symmetry.get()
        params += ' --significance %f' % self.significance.get()
        params += ' --md_outputdata %s' % self._getFileName(METADATA_MASK_FILE)
        params += ' --filtered_volume %s' % ''
        params += ' --threads %i' % self.numberOfThreads.get()

        self.runJob('xmipp_resolution_monogenic_signal', params)

    def resolutionMonogenicSignalStep(self):
        # Number of frequencies
        if (not self.maxRes.hasValue()):
            self.resolutionMonogenicAuto()
            imageFile = self._getFileName(OUTPUT_RESOLUTION_FILE)
            min_, max_ = self.getMinMax(imageFile)
        else:
            max_ = self.maxRes.get()

        if self.stepSize.hasValue():
            freq_step = self.stepSize.get()
        else:
            freq_step = 0.25

        xdim = self.maskRadius(self.halfVolumes, self.isPremasked)

        if self.halfVolumes:
            params = ' --vol %s' % self.vol1Fn
            params += ' --vol2 %s' % self.vol2Fn
            params += ' --meanVol %s' % self._getFileName(FN_MEAN_VOL)
            params += ' --mask %s' % self._getFileName(BINARY_MASK)
            params += ' --sampling_rate %f' % self.inputVolume.get(
            ).getSamplingRate()
            if (self.noiseonlyinhalves is False):
                params += ' --noiseonlyinhalves'
        else:
            params = ' --vol %s' % self.vol0Fn
            params += ' --mask %s' % self._getFileName(BINARY_MASK)
            params += ' --sampling_rate %f' % self.inputVolumes.get(
            ).getSamplingRate()

        params += ' --minRes %f' % self.minRes.get()
        params += ' --maxRes %f' % max_

        params += ' --step %f' % freq_step
        params += ' --mask_out %s' % self._getFileName(OUTPUT_MASK_FILE)
        params += ' -o %s' % self._getFileName(OUTPUT_RESOLUTION_FILE)
        params += ' --volumeRadius %f' % xdim
        params += ' --exact'
        params += ' --chimera_volume %s' % self._getFileName(
            OUTPUT_RESOLUTION_FILE_CHIMERA)
        params += ' --sym %s' % 'c1'  #self.symmetry.get()
        params += ' --significance %f' % self.significance.get()
        params += ' --md_outputdata %s' % self._getFileName(METADATA_MASK_FILE)
        params += ' --threads %i' % self.numberOfThreads.get()
        if self.filterInput.get():
            params += ' --filtered_volume %s' % self._getFileName(
                FN_FILTERED_MAP)
        else:
            params += ' --filtered_volume %s' % ''

        self.runJob('xmipp_resolution_monogenic_signal', params)

    def createHistrogram(self):

        M = float(self.max_res_init)
        m = float(self.min_res_init)
        range_res = round((M - m) * 4.0)

        params = ' -i %s' % self._getFileName(OUTPUT_RESOLUTION_FILE)
        params += ' --mask binary_file %s' % self._getFileName(
            OUTPUT_MASK_FILE)
        params += ' --steps %f' % (range_res)
        params += ' --range %f %f' % (self.min_res_init, self.max_res_init)
        params += ' -o %s' % self._getFileName(FN_METADATA_HISTOGRAM)

        self.runJob('xmipp_image_histogram', params)

    def readMetaDataOutput(self):
        mData = md.MetaData(self._getFileName(METADATA_MASK_FILE))
        NvoxelsOriginalMask = float(
            mData.getValue(md.MDL_COUNT, mData.firstObject()))
        NvoxelsOutputMask = float(
            mData.getValue(md.MDL_COUNT2, mData.firstObject()))
        nvox = int(
            round(((NvoxelsOriginalMask - NvoxelsOutputMask) /
                   NvoxelsOriginalMask) * 100))
        return nvox

    def getMinMax(self, imageFile):
        img = ImageHandler().read(imageFile)
        imgData = img.getData()
        min_res = round(np.amin(imgData) * 100) / 100
        max_res = round(np.amax(imgData) * 100) / 100
        return min_res, max_res

    def createOutputStep(self):
        volume = Volume()
        volume.setFileName(self._getFileName(OUTPUT_RESOLUTION_FILE))
        if (self.halfVolumes):
            volume.setSamplingRate(self.inputVolume.get().getSamplingRate())
            self._defineOutputs(resolution_Volume=volume)
            self._defineSourceRelation(self.inputVolume, volume)
        else:
            volume.setSamplingRate(self.inputVolumes.get().getSamplingRate())
            self._defineOutputs(resolution_Volume=volume)
            self._defineSourceRelation(self.inputVolumes, volume)

        #Setting the min max for the summary
        imageFile = self._getFileName(OUTPUT_RESOLUTION_FILE_CHIMERA)
        min_, max_ = self.getMinMax(imageFile)
        self.min_res_init.set(round(min_ * 100) / 100)
        self.max_res_init.set(round(max_ * 100) / 100)
        self._store(self.min_res_init)
        self._store(self.max_res_init)

        if self.filterInput.get():
            print 'Saving filtered map'
            volume.setFileName(self._getFileName(FN_FILTERED_MAP))
            if (self.halfVolumes):
                volume.setSamplingRate(
                    self.inputVolume.get().getSamplingRate())
                self._defineOutputs(outputVolume_Filtered=volume)
                self._defineSourceRelation(self.inputVolume, volume)
            else:
                volume.setSamplingRate(
                    self.inputVolumes.get().getSamplingRate())
                self._defineOutputs(outputVolume_Filtered=volume)
                self._defineSourceRelation(self.inputVolumes, volume)

    # --------------------------- INFO functions ------------------------------

    def _methods(self):
        messages = []
        if hasattr(self, 'resolution_Volume'):
            messages.append('Information about the method/article in ' +
                            MONORES_METHOD_URL)
        return messages

    def _summary(self):
        summary = []
        summary.append("Highest resolution %.2f Å,   "
                       "Lowest resolution %.2f Å. \n" %
                       (self.min_res_init, self.max_res_init))
        return summary

    def _citations(self):
        return ['Vilas2018']
 def __init__(self, **args):
     ProtAnalysis3D.__init__(self, **args)
     self.min_res_init = Float()
     self.max_res_init = Float()
     self.halfVolumes = True
 def __init__(self, **args):
     ProtAnalysis3D.__init__(self, **args)
     self.min_res_init = Float()
     self.max_res_init = Float()
     self.median_res_init = Float()
class XmippProtMonoTomo(ProtAnalysis3D):
    """
    Given a tomogram the protocol assigns local resolutions to each voxel of the tomogram.
    """
    _label = 'local Resolution MonoTomo'
    _lastUpdateVersion = VERSION_2_0

    def __init__(self, **args):
        ProtAnalysis3D.__init__(self, **args)
        self.min_res_init = Float()
        self.max_res_init = Float()

    # --------------------------- DEFINE param functions ----------------------
    def _defineParams(self, form):
        form.addSection(label='Input')

        form.addParam('half1', PointerParam, pointerClass='Tomogram',
                      label="Odd tomogram", important=True,
                      help='Select a volume for determining its '
                           'local resolution.')

        form.addParam('half2', PointerParam, pointerClass='Tomogram',
                      label="Even Tomogram", important=True,
                      help='Select a second volume for determining a '
                           'local resolution.')

        form.addParam('useMask', BooleanParam, default=False,
                      label="Use mask?",
                      help='The mask determines which points are specimen'
                           ' and which are not.')

        form.addParam('Mask', PointerParam, pointerClass='VolumeMask',
                      condition='useMask', allowsNull=True,
                      label="Binary Mask",
                      help='The mask determines which points are specimen'
                           ' and which are not')

        group = form.addGroup('Extra parameters')
        line = group.addLine('Resolution Range (Å)',
                             help="Resolution range (and step in expert mode) "
                                  "to evaluate the local resolution.")

        group.addParam('significance', FloatParam, default=0.95,
                       expertLevel=LEVEL_ADVANCED,
                       label="Significance",
                       help='Relution is computed using hipothesis tests, '
                            'this value determines the significance of that test')

        line.addParam('minRes', FloatParam, default=0, label='High')
        line.addParam('maxRes', FloatParam, allowsNull=True, label='Low')
        line.addParam('stepSize', FloatParam, allowsNull=True, default=0.25,
                      expertLevel=LEVEL_ADVANCED, label='Step')

        form.addParallelSection(threads=4, mpi=0)

    # --------------------------- INSERT steps functions --------------------------------------------

    def _createFilenameTemplates(self):
        """ Centralize how files are called """
        myDict = {
            FN_MEAN_VOL: self._getExtraPath('mean_Tomogram.mrc'),
            OUTPUT_RESOLUTION_FILE: self._getExtraPath('TomogramLocalResolution.mrc'),
            METADATA_MASK_FILE: self._getExtraPath('mask_data.xmd'),
            FN_METADATA_HISTOGRAM: self._getExtraPath('hist.xmd'),
            BINARY_MASK: self._getExtraPath('binarized_mask.mrc'),
            FN_GAUSSIAN_MAP: self._getExtraPath('gaussianfilted.mrc'),
        }
        self._updateFilenamesDict(myDict)

    def _insertAllSteps(self):
        # Convert input into xmipp Metadata format
        self._createFilenameTemplates()
        self._insertFunctionStep('convertInputStep')
        self._insertFunctionStep('resolutionMonoTomoStep')
        self._insertFunctionStep('createOutputStep')
        self._insertFunctionStep("createHistrogram")

    def convertInputStep(self):
        """ Read the input volume.
        """

        self.vol1Fn = self.half1.get().getFileName()
        self.vol2Fn = self.half2.get().getFileName()
        extVol1 = getExt(self.vol1Fn)
        extVol2 = getExt(self.vol2Fn)
        if (extVol1 == '.mrc') or (extVol1 == '.map'):
            self.vol1Fn = self.vol1Fn + ':mrc'
        if (extVol2 == '.mrc') or (extVol2 == '.map'):
            self.vol2Fn = self.vol2Fn + ':mrc'

        if self.useMask.get():
            if (not self.Mask.hasValue()):
                self.ifNomask(self.vol1Fn)
            else:
                self.maskFn = self.Mask.get().getFileName()

            extMask = getExt(self.maskFn)

            if (extMask == '.mrc') or (extMask == '.map'):
                self.maskFn = self.maskFn + ':mrc'

            if self.Mask.hasValue():
                params = ' -i %s' % self.maskFn
                params += ' -o %s' % self._getFileName(BINARY_MASK)
                params += ' --select below %f' % 0.5  # Mask threshold = 0.5 self.maskthreshold.get()
                params += ' --substitute binarize'

                self.runJob('xmipp_transform_threshold', params)

    def ifNomask(self, fnVol):
        xdim, _ydim, _zdim = self.half1.get().getDim()
        params = ' -i %s' % fnVol
        params += ' -o %s' % self._getFileName(FN_GAUSSIAN_MAP)
        setsize = 0.02 * xdim
        params += ' --fourier real_gaussian %f' % (setsize)

        self.runJob('xmipp_transform_filter', params)
        img = ImageHandler().read(self._getFileName(FN_GAUSSIAN_MAP))
        imgData = img.getData()
        max_val = np.amax(imgData) * 0.05

        params = ' -i %s' % self._getFileName(FN_GAUSSIAN_MAP)
        params += ' --select below %f' % max_val
        params += ' --substitute binarize'
        params += ' -o %s' % self._getFileName(BINARY_MASK)

        self.runJob('xmipp_transform_threshold', params)

        self.maskFn = self._getFileName(BINARY_MASK)

    def maskRadius(self):

        xdim, _ydim, _zdim = self.half1.get().getDim()
        xdim = xdim * 0.5

        return xdim

    def resolutionMonoTomoStep(self):
        # Number of frequencies
        max_ = self.maxRes.get()

        if self.stepSize.hasValue():
            freq_step = self.stepSize.get()
        else:
            freq_step = 0.25

        xdim = self.maskRadius()

        params = ' --vol %s' % self.vol1Fn
        params += ' --vol2 %s' % self.vol2Fn
        params += ' --meanVol %s' % self._getFileName(FN_MEAN_VOL)

        if self.useMask.get():
            params += ' --mask %s' % self._getFileName(BINARY_MASK)

        params += ' --sampling_rate %f' % self.half1.get().getSamplingRate()
        params += ' --minRes %f' % self.minRes.get()
        params += ' --maxRes %f' % max_
        params += ' --step %f' % freq_step
        params += ' -o %s' % self._getFileName(OUTPUT_RESOLUTION_FILE)
        params += ' --significance %f' % self.significance.get()

        self.runJob('xmipp_resolution_monotomo', params)

    def createHistrogram(self):

        freq_step = self.stepSize.get() if self.stepSize.hasValue() else 10

        M = float(self.max_res_init)
        m = float(self.min_res_init)
        range_res = round((M - m) / freq_step)

        params = ' -i %s' % self._getFileName(OUTPUT_RESOLUTION_FILE)

        if self.useMask.get():
            params += ' --mask binary_file %s' % self._getFileName(BINARY_MASK)

        params += ' --steps %f' % range_res
        params += ' --range %f %f' % (self.min_res_init.get(),
                                      (float(self.max_res_init.get()) - float(freq_step)))
        params += ' -o %s' % self._getFileName(FN_METADATA_HISTOGRAM)

        self.runJob('xmipp_image_histogram', params)

    def readMetaDataOutput(self):
        mData = md.MetaData(self._getFileName(METADATA_MASK_FILE))
        NvoxelsOriginalMask = float(mData.getValue(md.MDL_COUNT, mData.firstObject()))
        NvoxelsOutputMask = float(mData.getValue(md.MDL_COUNT2, mData.firstObject()))
        nvox = int(round(
            ((NvoxelsOriginalMask - NvoxelsOutputMask) / NvoxelsOriginalMask) * 100))
        return nvox

    def getMinMax(self, imageFile):
        img = ImageHandler().read(imageFile)
        imgData = img.getData()
        min_res = round(np.amin(imgData) * 100) / 100
        max_res = round(np.amax(imgData) * 100) / 100
        return min_res, max_res

    def createOutputStep(self):
        volume = Tomogram()
        volume.setFileName(self._getFileName(OUTPUT_RESOLUTION_FILE))

        volume.setSamplingRate(self.half1.get().getSamplingRate())
        self._defineOutputs(resolution_Volume=volume)
        self._defineSourceRelation(self.half1, volume)

        # Setting the min max for the summary
        imageFile = self._getFileName(OUTPUT_RESOLUTION_FILE)
        min_, max_ = self.getMinMax(imageFile)
        self.min_res_init.set(round(min_ * 100) / 100)
        self.max_res_init.set(round(max_ * 100) / 100)
        self._store(self.min_res_init)
        self._store(self.max_res_init)

    # --------------------------- INFO functions ------------------------------

    def _methods(self):
        messages = []
        if hasattr(self, 'LocalResolution_Tomogram'):
            messages.append(
                'Information about the method/article in ' + MONOTOMO_METHOD_URL)
        return messages

    def _summary(self):
        summary = []
        summary.append("Highest resolution %.2f Å,   "
                       "Lowest resolution %.2f Å. \n" % (self.min_res_init,
                                                         self.max_res_init))
        return summary

    def _citations(self):
        return ['Vilas2020']
 def __init__(self, **args):
     ProtAnalysis3D.__init__(self, **args)
     self.min_res_init = Float() 
     self.max_res_init = Float()
Пример #26
0
    def testMergeDifferentAttrs(self):
        """ Test merge from subsets with different attritubes.
        That is, M1(a,b,c) U M2(a,b,c,d)"""

        #create two set of particles
        inFileNameMetadata1 = self.proj.getTmpPath('particles11.sqlite')
        inFileNameMetadata2 = self.proj.getTmpPath('particles22.sqlite')
        imgSet1 = SetOfParticles(filename=inFileNameMetadata1)
        imgSet2 = SetOfParticles(filename=inFileNameMetadata2)

        inFileNameData = self.proj.getTmpPath('particles.stk')
        img1 = Particle()
        img2 = Particle()
        attrb1 = [11, 12, 13, 14]
        attrb2 = [21, 22, 23, 24]
        attrb3 = [31, 32]
        counter = 0
        for i in range(1, 3):
            img1.cleanObjId()
            img1.setLocation(i, inFileNameData)
            img1.setMicId(i % 3)
            img1.setClassId(i % 5)
            img1.setSamplingRate(1.)
            img1._attrb1 = Float(attrb1[counter])
            img1._attrb2 = Float(attrb2[counter])
            img1._attrb3 = Float(attrb3[counter])
            imgSet1.append(img1)
            counter += 1

        for i in range(1, 3):
            img2.cleanObjId()
            img2.setLocation(i, inFileNameData)
            img2.setClassId(i % 5)
            img2.setMicId(i % 3)
            img2.setSamplingRate(2.)
            img2._attrb1 = Float(attrb1[counter])
            img2._attrb2 = Float(attrb2[counter])
            imgSet2.append(img2)
            counter += 1

        imgSet1.write()
        imgSet2.write()

        #import them
        protImport1 = self.newProtocol(
            ProtImportParticles,
            objLabel='import set1',
            importFrom=ProtImportParticles.IMPORT_FROM_SCIPION,
            sqliteFile=inFileNameMetadata1,
            magnification=10000,
            samplingRate=7.08,
            haveDataBeenPhaseFlipped=True)
        self.launchProtocol(protImport1)

        protImport2 = self.newProtocol(
            ProtImportParticles,
            objLabel='import set2',
            importFrom=ProtImportParticles.IMPORT_FROM_SCIPION,
            sqliteFile=inFileNameMetadata2,
            magnification=10000,
            samplingRate=7.08,
            haveDataBeenPhaseFlipped=True)
        self.launchProtocol(protImport2)

        #create merge protocol
        p_union = self.newProtocol(ProtUnionSet,
                                   objLabel='join diff column order',
                                   ignoreExtraAttributes=True)
        p_union.inputSets.append(protImport1.outputParticles)
        p_union.inputSets.append(protImport2.outputParticles)
        self.proj.launchProtocol(p_union, wait=True)
        #assert
        counter = 0
        for img in p_union.outputSet:
            self.assertAlmostEqual(attrb1[counter], img._attrb1, 4)
            self.assertAlmostEqual(attrb2[counter], img._attrb2, 4)
            if hasattr(img, '_attrb3'):
                self.assertTrue(False, "join should not have attrb3")
            if not hasattr(img, '_attrb2'):
                self.assertTrue(False, "join should have attrb2")
            counter += 1