def _defineAlignmentParams(self, form): ProtAlignMovies._defineAlignmentParams(self, form) form.addParam('splineOrder', params.EnumParam, condition="doSaveAveMic or doSaveMovie", default=self.INTERP_CUBIC, choices=['linear', 'cubic'], expertLevel=cons.LEVEL_ADVANCED, label='Interpolation', help="linear (faster but lower quality), " "cubic (slower but more accurate).") form.addParam('maxFreq', params.FloatParam, default=4, label='Filter at (A)', help="For the calculation of the shifts with Xmipp, " "micrographs are filtered (and downsized " "accordingly) to this resolution. Then shifts are " "calculated, and they are applied to the original " "frames without any filtering and downsampling.") form.addParam('doComputePSD', params.BooleanParam, default=True, label="Compute PSD (before/after)?", help="If Yes, the protocol will compute for each movie " "the PSD of the average micrograph (without CC " "alignement) and after that, to compare each PSDs") form.addParam('maxShift', params.IntParam, default=30, expertLevel=cons.LEVEL_ADVANCED, label="Maximum shift (pixels)", help='Maximum allowed distance (in pixels) that each ' 'frame can be shifted with respect to the next.') form.addParam('outsideMode', params.EnumParam, choices=['Wrapping', 'Average', 'Value'], default=self.OUTSIDE_WRAP, expertLevel=cons.LEVEL_ADVANCED, label="How to fill borders", help='How to fill the borders when shifting the frames') form.addParam('outsideValue', params.FloatParam, default=0.0, expertLevel=cons.LEVEL_ADVANCED, condition="outsideMode==2", label='Fill value', help="Fixed value for filling borders") form.addParallelSection(threads=1, mpi=1)
def _validate(self): errors = ProtAlignMovies._validate(self) # Although getFirstItem is not recommended in general, here it is # used only once, for validation purposes, so performance # problems not should be appear. if not self.inputMovies.get() is None: inputSet = self.inputMovies.get() movie = inputSet.getFirstItem() if (not movie.hasAlignment()) and self.useAlignment: errors.append( "Your movies have no alignment. Please, set *No* " "the parameter _Use previous movie alignment to SUM" " frames?_") if self.doApplyDoseFilter: doseFrame = inputSet.getAcquisition().getDosePerFrame() if doseFrame == 0.0 or doseFrame is None: errors.append( 'Dose per frame for input movies is 0 or not ' 'set. You cannot apply dose filter.') if self.numberOfThreads > 1 and self.useGpu: errors.append("GPU and Parallelization can not be used together") return errors
def _validate(self): errors = ProtAlignMovies._validate(self) # Although getFirstItem is not recommended in general, here it is # used only once, for validation purposes, so performance # problems not should be appear. if not self.inputMovies.get() is None: inputSet = self.inputMovies.get() movie = inputSet.getFirstItem() if (not movie.hasAlignment()) and self.useAlignment: errors.append("Your movies have no alignment. Please, set *No* " "the parameter _Use previous movie alignment to SUM" " frames?_") if self.doApplyDoseFilter: doseFrame = inputSet.getAcquisition().getDosePerFrame() if doseFrame == 0.0 or doseFrame is None: errors.append('Dose per frame for input movies is 0 or not ' 'set. You cannot apply dose filter.') if self.numberOfThreads > 1 and self.useGpu: errors.append("GPU and Parallelization can not be used together") return errors
def _validate(self): if self.autoControlPoints.get(): self._setControlPoints() # make sure we work with proper values errors = ProtAlignMovies._validate(self) getXmippHome = self.getClassPackage().Plugin.getHome if self.doLocalAlignment.get(): cudaBinaryFn = getXmippHome( 'bin', 'xmipp_cuda_movie_alignment_correlation') if not os.path.isfile(cudaBinaryFn): errors.append('GPU version not found, make sure that Xmipp is ' 'compiled with GPU\n' '( *CUDA=True* in _scipion.conf_ + ' '_run_: $ *scipion installb xmippSrc* ).') return errors elif not self.useGpu.get(): errors.append("GPU is needed to do local alignment.") return errors if self.numberOfMpi.get() * self.numberOfThreads.get() > 1: errors.append( "Multiple threads and/or mpi is incompatible with" " useGPU.") else: cpuBinaryFn = getXmippHome('bin', 'xmipp_movie_alignment_correlation') if not os.path.isfile(cpuBinaryFn): errors.append( 'CPU version not found for some reason, try to GPU=True.') return errors if (self.controlPointX < 3): errors.append("You have to use at least 3 control points in X dim") return errors # to avoid possible division by zero later if (self.controlPointY < 3): errors.append("You have to use at least 3 control points in Y dim") return errors # to avoid possible division by zero later if (self.controlPointT < 3): errors.append("You have to use at least 3 control points in T dim") return errors # to avoid possible division by zero later _, _, frames = self.inputMovies.get().getDim() tPointsRatio = frames / (int(self.controlPointT) - 2) yPointsRatio = int(self.patchY) / (int(self.controlPointY) - 2) xPointsRatio = int(self.patchX) / (int(self.controlPointX) - 2) if (tPointsRatio < 2): errors.append( "You need at least 2 measurements per control point, " "i.e. use movie with more frames or decrease number of control points in T dimension." ) if (yPointsRatio < 2): errors.append( "You need at least 2 measurements per control point, " "i.e. use more patches in Y dimesion or decrease number of control points." ) if (xPointsRatio < 2): errors.append( "You need at least 2 measurements per control point, " "i.e. use more patches in X dimesion or decrease number of control points." ) return errors
def _defineAlignmentParams(self, form): ProtAlignMovies._defineAlignmentParams(self, form) form.addParam('splineOrder', params.EnumParam, condition="doSaveAveMic or doSaveMovie", default=self.INTERP_CUBIC, choices=['linear', 'cubic'], expertLevel=cons.LEVEL_ADVANCED, label='Interpolation', help="linear (faster but lower quality), " "cubic (slower but more accurate).") form.addParam('maxFreq', params.FloatParam, default=4, label='Filter at (A)', help="For the calculation of the shifts with Xmipp, " "micrographs are filtered (and downsized " "accordingly) to this resolution. Then shifts are " "calculated, and they are applied to the original " "frames without any filtering and downsampling.") form.addParam('doComputePSD', params.BooleanParam, default=True, label="Compute PSD (before/after)?", help="If Yes, the protocol will compute for each movie " "the PSD of the average micrograph (without CC " "alignement) and after that, to compare each PSDs") form.addParam('maxShift', params.IntParam, default=30, expertLevel=cons.LEVEL_ADVANCED, label="Maximum shift (pixels)", help='Maximum allowed distance (in pixels) that each ' 'frame can be shifted with respect to the next.') form.addParam('outsideMode', params.EnumParam, choices=['Wrapping','Average','Value'], default=self.OUTSIDE_WRAP, expertLevel=cons.LEVEL_ADVANCED, label="How to fill borders", help='How to fill the borders when shifting the frames') form.addParam('outsideValue', params.FloatParam, default=0.0, expertLevel=cons.LEVEL_ADVANCED, condition="outsideMode==2", label='Fill value', help="Fixed value for filling borders") form.addParallelSection(threads=1, mpi=1)
def _createOutputMovie(self, movie): """ Overwrite this function to store the Relion's specific Motion model coefficients. """ m = ProtAlignMovies._createOutputMovie(self, movie) # Load local motion values only if the patches are more than one if self.patchX.get() * self.patchY.get() > 1: table = md.Table(fileName=self._getMovieExtraFn(movie, '.star'), tableName='local_motion_model') coeffs = [row.rlnMotionModelCoeff for row in table] m._rlnMotionModelCoeff = pwobj.String(json.dumps(coeffs)) return m
def _validate(self): errors = ProtAlignMovies._validate(self) # Although getFirstItem is not recommended in general, here it is # used only once, for validation purposes, so performance # problems not should be appear. if not self.inputMovies.get() is None: inputSet = self.inputMovies.get() movie = inputSet.getFirstItem() if (not movie.hasAlignment()) and self.useAlignment: errors.append("Your movies have no alignment. Please, set *No* " "the parameter _Use previous movie alignment to SUM" " frames?_") if self.doApplyDoseFilter: doseFrame = inputSet.getAcquisition().getDosePerFrame() if doseFrame == 0.0 or doseFrame is None: errors.append('Dose per frame for input movies is 0 or not ' 'set. You cannot apply dose filter.') if self.numberOfThreads > 1 and self.useGpu: errors.append("GPU and Parallelization can not be used together") ofCpu = Plugin.getHome("bin", "xmipp_movie_optical_alignment_cpu") ofGpu = Plugin.getHome("bin", "xmipp_movie_optical_alignment_gpu") if not (exists(ofGpu) or exists(ofCpu)): errors.append("It seems that Xmipp Optical Alignment is not installed. " "OpenCV should be installed in the system to compile it.\n" "Please, install OpenCV in your system and, then, " "re-install Xmipp by running 'scipion installb xmippSrc'.") else: if self.useGpu and not exists(ofGpu): errors.append("It seems that Xmipp Optical Alignment has not been " "compiled with CUDA.\nPlease, try with *GPU=No*.\n" "Error: '%s' not found." % ofGpu) if not self.useGpu and not exists(ofCpu): errors.append("It seems that Xmipp Optical Alignment has been " "compiled with CUDA.\nPlease, try with *GPU=Yes*.\n" "Error: '%s' not found." % ofCpu) return errors
def _validate(self): # Check base validation before the specific ones for Motioncorr errors = ProtAlignMovies._validate(self) program = MOTIONCOR2_PATH if self.useMotioncor2 else MOTIONCORR_PATH if not os.path.exists(program): errors.append('Missing %s' % program) # Check CUDA paths cudaLib = getCudaLib(useMC2=self.useMotioncor2) cudaConst = (MOTIONCOR2_CUDA_LIB if self.useMotioncor2 else MOTIONCORR_CUDA_LIB) if cudaLib is None: errors.append("Do not know where to find CUDA lib path. " " %s or %s variables have None value or are not" " present in scipion configuration." % (cudaConst, CUDA_LIB)) elif not pwutils.existsVariablePaths(cudaLib): errors.append("Either %s or %s variables points to a non existing " "path (%s). Please, check scipion configuration." % (cudaConst, CUDA_LIB, cudaLib)) gpu = self.GPUIDs.get() if not self.useMotioncor2: bin = self.binFactor.get() if not (bin == 1.0 or bin == 2.0): errors.append("Binning factor can only be 1 or 2") if len(gpu) > 1: errors.append("Old motioncorr2.1 does not support multiple " "GPUs, use motioncor2.") else: if not self.doSaveAveMic: errors.append( 'Option not supported. Please select Yes for ' 'Save aligned micrograph. ' 'Optionally you could add -Align 0 to additional ' 'parameters so that protocol ' 'produces simple movie sum.') if self.doSaveMovie and not self._isOutStackSupport: errors.append('Saving aligned movies is not supported by ' 'this version of motioncor2. ' 'By default, the protocol will produce ' 'outputMovies equivalent to the input ' 'however containing alignment information.') if not self.useAlignToSum: errors.append('Frame range for ALIGN and SUM must be ' 'equivalent in case of motioncor2. \n Please, ' 'set *YES* _Use ALIGN frames range to SUM?_ ' 'flag or use motioncorr') if self.doApplyDoseFilter and self.inputMovies.get(): inputMovies = self.inputMovies.get() doseFrame = inputMovies.getAcquisition().getDosePerFrame() if doseFrame == 0.0 or doseFrame is None: errors.append( 'Dose per frame for input movies is 0 or not ' 'set. You cannot apply dose filter.') return errors
def _createOutputMovie(self, movie): alignedMovie = ProtAlignMovies._createOutputMovie(self, movie) self._setAlignmentInfo(movie, alignedMovie) return alignedMovie
def _defineAlignmentParams(self, form): ProtAlignMovies._defineAlignmentParams(self, form) form.addSection("Aditional Parameters") # GROUP GPU PARAMETERS #group = form.addGroup('GPU') form.addHidden( params.USE_GPU, params.BooleanParam, default=False, label="Use GPU (vs CPU)", help="Set to true if you want the GPU implementation of " "Optical Flow") form.addHidden( params.GPU_LIST, params.StringParam, default=0, expertLevel=params.LEVEL_ADVANCED, label="Choose GPU core", 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.") group = form.addGroup('OF Parameters') group.addParam('winSize', params.IntParam, default=150, expertLevel=params.LEVEL_ADVANCED, label="Window size", help="Window size (shifts are assumed to be constant " "within this window).") group.addParam('groupSize', params.IntParam, default=1, expertLevel=params.LEVEL_ADVANCED, label="Group Size", help="The number of frames in each group at the " "last step") group.addParam( 'useAlignment', params.BooleanParam, default=True, label="Use previous movie alignment to SUM frames?", help="Input movies could have alignment information from" "a previous protocol. If you select *Yes*, the " "previous alignment will be taken into account.") group.addParam('doComputePSD', params.BooleanParam, default=True, label="Compute PSD (before/after)?", help="If Yes, the protocol will compute for each movie " "the PSD of the average micrograph (without OF " "alignement) and after that, to compare each PSDs") group.addParam( 'memory', params.BooleanParam, default=False, label="Keep images in RAM ?", help="If True, the protocol will increase the demand of " "RAM, decreasing disc access") group = form.addGroup('Dose Compensation') group.addParam('doApplyDoseFilter', params.BooleanParam, default=False, label='Apply Dose filter', help='Apply a dose-dependent filter to frames before ' 'summing them. Pre-exposure and dose per frame ' 'should be specified during movies import.') group.addParam('doSaveUnweightedMic', params.BooleanParam, default=True, condition='doSaveAveMic and doApplyDoseFilter', label="Save unweighted micrographs?", help="Yes by default, if you have selected to apply a " "dose-dependent filter to the frames") group.addParam('applyDosePreAlign', params.BooleanParam, default=False, condition='doApplyDoseFilter', label="Apply Dose filter before alignment?", help="if *True*, you apply dose filter before perform " "the alignment; else will apply after alignment.") form.addParallelSection(threads=8, mpi=1)
def _defineAlignmentParams(self, form): ProtAlignMovies._defineAlignmentParams(self, form) form.addParam('splineOrder', params.EnumParam, condition="doSaveAveMic or doSaveMovie", default=self.INTERP_CUBIC, choices=['linear', 'cubic'], expertLevel=cons.LEVEL_ADVANCED, label='Interpolation', help="linear (faster but lower quality), " "cubic (slower but more accurate).") form.addHidden( params.USE_GPU, params.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(params.GPU_LIST, params.StringParam, default='0', expertLevel=cons.LEVEL_ADVANCED, label="Choose GPU IDs", help="Add a list of GPU devices that can be used") form.addParam('maxFreq', params.FloatParam, default=4, label='Filter at (A)', help="For the calculation of the shifts with Xmipp, " "micrographs are filtered (and downsized " "accordingly) to this resolution. Then shifts are " "calculated, and they are applied to the original " "frames without any filtering and downsampling.") form.addParam('doComputePSD', params.BooleanParam, default=True, label="Compute PSD (before/after)?", help="If Yes, the protocol will compute for each movie " "the PSD of the average micrograph (without CC " "alignement) and after that, to compare each PSDs") form.addParam('maxShift', params.IntParam, default=30, expertLevel=cons.LEVEL_ADVANCED, label="Maximum shift (pixels)", help='Maximum allowed distance (in pixels) that each ' 'frame can be shifted with respect to the next.') form.addParam('outsideMode', params.EnumParam, choices=['Wrapping', 'Average', 'Value'], default=self.OUTSIDE_WRAP, expertLevel=cons.LEVEL_ADVANCED, label="How to fill borders", help='How to fill the borders when shifting the frames') #Local alignment params group = form.addGroup('Local alignment') group.addParam( 'doLocalAlignment', params.BooleanParam, default=True, label="Compute local alignment?", help= "If Yes, the protocol will try to determine local shifts, similarly to MotionCor2." ) group.addParam( 'autoControlPoints', params.BooleanParam, default=True, label="Auto control points", expertLevel=cons.LEVEL_ADVANCED, condition='doLocalAlignment', help= "If on, protocol will automatically determine necessary number of control points." ) line = group.addLine('Number of control points', expertLevel=cons.LEVEL_ADVANCED, help='Number of control points use for BSpline.', condition='not autoControlPoints') line.addParam('controlPointX', params.IntParam, default=6, label='X') line.addParam('controlPointY', params.IntParam, default=6, label='Y') line.addParam('controlPointT', params.IntParam, default=5, label='t') line = group.addLine( 'Number of patches', expertLevel=cons.LEVEL_ADVANCED, help= 'Number of patches to be used. Depending on the size of the movie, they may \ overlap.', condition='doLocalAlignment') line.addParam('patchX', params.IntParam, default=10, label='X') line.addParam('patchY', params.IntParam, default=10, label='Y') group.addParam( 'groupNFrames', params.IntParam, default=3, expertLevel=cons.LEVEL_ADVANCED, label='Group N frames', help= 'Group every specified number of frames by adding them together. \ The alignment is then performed on the summed frames.', condition='doLocalAlignment') form.addParam('outsideValue', params.FloatParam, default=0.0, expertLevel=cons.LEVEL_ADVANCED, condition="outsideMode==2", label='Fill value', help="Fixed value for filling borders") form.addParallelSection(threads=1, mpi=1)
def _defineAlignmentParams(self, form): form.addParam('gpuMsg', params.LabelParam, default=True, label='WARNING! You need to have installed CUDA' ' libraries and a Nvidia GPU') form.addHidden(params.GPU_LIST, params.StringParam, default='0', expertLevel=cons.LEVEL_ADVANCED, label="Choose GPU IDs", 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." " Motioncor2 can use multiple GPUs - in that case" " set to i.e. *0 1 2*.") ProtAlignMovies._defineAlignmentParams(self, form) form.addParam('doComputePSD', params.BooleanParam, default=False, expertLevel=cons.LEVEL_ADVANCED, label="Compute PSD (before/after)?", help="If Yes, the protocol will compute for each movie " "the average PSD before and after alignment, " "for comparison") form.addParam('doComputeMicThumbnail', params.BooleanParam, expertLevel=cons.LEVEL_ADVANCED, default=False, label='Compute micrograph thumbnail?', help='When using this option, we will compute a ' 'micrograph thumbnail and keep it with the ' 'micrograph object for visualization purposes. ') form.addParam('computeAllFramesAvg', params.BooleanParam, expertLevel=cons.LEVEL_ADVANCED, default=False, label='Compute all frames average?', help='Computing all the frames average could provide a ' 'sanity check about the microscope and the camera.') form.addParam('extraParams', params.StringParam, default='', expertLevel=cons.LEVEL_ADVANCED, label='Additional parameters', help="""Extra parameters for motioncorr (NOT motioncor2)\n -bft 150 BFactor in pix^2. -pbx 96 Box dimension for searching CC peak. -fod 2 Number of frame offset for frame comparison. -nps 0 Radius of noise peak. -sub 0 1: Save as sub-area corrected sum. 0: Not. -srs 0 1: Save uncorrected sum. 0: Not. -scc 0 1: Save CC Map. 0: Not. -slg 1 1: Save Log. 0: Not. -atm 1 1: Align to middle frame. 0: Not. -dsp 1 1: Save quick results. 0: Not. -fsc 0 1: Calculate and log FSC. 0: Not. """) form.addParam('extraProtocolParams', params.StringParam, default='', expertLevel=cons.LEVEL_ADVANCED, label='Additional protocol parameters', help="Here you can provide some extra parameters for the " "protocol, not the underlying motioncor program." "You can provide many options separated by space. " "\n*Options:* \n" "--use_worker_thread \n" " Use an extra thread to compute" " PSD and thumbnail. This will allow a more effective" " use of the GPU card, but requires an extra CPU. ") form.addSection(label="Motioncor2") form.addParam('useMotioncor2', params.BooleanParam, default=True, label='Use motioncor2', help='Use new *motioncor2* program with local ' 'patch-based motion correction and dose weighting.') form.addParam('doApplyDoseFilter', params.BooleanParam, default=True, condition='useMotioncor2', label='Apply Dose filter', help='Apply a dose-dependent filter to frames before ' 'summing them. Pre-exposure and dose per frame ' 'should be specified during movies import.') line = form.addLine('Number of patches', condition='useMotioncor2', help='Number of patches to be used for patch based ' 'alignment. Set to *0 0* to do only global motion ' 'correction. \n') line.addParam('patchX', params.IntParam, default=5, label='X') line.addParam('patchY', params.IntParam, default=5, label='Y') if self.versionGE('1.0.1'): # Patch overlap was introduced in 1.0.1 form.addParam('patchOverlap', params.IntParam, default=0, condition='useMotioncor2', label='Patches Overlap (%)', help='In versions > 1.0.1 it is possible to specify' 'the overlapping between patches. ' '\nFor example, overlap=20 means that ' 'each patch will have a 20% overlapping \n' 'with its neighboring patches in each dimension.') form.addParam('group', params.IntParam, default='1', label='Group N frames', condition='useMotioncor2', help='Group every specified number of frames by adding ' 'them together. The alignment is then performed on ' 'the summed frames. By default, no grouping is ' 'performed.') form.addParam('tol', params.FloatParam, default='0.5', label='Tolerance (px)', condition='useMotioncor2', help='Tolerance for iterative alignment, default *0.5px*.') if self._supportsMagCorrection(): group = form.addGroup('Magnification correction') group.addParam('doMagCor', params.BooleanParam, default=False, label='Correct anisotropic magnification?', condition='useMotioncor2', help='Correct anisotropic magnification by ' 'stretching image along the major axis, ' 'the axis where the lower magnification is ' 'detected.') group.addParam('useEst', params.BooleanParam, default=True, label='Use previous estimation?', condition='useMotioncor2 and doMagCor', help='Use previously calculated parameters of ' 'magnification anisotropy (from magnification ' 'distortion estimation protocol).') group.addParam('inputEst', params.PointerParam, pointerClass='ProtMagDistEst', condition='useEst and useMotioncor2 and doMagCor', label='Input protocol', help='Select previously executed estimation protocol.') group.addParam('scaleMaj', params.FloatParam, default=1.0, condition='not useEst and useMotioncor2 and doMagCor', label='Major scale factor', help='Major scale factor.') group.addParam('scaleMin', params.FloatParam, default=1.0, condition='not useEst and useMotioncor2 and doMagCor', label='Minor scale factor', help='Minor scale factor.') group.addParam('angDist', params.FloatParam, default=0.0, condition='not useEst and useMotioncor2 and doMagCor', label='Distortion angle (deg)', help='Distortion angle, in degrees.') else: form.addParam('motioncor2Version', params.LabelParam, condition='useMotioncor2', label='Scipion supports some versions of motioncor2 ' 'that can do magnification correction, ' 'but they do not seems to be installed. Check ' 'available versions with: \n' 'scipion install --help.\n' 'Also, make sure MOTIONCOR2_CUDA_LIB or ' 'CUDA_LIB point to cuda-8.0/lib path') if self.isSemVersion(): form.addParam('defectFile', params.FileParam, allowsNull=True, expertLevel=cons.LEVEL_ADVANCED, condition='useMotioncor2', label='Camera defects file', help='Defect file that stores entries of defects on camera.\n' 'Each entry corresponds to a rectangular region in image. ' 'The pixels in such a region are replaced by ' 'neighboring good pixel values. Each entry contains ' '4 integers x, y, w, h representing the x, y ' 'coordinates, width, and height, respectively.') form.addParam('extraParams2', params.StringParam, default='', expertLevel=cons.LEVEL_ADVANCED, condition='useMotioncor2', label='Additional parameters', help="""Extra parameters for motioncor2\n -Bft 100 BFactor for alignment, in px^2. -Iter 5 Maximum iterations for iterative alignment. -MaskCent 0 0 Center of subarea that will be used for alignment, default *0 0* corresponding to the frame center. -MaskSize 1.0 1.0 The size of subarea that will be used for alignment, default *1.0 1.0* corresponding full size. -Align 1 Generate aligned sum (1) or simple sum (0). -FmRef -1 Specify which frame to be the reference to which all other frames are aligned, by default (-1) the the central frame is chosen. The central frame is at N/2 based upon zero indexing where N is the number of frames that will be summed, i.e., not including the frames thrown away. -RotGain 0 Rotate gain reference counter-clockwise: 0 - no rotation, 1 - 90 degrees, 2 - 180 degrees, 3 - 270 degrees. -FlipGain 0 Flip gain reference after gain rotation: 0 - no flipping, 1 - flip upside down, 2 - flip left right. -Tilt 0 0 Tilt angle range for a dose fractionated tomographic tilt series, e.g. *-60 60* Since version *1.1.0*: -GpuMemUsage 0.5 Specify how much GPU memory is used to buffer movie frames. It is recommended when running side by side processes in the same card. By default is 50% (i. e 0.5) -InFmMotion 1 Takes into account of motion-induced blurring of each frame. It has shown resolution improvement in some test cases. By default this option is off. -Bft 500 150 Since version 1.1.0 this option can take two arguments. First one is used in global-motion measurement and the second one is for local-motion. (default 500 150). """) form.addParam('doSaveUnweightedMic', params.BooleanParam, default=True, condition='doSaveAveMic and useMotioncor2 and doApplyDoseFilter', label="Save unweighted micrographs?", help="Yes by default, if you have selected to apply a " "dose-dependent filter to the frames") # Since only runs on GPU, do not allow neither threads nor mpi form.addParallelSection(threads=1, mpi=1)
def __init__(self, **args): ProtAlignMovies.__init__(self, **args) self.stepsExecutionMode = STEPS_PARALLEL
def _validate(self): # Check base validation before the specific ones for Motioncorr errors = ProtAlignMovies._validate(self) program = MOTIONCOR2_PATH if self.useMotioncor2 else MOTIONCORR_PATH if not os.path.exists(program): errors.append('Missing %s' % program) # Check CUDA paths cudaLib = getCudaLib(useMC2=self.useMotioncor2) cudaConst = (MOTIONCOR2_CUDA_LIB if self.useMotioncor2 else MOTIONCORR_CUDA_LIB) if cudaLib is None: errors.append("Do not know where to find CUDA lib path. " " %s or %s variables have None value or are not" " present in scipion configuration." % (cudaConst, CUDA_LIB)) elif not pwutils.existsVariablePaths(cudaLib): errors.append("Either %s or %s variables points to a non existing " "path (%s). Please, check scipion configuration." % (cudaConst, CUDA_LIB, cudaLib)) gpu = self.gpuList.get() if not self.useMotioncor2: bin = self.binFactor.get() if not (bin == 1.0 or bin == 2.0): errors.append("Binning factor can only be 1 or 2") if len(gpu) > 1: errors.append("Old motioncorr2.1 does not support multiple " "GPUs, use motioncor2.") else: if not self.doSaveAveMic: errors.append('Option not supported. Please select Yes for ' 'Save aligned micrograph. ' 'Optionally you could add -Align 0 to additional ' 'parameters so that protocol ' 'produces simple movie sum.') if self.doSaveMovie and not self._isOutStackSupport: errors.append('Saving aligned movies is not supported by ' 'this version of motioncor2. ' 'By default, the protocol will produce ' 'outputMovies equivalent to the input ' 'however containing alignment information.') if not self.useAlignToSum: errors.append('Frame range for ALIGN and SUM must be ' 'equivalent in case of motioncor2. \n Please, ' 'set *YES* _Use ALIGN frames range to SUM?_ ' 'flag or use motioncorr') if self.doApplyDoseFilter and self.inputMovies.get(): inputMovies = self.inputMovies.get() doseFrame = inputMovies.getAcquisition().getDosePerFrame() if doseFrame == 0.0 or doseFrame is None: errors.append('Dose per frame for input movies is 0 or not ' 'set. You cannot apply dose filter.') return errors
def _defineAlignmentParams(self, form): ProtAlignMovies._defineAlignmentParams(self, form) form.addSection("Aditional Parameters") # GROUP GPU PARAMETERS #group = form.addGroup('GPU') form.addHidden(params.USE_GPU, params.BooleanParam, default=False, label="Use GPU (vs CPU)", help="Set to true if you want the GPU implementation of " "Optical Flow") form.addHidden(params.GPU_LIST, params.StringParam, default=0, expertLevel=params.LEVEL_ADVANCED, label="Choose GPU core", 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.") group = form.addGroup('OF Parameters') group.addParam('winSize', params.IntParam, default=150, expertLevel=params.LEVEL_ADVANCED, label="Window size", help="Window size (shifts are assumed to be constant " "within this window).") group.addParam('groupSize', params.IntParam, default=1, expertLevel=params.LEVEL_ADVANCED, label="Group Size", help="The number of frames in each group at the " "last step") group.addParam('useAlignment', params.BooleanParam, default=True, label="Use previous movie alignment to SUM frames?", help="Input movies could have alignment information from" "a previous protocol. If you select *Yes*, the " "previous alignment will be taken into account.") group.addParam('doComputePSD', params.BooleanParam, default=True, label="Compute PSD (before/after)?", help="If Yes, the protocol will compute for each movie " "the PSD of the average micrograph (without OF " "alignement) and after that, to compare each PSDs") group.addParam('memory', params.BooleanParam, default=False, label="Keep images in RAM ?", help="If True, the protocol will increase the demand of " "RAM, decreasing disc access") group = form.addGroup('Dose Compensation') group.addParam('doApplyDoseFilter', params.BooleanParam, default=False, label='Apply Dose filter', help='Apply a dose-dependent filter to frames before ' 'summing them. Pre-exposure and dose per frame ' 'should be specified during movies import.') group.addParam('doSaveUnweightedMic', params.BooleanParam, default=True, condition='doSaveAveMic and doApplyDoseFilter', label="Save unweighted micrographs?", help="Yes by default, if you have selected to apply a " "dose-dependent filter to the frames") group.addParam('applyDosePreAlign', params.BooleanParam, default=False, condition='doApplyDoseFilter', label="Apply Dose filter before alignment?", help="if *True*, you apply dose filter before perform " "the alignment; else will apply after alignment.") form.addParallelSection(threads=8, mpi=1)
def _validate(self): # Check base validation before the specific ones for Motioncorr errors = ProtAlignMovies._validate(self) return errors
def _convertInputStep(self): self.info("Relion version:") self.runJob("which", "relion_run_motioncorr", numberOfMpi=1) ProtAlignMovies._convertInputStep(self)
def _defineAlignmentParams(self, form): form.addParam('gpuMsg', params.LabelParam, default=True, label='WARNING! You need to have installed CUDA' ' libraries and a Nvidia GPU') form.addParam('GPUIDs', params.StringParam, default='0', expertLevel=cons.LEVEL_ADVANCED, label="Choose GPU IDs", 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." " Motioncor2 can use multiple GPUs - in that case" " set to i.e. *0 1 2*.") ProtAlignMovies._defineAlignmentParams(self, form) form.addParam('doComputePSD', params.BooleanParam, default=False, expertLevel=cons.LEVEL_ADVANCED, label="Compute PSD (before/after)?", help="If Yes, the protocol will compute for each movie " "the average PSD before and after alignment, " "for comparison") form.addParam('doComputeMicThumbnail', params.BooleanParam, expertLevel=cons.LEVEL_ADVANCED, default=False, label='Compute micrograph thumbnail?', help='When using this option, we will compute a ' 'micrograph thumbnail and keep it with the ' 'micrograph object for visualization purposes. ') form.addParam('computeAllFramesAvg', params.BooleanParam, expertLevel=cons.LEVEL_ADVANCED, default=False, label='Compute all frames average?', help='Computing all the frames average could provide a ' 'sanity check about the microscope and the camera.') form.addParam( 'extraParams', params.StringParam, default='', expertLevel=cons.LEVEL_ADVANCED, label='Additional parameters', help="""Extra parameters for motioncorr (NOT motioncor2)\n -bft 150 BFactor in pix^2. -pbx 96 Box dimension for searching CC peak. -fod 2 Number of frame offset for frame comparison. -nps 0 Radius of noise peak. -sub 0 1: Save as sub-area corrected sum. 0: Not. -srs 0 1: Save uncorrected sum. 0: Not. -scc 0 1: Save CC Map. 0: Not. -slg 1 1: Save Log. 0: Not. -atm 1 1: Align to middle frame. 0: Not. -dsp 1 1: Save quick results. 0: Not. -fsc 0 1: Calculate and log FSC. 0: Not. """) form.addSection(label="Motioncor2") form.addParam('useMotioncor2', params.BooleanParam, default=True, label='Use motioncor2', help='Use new *motioncor2* program with local ' 'patch-based motion correction and dose weighting.') form.addParam('doApplyDoseFilter', params.BooleanParam, default=True, condition='useMotioncor2', label='Apply Dose filter', help='Apply a dose-dependent filter to frames before ' 'summing them. Pre-exposure and dose per frame ' 'should be specified during movies import.') line = form.addLine( 'Number of patches', condition='useMotioncor2', help='Number of patches to be used for patch based ' 'alignment. Set to *0 0* to do only global motion ' 'correction. \n') line.addParam('patchX', params.IntParam, default=5, label='X') line.addParam('patchY', params.IntParam, default=5, label='Y') if self.versionGE('1.0.1'): # Patch overlap was introduced in 1.0.1 form.addParam('patchOverlap', params.IntParam, default=0, condition='useMotioncor2', label='Patches Overlap (%)', help='In versions > 1.0.1 it is possible to specify' 'the overlapping between patches. ' '\nFor example, overlap=20 means that ' 'each patch will have a 20% overlapping \n' 'with its neighboring patches in each dimension.') form.addParam('group', params.IntParam, default='1', label='Group N frames', condition='useMotioncor2', help='Group every specified number of frames by adding ' 'them together. The alignment is then performed on ' 'the summed frames. By default, no grouping is ' 'performed.') form.addParam( 'tol', params.FloatParam, default='0.5', label='Tolerance (px)', condition='useMotioncor2', help='Tolerance for iterative alignment, default *0.5px*.') if self._supportsMagCorrection(): group = form.addGroup('Magnification correction') group.addParam('doMagCor', params.BooleanParam, default=False, label='Correct anisotropic magnification?', condition='useMotioncor2', help='Correct anisotropic magnification by ' 'stretching image along the major axis, ' 'the axis where the lower magnification is ' 'detected.') group.addParam('useEst', params.BooleanParam, default=True, label='Use previous estimation?', condition='useMotioncor2 and doMagCor', help='Use previously calculated parameters of ' 'magnification anisotropy (from magnification ' 'distortion estimation protocol).') group.addParam( 'inputEst', params.PointerParam, pointerClass='ProtMagDistEst', condition='useEst and useMotioncor2 and doMagCor', label='Input protocol', help='Select previously executed estimation protocol.') group.addParam( 'scaleMaj', params.FloatParam, default=1.0, condition='not useEst and useMotioncor2 and doMagCor', label='Major scale factor', help='Major scale factor.') group.addParam( 'scaleMin', params.FloatParam, default=1.0, condition='not useEst and useMotioncor2 and doMagCor', label='Minor scale factor', help='Minor scale factor.') group.addParam( 'angDist', params.FloatParam, default=0.0, condition='not useEst and useMotioncor2 and doMagCor', label='Distortion angle (deg)', help='Distortion angle, in degrees.') else: form.addParam('motioncor2Version', params.LabelParam, condition='useMotioncor2', label='Scipion supports some versions of motioncor2 ' 'that can do magnification correction, ' 'but they do not seems to be installed. Check ' 'available versions with: \n' 'scipion install --help.\n' 'Also, make sure MOTIONCOR2_CUDA_LIB or ' 'CUDA_LIB point to cuda-8.0/lib path') if self.isSemVersion(): form.addParam( 'defectFile', params.FileParam, allowsNull=True, expertLevel=cons.LEVEL_ADVANCED, condition='useMotioncor2', label='Camera defects file', help='Defect file that stores entries of defects on camera.\n' 'Each entry corresponds to a rectangular region in image. ' 'The pixels in such a region are replaced by ' 'neighboring good pixel values. Each entry contains ' '4 integers x, y, w, h representing the x, y ' 'coordinates, width, and height, respectively.') form.addParam('extraParams2', params.StringParam, default='', expertLevel=cons.LEVEL_ADVANCED, condition='useMotioncor2', label='Additional parameters', help="""Extra parameters for motioncor2\n -Bft 100 BFactor for alignment, in px^2. -Iter 5 Maximum iterations for iterative alignment. -MaskCent 0 0 Center of subarea that will be used for alignment, default *0 0* corresponding to the frame center. -MaskSize 1.0 1.0 The size of subarea that will be used for alignment, default *1.0 1.0* corresponding full size. -Align 1 Generate aligned sum (1) or simple sum (0). -FmRef -1 Specify which frame to be the reference to which all other frames are aligned, by default (-1) the the central frame is chosen. The central frame is at N/2 based upon zero indexing where N is the number of frames that will be summed, i.e., not including the frames thrown away. -RotGain 0 Rotate gain reference counter-clockwise: 0 - no rotation, 1 - 90 degrees, 2 - 180 degrees, 3 - 270 degrees. -FlipGain 0 Flip gain reference after gain rotation: 0 - no flipping, 1 - flip upside down, 2 - flip left right. -Tilt 0 0 Tilt angle range for a dose fractionated tomographic tilt series, e.g. *-60 60* """) form.addParam( 'doSaveUnweightedMic', params.BooleanParam, default=True, condition='doSaveAveMic and useMotioncor2 and doApplyDoseFilter', label="Save unweighted micrographs?", help="Yes by default, if you have selected to apply a " "dose-dependent filter to the frames") # Since only runs on GPU, do not allow neither threads nor mpi form.addParallelSection(threads=1, mpi=1)
def __init__(self, **kwargs): ProtAlignMovies.__init__(self, **kwargs) self.stepsExecutionMode = STEPS_SERIAL