Source code for xmipp3.protocols.protocol_preprocess.protocol_preprocess

# ******************************************************************************
# *
# * Authors:     Jose Gutierrez (jose.gutierrez@cnb.csic.es)
# *              Josue Gomez Blanco (josue.gomez-blanco@mcgill.ca)
# *
# * Unidad de  Bioinformatica of Centro Nacional de Biotecnologia , CSIC
# *
# * This program is free software; you can redistribute it and/or modify
# * it under the terms of the GNU General Public License as published by
# * the Free Software Foundation; either version 2 of the License, or
# * (at your option) any later version.
# *
# * This program is distributed in the hope that it will be useful,
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# * GNU General Public License for more details.
# *
# * You should have received a copy of the GNU General Public License
# * along with this program; if not, write to the Free Software
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# * 02111-1307  USA
# *
# *  All comments concerning this program package may be sent to the
# *  e-mail address 'scipion@cnb.csic.es'
# *
# ******************************************************************************

import os
from pyworkflow.utils import *
from pyworkflow.protocol.params import *
from pyworkflow.utils.path import cleanPath

from pwem.objects import Volume, SetOfParticles, SetOfClasses2D

from pwem import emlib
from xmipp3.constants import *
from xmipp3.convert import  writeSetOfParticles
from xmipp3.base import isXmippCudaPresent
from .protocol_process import XmippProcessParticles,\
    XmippProcessVolumes


[docs]class XmippPreprocessHelper: """ Helper class that contains some Protocol utilities methods used by both XmippProtPreprocessParticles and XmippProtPreprocessVolumes. """ #--------------------------- DEFINE param functions ------------------------ @classmethod def _defineProcessParams(cls, form): form.addHidden(USE_GPU, BooleanParam, default=True, label="Use GPU for execution", help="This protocol has both CPU and GPU implementation.\ Select the one you want to use.") form.addHidden(GPU_LIST, StringParam, default='0', expertLevel=LEVEL_ADVANCED, label="Choose GPU IDs", help="Add a list of GPU devices that can be used") # Invert Contrast form.addParam('doInvert', BooleanParam, default=False, label='Invert contrast', help='Invert the contrast if your particles are black over' 'a white background.') # Threshold form.addParam('doThreshold', BooleanParam, default=False, label="Threshold", help='Remove voxels below a certain value.') form.addParam('thresholdType', EnumParam, condition='doThreshold', choices=['abs_below', 'below', 'above'], default=MASK_FILL_VALUE, label="Fill with ", display=EnumParam.DISPLAY_COMBO, help='Select how are you going to fill the pixel values' 'outside the mask.') form.addParam('threshold', FloatParam, default=0, label="Threshold value", condition='doThreshold', help='Grey value below which all voxels should be set to 0.') form.addParam('fillType', EnumParam, condition='doThreshold', choices=['value', 'binarize', 'avg'], default=FILL_VALUE, label="Substitute by", display=EnumParam.DISPLAY_COMBO, help='If you select: value: Selected are substitute by a desired value.' ' binarize: Selected are set to 0, non-selected to 1.' ' avg: Average of non-selected.') form.addParam('fillValue', IntParam, default=0, condition='doThreshold and fillType == %d' % FILL_VALUE, help=' Substitute selected pixels by this value.', label='Fill value') #--------------------------- INSERT steps functions ------------------------ @classmethod def _insertCommonSteps(cls, protocol, changeInserts): if protocol.doInvert: args = protocol._argsInvert() protocol._insertFunctionStep("invertStep", args, changeInserts) if protocol.doThreshold: args = protocol._argsThreshold() protocol._insertFunctionStep("thresholdStep", args, changeInserts) #--------------------------- UTILS functions ------------------------------- @classmethod def _argsCommonInvert(cls): args = ' --mult -1' return args @classmethod def _argsCommonThreshold(cls, protocol): args = " --select %s %f" % (protocol.getEnumText('thresholdType'), protocol.threshold) fillStr = protocol.getEnumText('fillType') args += " --substitute %s " % fillStr if protocol.fillType == MASK_FILL_VALUE: args += " %f" % protocol.fillValue return args
[docs]class XmippProtPreprocessParticles(XmippProcessParticles): """ Preprocess a set of particles. You can remove dust, normalize, apply threshold, etc """ _label = 'preprocess particles' # Normalization enum constants NORM_OLD = 0 NORM_NEW = 1 NORM_RAMP =2 def __init__(self, **kwargs): XmippProcessParticles.__init__(self, **kwargs) #--------------------------- DEFINE param functions ------------------------ def _defineProcessParams(self, form): form.addParam('doRemoveDust', BooleanParam, default=False, label='Dust removal', help='Sets pixels with unusually large values to' 'random values from a Gaussian ' 'with zero-mean and unity-standard deviation.') form.addParam('thresholdDust', FloatParam, default=3.5, condition='doRemoveDust', expertLevel=LEVEL_ADVANCED, label='Threshold for dust removal', help='Pixels with a signal higher or lower than' 'this value times the standard deviation of the image' 'will be affected. For cryo, 3.5 is a good value.' 'For high-contrast negative stain, the signal itself' 'may be affected so that a higher value may be preferable.') form.addParam('doRandomize', BooleanParam, default=False, label="Randomize phases", help='Randomize phases beyond a certain frequency.') form.addParam('maxResolutionRandomize', FloatParam, default=40, label="Maximum Resolution", condition='doRandomize', help='Angstroms.') form.addParam('doNormalize', BooleanParam, default=False, label='Normalize', help='It subtract a ramp in the gray values and normalizes' 'so that in the background there is 0 mean and' 'standard deviation 1.') form.addParam('normType', EnumParam, condition='doNormalize', label='Normalization type', expertLevel=LEVEL_ADVANCED, choices=['OldXmipp','NewXmipp','Ramp'], default=self.NORM_RAMP,display=EnumParam.DISPLAY_COMBO, help='OldXmipp: mean(Image)=0, stddev(Image)=1\n' 'NewXmipp: mean(background)=0, stddev(background)=1\n' 'Ramp: subtract background + NewXmipp') form.addParam('backRadius', IntParam, default=-1, condition='doNormalize', label='Background radius', expertLevel=LEVEL_ADVANCED, help='Pixels outside this circle are assumed to be noise and' 'their stddev is set to 1. Radius for background' 'circle definition (in pix.).' 'If this value is 0, then half the box size is used.') form.addParam('doCenter', BooleanParam, default=False, label='Center images') form.addParam('doPhaseFlip', BooleanParam, default=False, label='Phase flip images') XmippPreprocessHelper._defineProcessParams(form) #--------------------------- INSERT steps functions ------------------------ def _insertProcessStep(self): self.isFirstStep = True # this is for when the options selected has changed and the protocol is resumed changeInserts = [self.doRemoveDust.get(), self.doNormalize.get(), self.doInvert.get(), self.doThreshold.get(), self.doCenter.get(), self.doPhaseFlip.get()] if self.doRemoveDust: args = self._argsRemoveDust() self._insertFunctionStep("removeDustStep", args, changeInserts) if self.doRandomize: args = self._argsRandomize() self._insertFunctionStep("randomizeStep", args, changeInserts) if self.doNormalize: args = self._argsNormalize() self._insertFunctionStep("normalizeStep", args, changeInserts) if self.doCenter: args = self._argsCenter() self._insertFunctionStep("centerStep", args, changeInserts) if self.doPhaseFlip: args = self._argsPhaseFlip() self._insertFunctionStep("phaseFlipStep", args, changeInserts) XmippPreprocessHelper._insertCommonSteps(self, changeInserts) #--------------------------- STEPS functions -------------------------------
[docs] def invertStep(self, args, changeInserts): self.runJob('xmipp_image_operate', args)
[docs] def randomizeStep(self, args, changeInserts): self.runJob("xmipp_transform_randomize_phases", args)
[docs] def thresholdStep(self, args, changeInserts): self.runJob("xmipp_transform_threshold", args)
[docs] def removeDustStep(self, args, changeInserts): self.runJob('xmipp_transform_filter', args)
[docs] def normalizeStep(self, args, changeInserts): self.runJob("xmipp_transform_normalize", args)
[docs] def centerStep(self, args, changeInserts): self.runJob("xmipp_transform_center_image", args % locals())
[docs] def phaseFlipStep(self, args, changeInserts): self.runJob("xmipp_ctf_correct_phase", args % locals())
[docs] def sortImages(self, outputFn, outputMd): pass
#--------------------------- INFO functions -------------------------------- def _validate(self): validateMsgs = [] if self.doNormalize.get() and self.normType.get() != 0: size = self._getSize() if self.backRadius.get() > size: validateMsgs.append('Set a valid Background radius less than %d' % size) return validateMsgs def _summary(self): summary = [] summary.append("Input particles: %s" % self.inputParticles.get().getFileName()) if not hasattr(self, 'outputParticles'): summary.append("Output particles not ready yet.") else: summary.append("Dust removal: %s" % self.doRemoveDust) summary.append("Normalize the background: %s" % self.doNormalize) summary.append("Invert contrast: %s" % self.doInvert) summary.append("Remove voxels with threshold: %s" %self.doThreshold) return summary def _methods(self): methods = [] if hasattr(self, 'outputParticles'): methods.append("Input particles %s of %s elements" % (self.getObjectTag('inputParticles'), self.inputParticles.get().getSize())) if self.doNormalize: methods.append("The background was normalized with %s method." % self.getEnumText('normType')) if self.doInvert: methods.append("The contrast was inverted") if self.doThreshold: methods.append("Pixels with values below %f was removed" % self.threshold.get()) methods.append('Output set: %s'%self.getObjectTag('outputParticles')) return methods #--------------------------- UTILS functions ------------------------------- def _argsRemoveDust(self): if self.isFirstStep: args = "-i %s -o %s --save_metadata_stack %s --keep_input_columns" \ % (self.inputFn, self.outputStk, self.outputMd) self._setFalseFirstStep() else: args = "-i %s" % self.outputStk args += " --bad_pixels outliers %f" % self.thresholdDust.get() return args def _argsRandomize(self): if self.isFirstStep: args = "-i %s -o %s --save_metadata_stack %s --keep_input_columns" \ % (self.inputFn, self.outputStk, self.outputMd) self._setFalseFirstStep() else: args = "-i %s" % self.outputStk samplingRate = self.inputParticles.get().getSamplingRate() args+= " --freq continuous %f %f"%(float(self.maxResolutionRandomize.get()),samplingRate) return args def _argsNormalize(self): if self.isFirstStep: args = "-i %s -o %s --save_metadata_stack %s --keep_input_columns" \ % (self.inputFn, self.outputStk, self.outputMd) self._setFalseFirstStep() else: args = "-i %s" % self.outputStk normType = self.normType.get() bgRadius = self.backRadius.get() radii = self._getSize() if bgRadius <= 0: bgRadius = int(radii) if normType == self.NORM_OLD: args += " --method OldXmipp" elif normType == self.NORM_NEW: args += " --method NewXmipp --background circle %d" % bgRadius else: args += " --method Ramp --background circle %d" % bgRadius return args def _argsInvert(self): if self.isFirstStep: args = "-i %s -o %s --save_metadata_stack %s --keep_input_columns" \ % (self.inputFn, self.outputStk, self.outputMd) self._setFalseFirstStep() else: args = "-i %s" % self.outputStk args += XmippPreprocessHelper._argsCommonInvert() return args def _argsThreshold(self): if self.isFirstStep: args = "-i %s -o %s --save_metadata_stack %s --keep_input_columns" \ % (self.inputFn, self.outputStk, self.outputMd) self._setFalseFirstStep() else: args = "-i %s" % self.outputStk args += XmippPreprocessHelper._argsCommonThreshold(self) return args def _argsCenter(self): if self.isFirstStep: args = "-i %s -o %s --save_metadata_stack %s" \ % (self.inputFn, self.outputStk, self.outputMd) self._setFalseFirstStep() else: args = "-i %s" % self.outputStk return args def _argsPhaseFlip(self): if self.isFirstStep: args = "-i %s -o %s --save_metadata_stack %s" \ % (self.inputFn, self.outputStk, self.outputMd) self._setFalseFirstStep() else: args = "-i %s" % self.outputMd args+=" --sampling_rate %f"%self.inputParticles.get().getSamplingRate() return args def _getSize(self): """ get the size of SetOfParticles object""" Xdim = self.inputParticles.get().getDimensions()[0] size = int(Xdim/2) return size def _setFalseFirstStep(self): if self.isFirstStep: self.isFirstStep = False def _postprocessOutput(self, outputSet): if self.doPhaseFlip.get(): outputSet.setIsPhaseFlipped(not self.inputParticles.get().isPhaseFlipped())
[docs]class XmippProtPreprocessVolumes(XmippProcessVolumes): """ Protocol for Xmipp-based preprocess for volumes """ _label = 'preprocess volumes' # Aggregation constants AGG_AVERAGE=0 AGG_SUM=1 # Segmentation type SEG_VOXEL=0 SEG_AMIN=1 SEG_DALTON=2 SEG_AUTO=3 def __init__(self, **kwargs): XmippProcessVolumes.__init__(self, **kwargs) #--------------------------- DEFINE param functions ------------------------ def _defineProcessParams(self, form): # Change hand form.addParam('doChangeHand', BooleanParam, default=False, label="Change hand", help='Change hand by applying a mirror along X.') # Change from one icosahedral standard orientation to another form.addParam('doRotateIco', BooleanParam, default=False, label="Change icosahedral orientation", help='Change from one icosahedral standard orientation to another.') form.addParam('rotateFromIco', EnumParam, choices=['i1','i2','i3','i4'], display=EnumParam.DISPLAY_COMBO, default=0, label='from', condition='doRotateIco', help='See [[http://xmipp.cnb.csic.es/twiki/bin/view/Xmipp/Symmetry][Symmetry]] ' 'for a description of the symmetry groups format.') form.addParam('rotateToIco', EnumParam, choices=['i1','i2','i3','i4'], label='to', default=1, display=EnumParam.DISPLAY_COMBO, condition='doRotateIco') # Randomize the phases form.addParam('doRandomize', BooleanParam, default=False, label="Randomize phases", help='Randomize phases beyond a certain frequency.') # ToDo: add wizard form.addParam('maxResolutionRandomize', FloatParam, default=40, label="Maximum Resolution", condition='doRandomize', help='Angstroms.') # Symmetrization form.addParam('doSymmetrize', BooleanParam, default=False, label="Symmetrize", help='Symmetrize the input model.') form.addParam('symmetryGroup', TextParam, default='i1', label="Symmetry group", condition='doSymmetrize', help='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, set the Symmetrize field to not.') form.addParam('aggregation', EnumParam, choices=['Average', 'Sum'], display=EnumParam.DISPLAY_COMBO, condition = 'doSymmetrize', default=0, label='Aggregation mode', help='Symmetrized volumes can be averaged or summed.') form.addParam('doWrap', BooleanParam, default=True, label="Wrap", condition='doSymmetrize', help='by default, the image/volume is wrapped') # Filtering form.addParam('doLaplacian', BooleanParam, default=False, help="Laplacian denoising", label="Apply Laplacian") form.addParam('volumeMask', PointerParam, pointerClass='VolumeMask', label='Mask volume', condition='doSymmetrize or doLaplacian', allowsNull=True) # Adjust gray values form.addParam('doAdjust', BooleanParam, default=False, label="Adjust gray values", help='Adjust input gray values so that it is compatible' 'with a set of projections.') form.addParam('inputImages', PointerParam, pointerClass='SetOfParticles, SetOfAverages, SetOfClasses2D', label="Set of particles", condition='doAdjust', help='Set of images to which the model should conform.' 'The set of images should have the final pixel size' 'and the final size of the model.') form.addParam('sigSymGroup', TextParam, default='c1', label="Symmetry group", condition='doAdjust', help='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.') # Segment form.addParam('doSegment', BooleanParam, default=False, label="Segment", help='Separate the molecule from its background.') form.addParam('segmentationType', EnumParam, condition='doSegment', choices=['Voxel mass', 'Aminoacid mass','Dalton mass','Automatic'], default=3, display=EnumParam.DISPLAY_COMBO, label="Segmentation Type", help='Type of segmentation.') form.addParam('segmentationMass', FloatParam, label="Molecule Mass", default=-1, condition='doSegment and segmentationType != 3', help='In automatic segmentation, set it to -1.') # Normalize background form.addParam('doNormalize', BooleanParam, default=False, label="Normalize background", help='Set background to have zero mean and standard deviation 1.') form.addParam('backRadius', FloatParam, default=-1, label="Mask Radius", condition='doNormalize', help='In pixels. Set to -1 for half of the size of the volume.') XmippPreprocessHelper._defineProcessParams(form) #--------------------------- INSERT steps functions ------------------------ def _insertProcessStep(self): self.isFirstStep = True # this is for when the options selected has changed and the protocol is resumed changeInserts = [self.doChangeHand, self.doRotateIco, self.doRandomize, self.doSymmetrize, self.doLaplacian, self.doAdjust, self.doSegment, self.doInvert, self.doNormalize, self.doThreshold] if self.doChangeHand: args = self._argsChangeHand() self._insertFunctionStep("changeHandStep", args, changeInserts) if self.doRotateIco: args = self._argsRotateIco() self._insertFunctionStep("rotateIcoStep", args, changeInserts) if self.doRandomize: args = self._argsRandomize() self._insertFunctionStep("randomizeStep", args, changeInserts) if self.doSymmetrize: args = self._argsSymmetrize() self._insertFunctionStep("symmetrizeStep", args, changeInserts) if self.doLaplacian: args = self._argsLaplacian() self._insertFunctionStep("laplacianStep", args, changeInserts) if self.doAdjust: self._insertFunctionStep("projectionStep", changeInserts) self._insertFunctionStep("adjustStep",self.isFirstStep,changeInserts) if self.isFirstStep: self.isFirstStep = False if self.doSegment: args = self._argsSegment() self._insertFunctionStep("segmentStep", args, changeInserts) if self.isFirstStep: self.isFirstStep = False if self.doNormalize: args = self._argsNormalize() self._insertFunctionStep("normalizeStep", args, changeInserts) XmippPreprocessHelper._insertCommonSteps(self, changeInserts) #--------------------------- STEPS functions -------------------------------
[docs] def invertStep(self, args, changeInserts): self.runJob('xmipp_image_operate', args)
[docs] def thresholdStep(self, args, changeInserts): self.runJob("xmipp_transform_threshold", args)
[docs] def removeDustStep(self, args, changeInserts): self.runJob('xmipp_transform_filter', args)
[docs] def normalizeStep(self, args, changeInserts): self.runJob("xmipp_transform_normalize", args)
[docs] def changeHandStep(self, args, changeInserts): self.runJob("xmipp_transform_mirror", args)
[docs] def rotateIcoStep(self, args, changeInserts): self.runJob("xmipp_transform_geometry", args)
[docs] def randomizeStep(self, args, changeInserts): self.runJob("xmipp_transform_randomize_phases", args)
[docs] def symmetrizeStep(self, args, changeInserts): self.runJob("xmipp_transform_symmetrize", args)
[docs] def laplacianStep(self, args, changeInserts): self.runJob("xmipp_transform_filter", args, numberOfMpi=1)
[docs] def projectionStep(self, changeInserts): partSet = self.inputImages.get() imgsFn = self._getTmpPath('input_images.xmd') if partSet.getSize() > 200: newPartSet = self._getRandomSubset(partSet, 200) else: newPartSet = partSet writeSetOfParticles(newPartSet, imgsFn) if not partSet.hasAlignmentProj(): if not self.useGpu.get(): params = {'imgsFn': imgsFn, 'dir': self._getTmpPath(), 'vols': self.inputFn, 'symmetryGroup': self.sigSymGroup.get(), } sigArgs = '-i %(imgsFn)s --initvolumes %(vols)s --odir %(dir)s' \ ' --sym %(symmetryGroup)s --alpha0 0.005 --dontReconstruct ' \ % params self.runJob("xmipp_reconstruct_significant", sigArgs) else: fnGallery = self._getExtraPath('gallery.stk') fnGalleryMd = self._getExtraPath('gallery.doc') angleStep = 5 args = "-i %s -o %s --sampling_rate %f --sym %s --min_tilt_angle 0 --max_tilt_angle 180 " % \ (self.inputFn, fnGallery, angleStep, self.sigSymGroup.get()) self.runJob("xmipp_angular_project_library", args, numberOfMpi=min(self.numberOfMpi.get(), 24)) count=0 GpuListCuda='' if self.useQueueForSteps() or self.useQueue(): GpuList = os.environ["CUDA_VISIBLE_DEVICES"] GpuList = GpuList.split(",") for elem in GpuList: GpuListCuda = GpuListCuda+str(count)+' ' count+=1 else: GpuListAux = '' for elem in self.getGpuList(): GpuListCuda = GpuListCuda+str(count)+' ' GpuListAux = GpuListAux+str(elem)+',' count+=1 os.environ["CUDA_VISIBLE_DEVICES"] = GpuListAux fnAngles = 'images_iter001_00.xmd' args = '-i %s -r %s -o %s --odir %s --keepBestN 1 --dev %s ' % ( imgsFn, fnGalleryMd, fnAngles, self._getTmpPath(), GpuListCuda) self.runJob(CUDA_ALIGN_SIGNIFICANT, args, numberOfMpi=1)
[docs] def adjustStep(self, isFirstStep, changeInserts): if isFirstStep: inputFn = self.inputFn else: if self._isSingleInput(): inputFn = self.outputStk else: inputFn = self.outputMd if self._isSingleInput(): args = self._argsAdjust(0) localArgs = self._adjustLocalArgs(inputFn, self.outputStk, args) self.runJob("xmipp_transform_adjust_volume_grey_levels", localArgs) else: volMd = emlib.MetaData(self.inputFn) outVolMd = emlib.MetaData(self.outputMd) for objId in volMd: args = self._argsAdjust(objId-1) inputVol = volMd.getValue(emlib.MDL_IMAGE, objId) outputVol = outVolMd.getValue(emlib.MDL_IMAGE, objId) localArgs = self._adjustLocalArgs(inputVol, outputVol, args) self.runJob("xmipp_transform_adjust_volume_grey_levels", localArgs)
[docs] def segmentStep(self, args, changeInserts): fnMask = self._getTmpPath("mask.vol") if self.isFirstStep: inputFn = self.inputFn else: if self._isSingleInput(): inputFn = self.outputStk else: inputFn = self.outputMd if self._isSingleInput(): localArgs = self._segmentLocalArgs(inputFn, fnMask, args) maskArgs = self._segMentMaskArgs(inputFn, self.outputStk, fnMask) self._segmentVolume(localArgs, maskArgs, fnMask) else: volMd = emlib.MetaData(inputFn) outVolMd = emlib.MetaData(self.outputMd) for objId in volMd: inputVol = volMd.getValue(emlib.MDL_IMAGE, objId) outputVol = outVolMd.getValue(emlib.MDL_IMAGE, objId) localArgs = self._segmentLocalArgs(inputVol, fnMask, args) maskArgs = self._segMentMaskArgs(inputVol, outputVol, fnMask) self._segmentVolume(localArgs, maskArgs, fnMask)
def _segmentVolume(self, localArgs, maskArgs, fnMask): self.runJob("xmipp_volume_segment", localArgs) if exists(fnMask): self.runJob("xmipp_transform_mask", maskArgs) cleanPath(fnMask) #--------------------------- INFO functions -------------------------------- def _argsChangeHand(self): if self.isFirstStep: if self._isSingleInput(): args = "-i %s -o %s" % (self.inputFn, self.outputStk) else: args = "-i %s -o %s --save_metadata_stack %s --keep_input_columns" \ % (self.inputFn, self.outputStk, self.outputMd) self._setFalseFirstStep() else: args = "-i %s" % self.outputStk args += " --flipX" return args def _argsRotateIco(self): if self.isFirstStep: if self._isSingleInput(): args = "-i %s -o %s" % (self.inputFn, self.outputStk) else: args = "-i %s -o %s --save_metadata_stack %s --keep_input_columns" \ % (self.inputFn, self.outputStk, self.outputMd) self._setFalseFirstStep() else: args = "-i %s" % self.outputStk args += " --rotate_volume icosahedral i%d i%s --dont_wrap" \ % (self.rotateFromIco.get()+1, self.rotateToIco.get()+1) return args def _argsRandomize(self): if self.isFirstStep: if self._isSingleInput(): args = "-i %s -o %s" % (self.inputFn, self.outputStk) else: args = "-i %s -o %s --save_metadata_stack %s --keep_input_columns" \ % (self.inputFn, self.outputStk, self.outputMd) self._setFalseFirstStep() else: args = "-i %s" % self.outputStk samplingRate = self.inputVolumes.get().getSamplingRate() resol = self.maxResolutionRandomize.get() args += " --freq continuous %f %f" % (float(resol),samplingRate) return args def _argsSymmetrize(self): if self.isFirstStep: if self._isSingleInput(): args = "-i %s -o %s" % (self.inputFn, self.outputStk) else: args = "-i %s -o %s --save_metadata_stack %s --keep_input_columns" \ % (self.inputFn, self.outputStk, self.outputMd) self._setFalseFirstStep() else: args = "-i %s" % self.outputStk symmetry = self.symmetryGroup.get() doWrap = self.doWrap.get() if self.volumeMask.get() is not None: fnVolumeMask = self.volumeMask.get().getFileName() doVolumeMask = True else: doVolumeMask = False ###########FILEFILEFILE symmetryAggregation = self.aggregation.get() # Validation done in the _validate function # if symmetry != 'c1': args += " --sym %s " % symmetry if symmetryAggregation == "sum": args += " --sum" if not doWrap: args += " --dont_wrap " if doVolumeMask: if exists(fnVolumeMask): args += " --mask_in %s "%fnVolumeMask else: print('Error: mask %s does not exists'%fnVolumeMask) return args def _argsLaplacian(self): args = "" if self._isSingleInput(): args = "-i %s -o %s --retinex %f" \ % (self.inputFn, self.outputStk, 0.9) if self.volumeMask.get() is not None: fnVolumeMask = self.volumeMask.get().getFileName() if exists(fnVolumeMask): args += " %s"%fnVolumeMask return args def _argsAdjust(self, number): if self.inputImages.get().hasAlignmentProj(): fn = "input_images.xmd" else: fn = "images_iter001_%02d.xmd" % number args = " -m %s" % self._getTmpPath(fn) return args def _adjustLocalArgs(self, inputVol, outputVol, args): localArgs = "-i %s -o %s" % (inputVol, outputVol) + args return localArgs def _argsSegment(self): segmentationType = self.segmentationType.get() segmentationMass = self.segmentationMass.get() ts = self._getSize() args = " --method " if segmentationType == "Voxel mass": args += "voxel_mass %d" % (int(segmentationMass)) elif segmentationType == "Aminoacid mass": args += "aa_mass %d %f" % (int(segmentationMass),float(ts)) elif segmentationType == "Dalton mass": args += "dalton_mass %d %f" % (int(segmentationMass),float(ts)) else: args += "otsu" return args def _segmentLocalArgs(self, inputVol, fnMask, args): return "-i %s -o %s " % (inputVol, fnMask) + args def _segMentMaskArgs(self, inputVol, outputVol, fnMask): print("self.isFirstStep, ", self.isFirstStep) if self.isFirstStep: maskArgs = "-i %s -o %s" % (inputVol, outputVol) self._setFalseFirstStep() else: maskArgs = "-i %s" % outputVol maskArgs += " --mask binary_file %s" % fnMask return maskArgs def _argsNormalize(self): if self.isFirstStep: if self._isSingleInput(): args = "-i %s -o %s" % (self.inputFn, self.outputStk) else: args = "-i %s -o %s --save_metadata_stack %s --keep_input_columns" \ % (self.inputFn, self.outputStk, self.outputMd) self._setFalseFirstStep() else: args = "-i %s" % self.outputStk maskRadius = self.backRadius.get() if maskRadius <= 0: size = self._getSize() maskRadius = size/2 args += " --method NewXmipp --background circle %d" % int(maskRadius) return args def _argsInvert(self): if self.isFirstStep: if self._isSingleInput(): args = "-i %s -o %s" % (self.inputFn, self.outputStk) else: args = "-i %s -o %s --save_metadata_stack %s --keep_input_columns" \ % (self.inputFn, self.outputStk, self.outputMd) self._setFalseFirstStep() else: args = "-i %s" % self.outputStk args += XmippPreprocessHelper._argsCommonInvert() return args def _argsThreshold(self): if self.isFirstStep: if self._isSingleInput(): args = "-i %s -o %s" % (self.inputFn, self.outputStk) else: args = "-i %s -o %s --save_metadata_stack %s --keep_input_columns" \ % (self.inputFn, self.outputStk, self.outputMd) else: args = "-i %s" % self.outputStk args += XmippPreprocessHelper._argsCommonThreshold(self) return args def _validate(self): validateMsgs = [] if not self.inputVolumes.hasValue(): validateMsgs.append('Please provide an initial volume(s).') if self.doNormalize.get(): size = int(self._getSize()/2) if self.backRadius.get() > size: validateMsgs.append('Set a valid Background radius less than %d' % size) if self.doSymmetrize.get(): if self.symmetryGroup.get() == 'c1': validateMsgs.append('c1 is not a valid symmetry group.' 'If you do not want to symmetrize set' 'the field Symmetrize to not.') if self.useGpu and not isXmippCudaPresent(CUDA_ALIGN_SIGNIFICANT): validateMsgs.append("You asked to use GPU, but I cannot find Xmipp cuda programs in the path") return validateMsgs def _summary(self): summary = [] if self.inputVolumes.get() is None: return summary summary.append("Input volumes: %s"%self.inputVolumes.get().getNameId()) if not hasattr(self, 'outputVol'): summary.append("Output volumes not ready yet.") else: summary.append("Output volumes: %s" % self.outputVol) return summary def _methods(self): return self._summary() #--------------------------- UTILS functions ------------------------------- def _getSize(self): """ get the size of either Volume or SetOfVolumes object""" if isinstance(self.inputVolumes.get(), Volume): Xdim = self.inputVolumes.get().getDim()[0] else: Xdim = self.inputVolumes.get().getDimensions()[0] return Xdim def _setFalseFirstStep(self): if self.isFirstStep: self.isFirstStep = False def _getRandomSubset(self, imgSet, numOfParts): if isinstance(imgSet, SetOfClasses2D): partSet = self._createSetOfParticles("_averages") for i, cls in enumerate(imgSet): img = cls.getRepresentative() img.setSamplingRate(cls.getSamplingRate()) img.setObjId(i+1) partSet.append(img) else: partSet = imgSet if partSet.getSize() > numOfParts: newPartSet = SetOfParticles(filename=self._getTmpPath("particles_tmp.sqlite")) counter = 0 for part in partSet.iterItems(orderBy='RANDOM()', direction='ASC'): if counter < numOfParts: newPartSet.append(part) counter += 1 else: break else: newPartSet = partSet return newPartSet