diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ba1c68058..694fb9bc54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ -## v1.0.0 (2016-02-15) Augusto +## v1.0.0 (2016-02-20) Augusto - Allows to combine several EM software packages (~ 100 protocols): - All protocols from Xmipp diff --git a/config/workflows/workflow_betagal1.json b/config/workflows/workflow_betagal1.json index 82c39d4185..e5572a69f2 100644 --- a/config/workflows/workflow_betagal1.json +++ b/config/workflows/workflow_betagal1.json @@ -32,7 +32,7 @@ "alignFrame0": 0, "alignFrameN": 0, "doGPU": false, - "GPUCore": 1, + "GPUCore": 0, "winSize": 150, "sumFrame0": 0, "sumFrameN": 0, diff --git a/pyworkflow/em/packages/grigoriefflab/bibtex.py b/pyworkflow/em/packages/grigoriefflab/bibtex.py index 51e299f1e9..1e25ff5f72 100644 --- a/pyworkflow/em/packages/grigoriefflab/bibtex.py +++ b/pyworkflow/em/packages/grigoriefflab/bibtex.py @@ -134,7 +134,18 @@ keywords = "Electron microscopy, Maximum likelihood, Classification, Single particle, Protein structure " } - +@Article{Rohou2015, + Author="Rohou, A. and Grigorieff, N. ", + Title="{{C}{T}{F}{F}{I}{N}{D}4: {F}ast and accurate defocus estimation from electron micrographs}", + Journal="J. Struct. Biol.", + Year="2015", + Volume="192", + Number="2", + Pages="216--221", + Month="Nov", + doi = "http://dx.doi.org/10.1016/j.jsb.2015.08.008", + url = "http://www.sciencedirect.com/science/article/pii/S1047847715300460" +} """ diff --git a/pyworkflow/em/packages/grigoriefflab/convert.py b/pyworkflow/em/packages/grigoriefflab/convert.py index 59e4c01872..d1c2454055 100644 --- a/pyworkflow/em/packages/grigoriefflab/convert.py +++ b/pyworkflow/em/packages/grigoriefflab/convert.py @@ -202,12 +202,13 @@ def readCtfModel(ctfModel, filename, ctf4=False): result = parseCtffind4Output(filename) if result is None: setWrongDefocus(ctfModel) - ctfFit, ctfResolution = -999, -999 + ctfFit, ctfResolution, ctfPhaseShift = -999, -999, -999 else: - defocusU, defocusV, defocusAngle, _, ctfFit, ctfResolution = result + defocusU, defocusV, defocusAngle, ctfPhaseShift, ctfFit, ctfResolution = result ctfModel.setStandardDefocus(defocusU, defocusV, defocusAngle) ctfModel._ctffind4_crossCorrelation = Float(ctfFit) ctfModel._ctffind4_ctfResolution = Float(ctfResolution) + ctfModel._ctffind4_ctfPhaseShift = Float(ctfPhaseShift) def geometryFromMatrix(matrix): diff --git a/pyworkflow/em/packages/grigoriefflab/protocol_ctffind.py b/pyworkflow/em/packages/grigoriefflab/protocol_ctffind.py index 68a3ff407d..651b822f5e 100644 --- a/pyworkflow/em/packages/grigoriefflab/protocol_ctffind.py +++ b/pyworkflow/em/packages/grigoriefflab/protocol_ctffind.py @@ -50,16 +50,40 @@ class ProtCTFFind(em.ProtCTFMicrographs): def _defineProcessParams(self, form): - form.addParam('useCftfind4', params.BooleanParam, default=True, + form.addParam('useCtffind4', params.BooleanParam, default=True, label="Use ctffind4 to estimate the CTF?", help='If is true, the protocol will use ctffind4 instead of ctffind3') form.addParam('astigmatism', params.FloatParam, default=100.0, - label='Expected (tolerated) astigmatism', expertLevel=params.LEVEL_ADVANCED, - condition='useCftfind4', ) + label='Expected (tolerated) astigmatism (A)', + expertLevel=params.LEVEL_ADVANCED, + help='Astigmatism values much larger than this will be penalised ' + '(Angstroms; set negative to remove this restraint)', + condition='useCtffind4') form.addParam('findPhaseShift', params.BooleanParam, default=False, - label="Find additional phase shift?", condition='useCftfind4', - expertLevel=params.LEVEL_ADVANCED,) - + label="Find additional phase shift?", condition='useCtffind4', + help='If the data was collected with phase plate, this will find ' + 'additional phase shift due to phase plate', + expertLevel=params.LEVEL_ADVANCED) + + group = form.addGroup('Phase shift parameters') + group.addParam('minPhaseShift', params.FloatParam, default=0.0, + label="Minimum phase shift (rad)", condition='findPhaseShift', + help='Lower bound of the search for additional phase shift. ' + 'Phase shift is of scattered electrons relative to ' + 'unscattered electrons. In radians.', + expertLevel=params.LEVEL_ADVANCED) + group.addParam('maxPhaseShift', params.FloatParam, default=3.15, + label="Maximum phase shift (rad)", condition='findPhaseShift', + help='Upper bound of the search for additional phase shift. ' + 'Phase shift is of scattered electrons relative to ' + 'unscattered electrons. In radians. ' + 'Please use value between 0.10 and 3.15', + expertLevel=params.LEVEL_ADVANCED) + group.addParam('stepPhaseShift', params.FloatParam, default=0.2, + label="Phase shift search step (rad)", condition='findPhaseShift', + help='Step size for phase shift search (radians)', + expertLevel=params.LEVEL_ADVANCED) + #--------------------------- STEPS functions --------------------------------------------------- def _estimateCTF(self, micFn, micDir, micName): """ Run ctffind, 3 or 4, with required parameters """ @@ -71,7 +95,9 @@ def _estimateCTF(self, micFn, micDir, micName): if downFactor != 1: #Replace extension by 'mrc' cause there are some formats that cannot be written (such as dm3) import pyworkflow.em.packages.xmipp3 as xmipp3 - self.runJob("xmipp_transform_downsample","-i %s -o %s --step %f --method fourier" % (micFn, micFnMrc, downFactor), env=xmipp3.getEnviron()) + self.runJob("xmipp_transform_downsample", + "-i %s -o %s --step %f --method fourier" % (micFn, micFnMrc, downFactor), + env=xmipp3.getEnviron()) self._params['scannedPixelSize'] = self.inputMicrographs.get().getScannedPixelSize() * downFactor else: micFnMrc = self._getTmpPath(pwutils.replaceBaseExt(micFn, "mrc")) @@ -122,12 +148,7 @@ def _createNewCtfModel(self, mic): out = self._getCtfOutPath(micDir) psdFile = self._getPsdPath(micDir) ctfModel2 = em.CTFModel() - - if not self.useCftfind4: - readCtfModel(ctfModel2, out) - else: - readCtfModel(ctfModel2, out, True) - + readCtfModel(ctfModel2, out, ctf4=self.useCtffind4.get()) ctfModel2.setPsdFile(psdFile) ctfModel2.setMicrograph(mic) return ctfModel2 @@ -144,12 +165,7 @@ def _createOutputStep(self): out = self._getCtfOutPath(micDir) ctfModel = em.CTFModel() - - if not self.useCftfind4: - readCtfModel(ctfModel, out) - else: - readCtfModel(ctfModel, out, True) - + readCtfModel(ctfModel, out, ctf4=self.useCtffind4.get()) ctfModel.setPsdFile(psdFile) ctfModel.setMicrograph(mic) @@ -164,16 +180,23 @@ def _createOutputStep(self): #--------------------------- INFO functions ---------------------------------------------------- def _validate(self): errors = [] - if self.useCftfind4: - ctffind = CTFFIND4_PATH - else: - ctffind = CTFFIND_PATH + ctffind = CTFFIND4_PATH if self.useCtffind4 else CTFFIND_PATH if not os.path.exists(ctffind): errors.append('Missing %s' % ctffind) + + valueStep = round(self.stepPhaseShift.get(), 2) + valueMin = round(self.minPhaseShift.get(), 2) + valueMax = round(self.maxPhaseShift.get(), 2) + + if not (self.minPhaseShift < self.maxPhaseShift and + valueStep <= (valueMax-valueMin) and + 0.10 <= valueMax <= 3.15): + errors.append('Wrong values for phase shift search.') + return errors def _citations(self): - return ['Mindell2003'] + return ['Rohou2015'] if self.useCtffind4 else ['Mindell2003'] def _methods(self): if self.inputMicrographs.get() is None: @@ -194,12 +217,15 @@ def _prepareCommand(self): self._params['lowRes'] = 50 self._params['highRes'] = sampling / self._params['highRes'] self._params['step_focus'] = 500.0 - if not self.useCftfind4: + if not self.useCtffind4: self._argsCtffind3() else: self._params['astigmatism'] = self.astigmatism.get() if self.findPhaseShift: self._params['phaseShift'] = "yes" + self._params['minPhaseShift'] = self.minPhaseShift.get() + self._params['maxPhaseShift'] = self.maxPhaseShift.get() + self._params['stepPhaseShift'] = self.stepPhaseShift.get() else: self._params['phaseShift'] = "no" self._argsCtffind4() @@ -226,12 +252,15 @@ def _prepareRecalCommand(self, ctfModel): self._params['maxDefocus'] = max([float(line[0]), float(line[1])]) self._params['windowSize'] = size - if not self.useCftfind4: + if not self.useCtffind4: self._argsCtffind3() else: self._params['astigmatism'] = self.astigmatism.get() if self.findPhaseShift: self._params['phaseShift'] = "yes" + self._params['minPhaseShift'] = self.minPhaseShift.get() + self._params['maxPhaseShift'] = self.maxPhaseShift.get() + self._params['stepPhaseShift'] = self.stepPhaseShift.get() else: self._params['phaseShift'] = "no" self._argsCtffind4() @@ -248,7 +277,29 @@ def _argsCtffind3(self): def _argsCtffind4(self): self._program = 'export OMP_NUM_THREADS=1; ' + CTFFIND4_PATH - self._args = """ << eof + if self.findPhaseShift: + self._args = """ << eof +%(micFn)s +%(ctffindPSD)s +%(sampling)f +%(voltage)f +%(sphericalAberration)f +%(ampContrast)f +%(windowSize)d +%(lowRes)f +%(highRes)f +%(minDefocus)f +%(maxDefocus)f +%(step_focus)f +%(astigmatism)f +%(phaseShift)s +%(minPhaseShift)f +%(maxPhaseShift)f +%(stepPhaseShift)f +eof +""" + else: + self._args = """ << eof %(micFn)s %(ctffindPSD)s %(sampling)f @@ -276,7 +327,7 @@ def _parseOutput(self, filename): """ Try to find the output estimation parameters from filename. It search for a line containing: Final Values. """ - if not self.useCftfind4: + if not self.useCtffind4: return parseCtffindOutput(filename) else: return parseCtffind4Output(filename) @@ -287,3 +338,4 @@ def _getCTFModel(self, defocusU, defocusV, defocusAngle, psdFile): ctf.setPsdFile(psdFile) return ctf + diff --git a/pyworkflow/em/packages/grigoriefflab/viewer.py b/pyworkflow/em/packages/grigoriefflab/viewer.py index dc9a4b100e..8ddf03a667 100644 --- a/pyworkflow/em/packages/grigoriefflab/viewer.py +++ b/pyworkflow/em/packages/grigoriefflab/viewer.py @@ -28,8 +28,9 @@ """ import os from os.path import exists, relpath -from pyworkflow.utils.path import cleanPath +from pyworkflow.utils.path import cleanPath, removeBaseExt from pyworkflow.viewer import (ProtocolViewer, DESKTOP_TKINTER, WEB_DJANGO, Viewer) +from pyworkflow.em.viewer import CtfView import pyworkflow.em as em import pyworkflow.em.showj as showj from pyworkflow.em.plotter import EmPlotter @@ -164,9 +165,8 @@ def _showImagesInClasses(self, paramName=None): #=============================================================================== def _showImagesAngularAssignment(self, paramName=None): - views = [] - + for it in self._iterations: fn = self._getIterData(it) v = self.createScipionPartView(fn) @@ -180,6 +180,7 @@ def _showImagesAngularAssignment(self, paramName=None): def _viewMatchProj(self, paramName=None): views = [] + for it in self._iterations: files = self.protocol._getFileName('match', iter=it) v = self.createDataView(files) @@ -560,100 +561,53 @@ class ProtCTFFindViewer(Viewer): _environments = [DESKTOP_TKINTER, WEB_DJANGO] _label = 'viewer CtfFind' _targets = [ProtCTFFind] - - - def __init__(self, **args): - Viewer.__init__(self, **args) - self._views = [] - - def visualize(self, obj, **args): - self._visualize(obj, **args) - - for v in self._views: - v.show() - + def _visualize(self, obj, **args): - cls = type(obj) - - def _getMicrographDir(mic): - """ Return an unique dir name for results of the micrograph. """ - from pyworkflow.utils.path import removeBaseExt - return obj._getExtraPath(removeBaseExt(mic.getFileName())) - - def iterMicrographs(mics): - """ Iterate over micrographs and yield - micrograph name and a directory to process. - """ - for mic in mics: - micFn = mic.getFileName() - micDir = _getMicrographDir(mic) - yield (micFn, micDir, mic) - - def visualizeObjs(obj, setOfMics): - if exists(obj._getPath("ctfs_temporary.sqlite")): - os.remove(obj._getPath("ctfs_temporary.sqlite")) - - ctfSet = self.protocol._createSetOfCTF("_temporary") - for fn, micDir, mic in iterMicrographs(setOfMics): - samplingRate = mic.getSamplingRate() * self.protocol.ctfDownFactor.get() - mic.setSamplingRate(samplingRate) - out = self.protocol._getCtfOutPath(micDir) - psdFile = self.protocol._getPsdPath(micDir) - - if exists(out) and exists(psdFile): - ctfModel = em.CTFModel() - - if not self.protocol.useCftfind4: - readCtfModel(ctfModel, out) - else: - readCtfModel(ctfModel, out, True) - - ctfModel.setPsdFile(psdFile) - ctfModel.setMicrograph(mic) - - ctfSet.append(ctfModel) - - if ctfSet.getSize() < 1: - raise Exception("Has not been completed the CTF estimation of any micrograph") - else: - ctfSet.write() - ctfSet.close() - self._visualize(ctfSet) - - - if issubclass(cls, ProtCTFFind) and not obj.hasAttribute("outputCTF"): + views = [] + + if obj.hasAttribute("outputCTF"): # Finished protocol + ctfSet = obj.outputCTF + other = '' + else: mics = obj.inputMicrographs.get() - visualizeObjs(obj, mics) - elif obj.hasAttribute("outputCTF"): - self._visualize(obj.outputCTF) + ctfSet = self.__createTemporaryCtfs(obj, mics) + other = obj.getObjId() + + if ctfSet.isEmpty(): + views.append(self.infoMessage("No CTF estimation has finished yet")) else: - fn = obj.getFileName() - if obj.strId() == "None": - objName = fn - else: - objName = obj.strId() - psdLabels = '_psdFile' - labels = 'id enabled comment %s _defocusU _defocusV _defocusAngle _defocusRatio' % psdLabels - if self.protocol.useCftfind4: - labels = labels + ' _ctffind4_ctfResolution _micObj._filename' - print "objName, ", objName - self._views.append(em.ObjectView(self._project, objName, fn, - viewParams={showj.MODE: showj.MODE_MD, - showj.ORDER: labels, - showj.VISIBLE: labels, - showj.ZOOM: 50, - showj.RENDER: psdLabels, - showj.OBJCMDS: "'%s'" % showj.OBJCMD_CTFFIND4})) - else: - labels += ' _micObj._filename' - self._views.append(em.ObjectView(self._project, obj.strId(), fn, - viewParams={showj.MODE: showj.MODE_MD, - showj.ORDER: labels, - showj.VISIBLE: labels, - showj.ZOOM: 50, - showj.RENDER: psdLabels})) - - return self._views + views.append(CtfView(self._project, ctfSet, other)) + + return views + + def __createTemporaryCtfs(self, obj, setOfMics): + """ Create a temporary .sqlite file to visualize CTF while the + protocol has not finished yet. + """ + cleanPath(obj._getPath("ctfs_temporary.sqlite")) + ctfSet = self.protocol._createSetOfCTF("_temporary") + + for mic in setOfMics: + micFn = mic.getFileName() + micDir = obj._getExtraPath(removeBaseExt(mic.getFileName())) + samplingRate = mic.getSamplingRate() * self.protocol.ctfDownFactor.get() + mic.setSamplingRate(samplingRate) + out = self.protocol._getCtfOutPath(micDir) + psdFile = self.protocol._getPsdPath(micDir) + + if exists(out) and exists(psdFile): + ctfModel = em.CTFModel() + readCtfModel(ctfModel, out, + ctf4=self.protocol.useCtffind4.get()) + ctfModel.setPsdFile(psdFile) + ctfModel.setMicrograph(mic) + ctfSet.append(ctfModel) + + if not ctfSet.isEmpty(): + ctfSet.write() + ctfSet.close() + + return ctfSet def createCtfPlot(ctfSet, ctfId): from pyworkflow.utils.path import removeExt diff --git a/pyworkflow/em/packages/relion/viewer.py b/pyworkflow/em/packages/relion/viewer.py index cf80ac9455..99c9b026c3 100644 --- a/pyworkflow/em/packages/relion/viewer.py +++ b/pyworkflow/em/packages/relion/viewer.py @@ -216,10 +216,10 @@ def _defineParams(self, form): label=changesLabel, help='Visualize changes in orientation, offset and\n number images assigned to each class') - def _getVisualizeDict(self): self._load() - return {'showImagesInClasses': self._showImagesInClasses, + visualizeDict = { + 'showImagesInClasses': self._showImagesInClasses, 'showClassesOnly': self._showClassesOnly, 'showImagesAngularAssignment' : self._showImagesAngularAssignment, 'showOptimiserFile': self._showOptimiserFile, @@ -231,6 +231,19 @@ def _getVisualizeDict(self): 'resolutionPlotsSSNR': self._showSSNR, 'resolutionPlotsFSC': self._showFSC } + + # If the is some error during the load, just show that instead + # of any viewer + if self._errors: + for k in visualizeDict.keys(): + visualizeDict[k] = self._showErrors + + return visualizeDict + + def _showErrors(self, param=None): + views = [] + self.errorList(self._errors, views) + return views def _viewAll(self, *args): pass @@ -416,7 +429,7 @@ def _showVolumesChimera(self): #=============================================================================== def _showAngularDistribution(self, paramName=None): views = [] - + if self.displayAngDist == ANGDIST_CHIMERA: for it in self._iterations: views.append(self._createAngDistChimera(it)) @@ -609,14 +622,31 @@ def createScipionPartView(self, filename, viewParams={}): env=self._env, viewParams=viewParams) + def _getRange(self, var, label): + """ Check if the range is not empty. + :param var: The variable to retrieve the value + :param label: the labe used for the message string + :return: the list with the range of values, empty + """ + value = var.get() + if value is None or not value.strip(): + self._errors.append('Provide %s selection.' % label) + result = [] + else: + result = self._getListFromRangeString(value) + + return result + def _load(self): """ Load selected iterations and classes 3D for visualization mode. """ self._refsList = [1] + self._errors = [] + if self.protocol.IS_3D and self.protocol.IS_CLASSIFY: if self.showClasses3D == CLASSES_ALL: self._refsList = range(1, self.protocol.numberOfClasses.get()+1) else: - self._refsList = self._getListFromRangeString(self.class3DSelection.get()) + self._refsList = self._getRange(self.class3DSelection, 'classes 3d') self.protocol._initialize() # Load filename templates self.firstIter = self.protocol._firstIter() self.lastIter = self.protocol._lastIter() @@ -625,8 +655,7 @@ def _load(self): if self.viewIter.get() == ITER_LAST or halves == 3: self._iterations = [self.lastIter] else: - self._iterations = self._getListFromRangeString(self.iterSelection.get()) - + self._iterations = self._getRange(self.iterSelection, 'iterations') from matplotlib.ticker import FuncFormatter self._plotFormatter = FuncFormatter(self._formatFreq) @@ -1029,14 +1058,28 @@ def _defineParams(self, form): def _getVisualizeDict(self): self._load() - return {'displayShinyParticles': self._showShinyParticles, + visualizeDict = { + 'displayShinyParticles': self._showShinyParticles, 'displayVol': self._showVolumes, 'displayAngDist': self._showAngularDistribution, 'resolutionPlotsFSC': self._showFSC, 'guinierPlots': self._showGuinier, 'bfactorsPlot': self._showBfactors } - + + # If the is some error during the load, just show that instead + # of any viewer + if self._errors: + for k in visualizeDict.keys(): + visualizeDict[k] = self._showErrors + + return visualizeDict + + def _showErrors(self, e=None): + views = [] + self.errorList(self._errors, views) + return views + def _viewAll(self, *args): pass @@ -1237,6 +1280,7 @@ def _plotBfactor(self, a, model, label): #=============================================================================== def _load(self): self.protocol._initialize() # Load filename templates + self._errors = [] self.lastIter = self.protocol._lastIter() halves = getattr(self, 'showHalves', None) if self.viewFrame.get() == 0 and halves < 3: @@ -1244,7 +1288,11 @@ def _load(self): # know how many frames has a SetOfMovieParticles. self._frames = range(1, self.protocol._lastFrame()) elif halves < 3: - self._frames = self._getListFromRangeString(self.frameSelection.get()) + frameSelection = self.frameSelection.get() + if frameSelection and frameSelection.strip(): + self._frames = self._getListFromRangeString(frameSelection) + else: + self._errors.append('Please provide FRAMES selection') else: self._frames = [1] diff --git a/pyworkflow/em/packages/spider/convert.py b/pyworkflow/em/packages/spider/convert.py index 11a558d5a3..94c2044864 100644 --- a/pyworkflow/em/packages/spider/convert.py +++ b/pyworkflow/em/packages/spider/convert.py @@ -34,7 +34,7 @@ from pyworkflow.utils.path import moveFile from spider import SpiderDocFile, runTemplate -from os.path import splitext +from os.path import splitext, split @@ -95,12 +95,13 @@ def convertEndian(stackFn, stackSize): stackSize: the number of particles in the stack """ fn, ext = splitext(stackFn) + fnDir, fnBase = split(fn) # Change to BigEndian runTemplate('cp_endian.spi', ext[1:], - {'[particles]': fn + '@******', - '[particles_big]': fn + '_big@******', + {'[particles]': fnBase + '@******', + '[particles_big]': fnBase + '_big@******', '[numberOfParticles]': stackSize - }) + }, cwd=fnDir) moveFile(fn + '_big' + ext, stackFn) diff --git a/pyworkflow/em/packages/xmipp3/protocol_extract_particles.py b/pyworkflow/em/packages/xmipp3/protocol_extract_particles.py index a89cc0fba7..3c306a75d8 100644 --- a/pyworkflow/em/packages/xmipp3/protocol_extract_particles.py +++ b/pyworkflow/em/packages/xmipp3/protocol_extract_particles.py @@ -427,18 +427,23 @@ def createOutputStep(self): #--------------------------- INFO functions -------------------------------------------- def _validate(self): - validateMsgs = [] + errors = [] # doFlip can only be True if CTF information is available on picked micrographs if self.doFlip and not self.ctfRelations.hasValue(): - validateMsgs.append('Phase flipping cannot be performed unless CTF information is provided.') - + errors.append('Phase flipping cannot be performed unless CTF information is provided.') + + if self.doNormalize: + if self.backRadius > int(self.boxSize.get()/2): + errors.append("Background radius for normalization should be " + "equal or less than half of the box size.") + self._setupCtfProperties() # setup self.micKey among others if self.ctfRelations.hasValue() and self.micKey is None: - validateMsgs.append('Some problem occurs matching micrographs and CTF.\n' + errors.append('Some problem occurs matching micrographs and CTF.\n' 'There were micrographs for which CTF was not found\n' 'either using micName or micId.\n') - return validateMsgs + return errors def _citations(self): return ['Vargas2013b'] diff --git a/pyworkflow/em/packages/xmipp3/protocol_extract_particles_movies.py b/pyworkflow/em/packages/xmipp3/protocol_extract_particles_movies.py index fff8e89cb9..ec4dc6c693 100644 --- a/pyworkflow/em/packages/xmipp3/protocol_extract_particles_movies.py +++ b/pyworkflow/em/packages/xmipp3/protocol_extract_particles_movies.py @@ -41,12 +41,14 @@ from pyworkflow.em.packages.xmipp3 import coordinateToRow, XmippMdRow + class XmippProtExtractMovieParticles(ProtExtractMovieParticles): """ Extract a set of Particles from each frame of a set of Movies. """ - _label = 'movie extract particles' - def __init__(self, **args): - ProtExtractMovieParticles.__init__(self, **args) + _label = 'movie extract particles' + + def __init__(self, **kwargs): + ProtExtractMovieParticles.__init__(self, **kwargs) self.stepsExecutionMode = STEPS_PARALLEL #--------------------------- DEFINE param functions -------------------------------------------- @@ -60,10 +62,16 @@ def _defineParams(self, form): help='In pixels. The box size is the size of the boxed particles, ' 'actual particles may be smaller than this.') form.addParam('applyAlignment', BooleanParam, default=False, - label='Apply alignments to extract?') - + label='Apply alignments to extract?', + help='If the input movies contains frames alignment, ' + 'you decide whether to use that information ' + 'for extracting the particles taking into account ' + 'the shifts between frames.') line = form.addLine('Frames range', - help='') + help='Specify the frames range to extract particles from.\n' + ' _First_: 1 will be the first frame in the movie.\n' + ' _Last_: For any value <= 0, the range will go until ' + 'the last frame. ') line.addParam('firstFrame', IntParam, default=1, label='First') line.addParam('lastFrame', IntParam, default=0, diff --git a/pyworkflow/em/packages/xmipp3/viewer.py b/pyworkflow/em/packages/xmipp3/viewer.py index 72ef3783fa..720e11416d 100644 --- a/pyworkflow/em/packages/xmipp3/viewer.py +++ b/pyworkflow/em/packages/xmipp3/viewer.py @@ -107,51 +107,37 @@ def visualize(self, obj, **args): for v in self._views: v.show() - + + def __createTemporaryCtfs(self, obj, setOfMics): + pwutils.cleanPath(obj._getPath("ctfs_temporary.sqlite")) + self.protocol._createFilenameTemplates() + ctfSet = self.protocol._createSetOfCTF("_temporary") + + for mic in setOfMics: + micDir = obj._getExtraPath(removeBaseExt(mic.getFileName())) + ctfparam = self.protocol._getFileName('ctfparam', micDir=micDir) + + if exists(ctfparam) or exists('xmipp_default_ctf.ctfparam'): + if not os.path.exists(ctfparam): + ctfparam = 'xmipp_default_ctf.ctfparam' + ctfModel = readCTFModel(ctfparam, mic) + self.protocol._setPsdFiles(ctfModel, micDir) + ctfSet.append(ctfModel) + + if not ctfSet.isEmpty(): + ctfSet.write() + ctfSet.close() + + return ctfSet + def _visualize(self, obj, **args): cls = type(obj) - def _getMicrographDir(mic): - """ Return an unique dir name for results of the micrograph. """ - return obj._getExtraPath(removeBaseExt(mic.getFileName())) - - def iterMicrographs(mics): - """ Iterate over micrographs and yield - micrograph name and a directory to process. - """ - for mic in mics: - micFn = mic.getFileName() - micDir = _getMicrographDir(mic) - yield (micFn, micDir, mic) - - def visualizeCTFObjs(obj, setOfMics): - - if exists(obj._getPath("ctfs_temporary.sqlite")): - os.remove(obj._getPath("ctfs_temporary.sqlite")) - self.protocol._createFilenameTemplates() - - ctfSet = self.protocol._createSetOfCTF("_temporary") - - for fn, micDir, mic in iterMicrographs(setOfMics): - ctfparam = self.protocol._getFileName('ctfparam', micDir=micDir) - - if exists(ctfparam) or exists('xmipp_default_ctf.ctfparam'): - if not os.path.exists(ctfparam): - ctfparam = 'xmipp_default_ctf.ctfparam' - - ctfModel = readCTFModel(ctfparam, mic) - self.protocol._setPsdFiles(ctfModel, micDir) - ctfSet.append(ctfModel) - - if ctfSet.getSize() < 1: - raise Exception("Has not been completed the CTT estimation of any micrograph") - else: - ctfSet.write() - ctfSet.close() - self._visualize(ctfSet) if issubclass(cls, Volume): fn = getImageLocation(obj) - self._views.append(ObjectView(self._project, obj.strId(), fn, viewParams={RENDER: 'image', SAMPLINGRATE: obj.getSamplingRate()})) + self._views.append(ObjectView(self._project, obj.strId(), fn, + viewParams={RENDER: 'image', + SAMPLINGRATE: obj.getSamplingRate()})) elif issubclass(cls, Image): fn = getImageLocation(obj) @@ -161,7 +147,9 @@ def visualizeCTFObjs(obj, setOfMics): elif issubclass(cls, SetOfNormalModes): fn = obj.getFileName() objCommands = "'%s' '%s'" % (OBJCMD_NMA_PLOTDIST, OBJCMD_NMA_VMD) - self._views.append(ObjectView(self._project, self.protocol.strId(), fn, obj.strId(), viewParams={OBJCMDS: objCommands}, **args)) + self._views.append(ObjectView(self._project, self.protocol.strId(), + fn, obj.strId(), + viewParams={OBJCMDS: objCommands}, **args)) elif issubclass(cls, SetOfMovies): fn = obj.getFileName() @@ -178,10 +166,6 @@ def visualizeCTFObjs(obj, setOfMics): elif issubclass(cls, MicrographsTiltPair): -# fnU = obj.getUntilted().getFileName() -# fnT = obj.getTilted().getFileName() -# self._views.append(ObjectView(self._project.getName(), obj.strId(), fnU, **args)) -# self._views.append(ObjectView(self._project.getName(), obj.strId(), fnT, **args)) labels = 'id enabled _untilted._filename _tilted._filename' self._views.append(ObjectView(self._project, obj.strId(), obj.getFileName(), viewParams={ORDER: labels, @@ -193,16 +177,15 @@ def visualizeCTFObjs(obj, setOfMics): labels = 'id enabled _untilted._filename _tilted._filename' self._views.append(ObjectView(self._project, obj.strId(), obj.getFileName(), viewParams={ORDER: labels, - VISIBLE: labels, RENDER:'_untilted._filename _tilted._filename', + VISIBLE: labels, + RENDER:'_untilted._filename _tilted._filename', MODE: MODE_MD})) - elif issubclass(cls, SetOfCoordinates): micSet = obj.getMicrographs() # accessing mics to provide metadata file if micSet is None: raise Exception('visualize: SetOfCoordinates has no micrographs set.') - mdFn = getattr(micSet, '_xmippMd', None) if mdFn: fn = mdFn.get() @@ -210,23 +193,16 @@ def visualizeCTFObjs(obj, setOfMics): fn = self._getTmpPath(micSet.getName() + '_micrographs.xmd') writeSetOfMicrographs(micSet, fn) tmpDir = self._getTmpPath(obj.getName()) - if os.path.exists(tmpDir): - r = dialog.askYesNoCancel("Question", - "It seems that you have edited this SetOfCoordinates before.\n" - "Do you wish to load the changes?\n\n" - "_Note_: If you choose *No*, the original coordinates will be loaded\n" - " and previous changes will be lost.", self._tkRoot) - - if r == dialog.RESULT_CANCEL: - return - elif r == dialog.RESULT_NO: - cleanPath(tmpDir) - makePath(tmpDir) - writeSetOfCoordinates(tmpDir, obj)# always write set of coordinates instead of reading pos dir, that could have changed - else: - makePath(tmpDir) - writeSetOfCoordinates(tmpDir, obj)# always write set of coordinates instead of reading pos dir, that could have changed - + cleanPath(tmpDir) + makePath(tmpDir) + # FIXME: (JMRT) We are always writing the SetOfCoordinates and removing + # the tmpDir, we need to take into account if the user have pick + # some particles in the tmpDir and have not save them, that now + # will loose all picked partices. + # A possible solution could be to alert that changes have not been + # written during modification of tmpDir or create a new Xmipp picking + # protocol to continue picking later without loosing the coordinates. + writeSetOfCoordinates(tmpDir, obj) self._views.append(CoordinatesObjectView(self._project, fn, tmpDir, self.protocol)) elif issubclass(cls, SetOfParticles): @@ -236,13 +212,17 @@ def visualizeCTFObjs(obj, setOfMics): self._views.append(ObjectView(self._project, obj.strId(), fn, viewParams={ORDER: labels, VISIBLE: labels, - 'sortby': '_xmipp_zScore asc', RENDER:'_filename'})) + 'sortby': '_xmipp_zScore asc', + RENDER:'_filename'})) elif issubclass(cls, SetOfVolumes): fn = obj.getFileName() labels = 'id enabled comment _filename ' self._views.append(ObjectView(self._project, obj.strId(), fn, - viewParams={MODE: MODE_MD, ORDER: labels, VISIBLE: labels, RENDER: '_filename'})) + viewParams={MODE: MODE_MD, + ORDER: labels, + VISIBLE: labels, + RENDER: '_filename'})) elif issubclass(cls, SetOfClasses2D): fn = obj.getFileName() @@ -252,22 +232,20 @@ def visualizeCTFObjs(obj, setOfMics): fn = obj.getFileName() self._views.append(Classes3DView(self._project, obj.strId(), fn)) - if issubclass(cls, XmippProtCTFMicrographs) and not obj.hasAttribute("outputCTF"): - mics = obj.inputMicrographs.get() - visualizeCTFObjs(obj, mics) + if issubclass(cls, XmippProtCTFMicrographs): + if obj.hasAttribute('outputCTF'): + ctfSet = obj.outputCTF + else: + mics = obj.inputMicrographs.get() + ctfSet = self.__createTemporaryCtfs(obj, mics) + + if ctfSet.isEmpty(): + self._views.append(self.infoMessage("No CTF estimation has finished yet")) + else: + self._views.append(CtfView(self._project, ctfSet)) - elif obj.hasAttribute("outputCTF"): - self._visualize(obj.outputCTF) - elif issubclass(cls, SetOfCTF): - fn = obj.getFileName() -# self._views.append(DataView(fn, viewParams={MODE: 'metadata'})) - psdLabels = '_psdFile _xmipp_enhanced_psd _xmipp_ctfmodel_quadrant _xmipp_ctfmodel_halfplane' - labels = 'id enabled label %s _defocusU _defocusV _defocusAngle _defocusRatio ' \ - '_xmipp_ctfCritFirstZero _xmipp_ctfCritCorr13 _xmipp_ctfCritFitting _xmipp_ctfCritNonAstigmaticValidity ' \ - '_xmipp_ctfCritCtfMargin _xmipp_ctfCritMaxFreq _micObj._filename' % psdLabels #TODO:CHECK IF _xmipp_ctfCritNonAstigmaticValidity AND _xmipp_ctfCritCtfMargin exist sometimes. - self._views.append(ObjectView(self._project, obj.strId(), fn, - viewParams={MODE: MODE_MD, ORDER: labels, VISIBLE: labels, ZOOM: 50, RENDER: psdLabels})) + self._views.append(CtfView(self._project, obj)) elif issubclass(cls, CoordinatesTiltPair): tmpDir = self._getTmpPath(obj.getName()) diff --git a/pyworkflow/em/protocol/protocol_sets.py b/pyworkflow/em/protocol/protocol_sets.py index a150355e12..238b708bcc 100644 --- a/pyworkflow/em/protocol/protocol_sets.py +++ b/pyworkflow/em/protocol/protocol_sets.py @@ -48,7 +48,7 @@ class ProtUnionSet(ProtSets): selected sets. It will validate that all sets are of the same type of elements (Micrographs, Particles or Volumes) """ - _label = 'union sets' + _label = 'join sets' _unionTypes = ['Particles', 'Micrographs', 'CTFs', diff --git a/pyworkflow/em/viewer.py b/pyworkflow/em/viewer.py index 4b4c15e707..7f7f1d3c63 100644 --- a/pyworkflow/em/viewer.py +++ b/pyworkflow/em/viewer.py @@ -144,13 +144,52 @@ def __init__(self, project, inputid, path, other='', viewParams={}, **kwargs): def getShowJParams(self): # mandatory to provide scipion params - params = DataView.getShowJParams(self) + ' --scipion %s %s %s'%(self.port, self.inputid, self.other) + params = DataView.getShowJParams(self) + ' --scipion %s %s %s' % (self.port, self.inputid, self.other) return params def show(self): showj.runJavaIJapp(self._memory, 'xmipp.viewer.scipion.ScipionViewer', self.getShowJParams(), env=self._env) - + +class CtfView(ObjectView): + """ Customized ObjectView for SetOfCTF objects . """ + # All extra labels that we want to show if present in the CTF results + PSD_LABELS = ['_psdFile', '_xmipp_enhanced_psd', + '_xmipp_ctfmodel_quadrant', '_xmipp_ctfmodel_halfplane' + ] + EXTRA_LABELS = ['_ctffind4_ctfResolution', '_xmipp_ctfCritFirstZero', + ' _xmipp_ctfCritCorr13', '_xmipp_ctfCritFitting', + '_xmipp_ctfCritNonAstigmaticValidity', + '_xmipp_ctfCritCtfMargin', '_xmipp_ctfCritMaxFreq' + ] + def __init__(self, project, ctfSet, other='', **kwargs): + first = ctfSet.getFirstItem() + + def existingLabels(labelList): + return ' '.join([l for l in labelList if first.hasAttribute(l)]) + + psdLabels = existingLabels(self.PSD_LABELS) + extraLabels = existingLabels(self.EXTRA_LABELS) + labels = 'id enabled comment %s _defocusU _defocusV ' % psdLabels + labels += '_defocusAngle _defocusRatio %s _micObj._filename' % extraLabels + viewParams = {showj.MODE: showj.MODE_MD, + showj.ORDER: labels, + showj.VISIBLE: labels, + showj.ZOOM: 50 + } + + if psdLabels: + viewParams[showj.RENDER] = psdLabels + + if first.hasAttribute('_ctffind4_ctfResolution'): + viewParams[showj.OBJCMDS] = "'%s'" % showj.OBJCMD_CTFFIND4 + + inputId = ctfSet.getObjId() or ctfSet.getFileName() + ObjectView.__init__(self, project, + inputId, ctfSet.getFileName(), other, + viewParams, **kwargs) + + class ClassesView(ObjectView): """ Customized ObjectView for SetOfClasses. """ def __init__(self, project, inputid, path, other='', viewParams={}, **kwargs): diff --git a/pyworkflow/object.py b/pyworkflow/object.py index 9979b7e2ed..9d9da8c30b 100644 --- a/pyworkflow/object.py +++ b/pyworkflow/object.py @@ -818,7 +818,7 @@ def __len__(self): return list.__len__(self) def isEmpty(self): - return len(self) > 0 + return len(self) == 0 def clear(self): del self[:] @@ -973,6 +973,9 @@ def __len__(self): def getSize(self): """Return the number of images""" return self._size.get() + + def isEmpty(self): + return self.getSize() == 0 def getFileName(self): if len(self._mapperPath): diff --git a/pyworkflow/tests/em/protocols/test_protocols_grigoriefflab.py b/pyworkflow/tests/em/protocols/test_protocols_grigoriefflab.py index 9351096368..de8d217265 100644 --- a/pyworkflow/tests/em/protocols/test_protocols_grigoriefflab.py +++ b/pyworkflow/tests/em/protocols/test_protocols_grigoriefflab.py @@ -167,7 +167,7 @@ def setUpClass(cls): cls.protImport = cls.runImportMicrographBPV(cls.micFn) def testCtffind(self): - protCTF = ProtCTFFind(useCftfind4=False) + protCTF = ProtCTFFind(useCtffind4=False) protCTF.inputMicrographs.set(self.protImport.outputMicrographs) protCTF.ctfDownFactor.set(2) protCTF.numberOfThreads.set(4) @@ -182,7 +182,7 @@ def testCtffind(self): self.assertAlmostEquals(ctfModel.getMicrograph().getSamplingRate(), 2.474, delta=0.001) def testCtffind2(self): - protCTF = ProtCTFFind(useCftfind4=False) + protCTF = ProtCTFFind(useCtffind4=False) protCTF.inputMicrographs.set(self.protImport.outputMicrographs) protCTF.numberOfThreads.set(4) self.proj.launchProtocol(protCTF, wait=True) diff --git a/scipion b/scipion index c19746deee..b48a35619b 100755 --- a/scipion +++ b/scipion @@ -40,7 +40,7 @@ except ImportError: __version__ = 'v1.0.0' __nickname__ = 'Augusto' -__releasedate__ = '2016-02-15' +__releasedate__ = '2016-02-20' # This script tries to run ok with any python version. So we cannot diff --git a/software/em/xmipp/java/src/xmipp/viewer/ctf/CTFAnalyzerJFrame.java b/software/em/xmipp/java/src/xmipp/viewer/ctf/CTFAnalyzerJFrame.java index 4418056342..5afc4b0973 100644 --- a/software/em/xmipp/java/src/xmipp/viewer/ctf/CTFAnalyzerJFrame.java +++ b/software/em/xmipp/java/src/xmipp/viewer/ctf/CTFAnalyzerJFrame.java @@ -32,6 +32,7 @@ import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; +import xmipp.jni.ImageGeneric; import xmipp.jni.CTFDescription; import xmipp.jni.MDLabel; import xmipp.jni.MetaData; @@ -39,6 +40,9 @@ import xmipp.utils.XmippFileChooser; import xmipp.utils.XmippLabel; import xmipp.utils.XmippWindowUtil; +import xmipp.ij.commons.XmippImageConverter; + + public class CTFAnalyzerJFrame extends JFrame implements ActionListener { @@ -77,81 +81,91 @@ public class CTFAnalyzerJFrame extends JFrame implements ActionListener private final static Color COLOR_DIFFERENCE = Color.orange; private ImagePlus profileimp; - - public CTFAnalyzerJFrame(ImagePlus imp, String ctffile, String psdfile) + + public CTFAnalyzerJFrame(String psdEnhancedFile, String ctffile, String psdfile) { - try - { - - this.imp = imp; - this.psdfile = psdfile; - this.profileimp = new ImagePlus(psdfile); - ctfmodel = new CTFDescription(ctffile); + try + { + this.imp = this.getThumbnail(psdEnhancedFile); + this.psdfile = psdfile; + this.profileimp = this.getThumbnail(psdfile); + ctfmodel = new CTFDescription(ctffile); double samplingRate = getSamplingRate(ctffile); - samples = imp.getWidth() / 2; - xvalues = getXValues(samples, samplingRate); - initComponents(); - - } - catch (Exception e) - { - throw new IllegalArgumentException(e); - } + samples = this.imp.getWidth() / 2; + xvalues = getXValues(samples, samplingRate); + initComponents(); + } catch (Exception e) { + e.printStackTrace(); + } } - public CTFAnalyzerJFrame(ImagePlus imp, CTFDescription ctfdescription, String psdfile, double samplingRate) + public CTFAnalyzerJFrame(String psdEnhancedFile, CTFDescription ctfdescription, String psdfile, double samplingRate) { - try - { - - this.imp = imp; - this.psdfile = psdfile; - this.profileimp = new ImagePlus(psdfile); - ctfmodel = ctfdescription; - samples = imp.getWidth() / 2; - xvalues = getXValues(samples, samplingRate); - initComponents(); - } - catch (Exception e) - { - throw new IllegalArgumentException(e); - } + try + { + this.imp = this.getThumbnail(psdEnhancedFile); + this.psdfile = psdfile; + this.profileimp = this.getThumbnail(psdfile); + ctfmodel = ctfdescription; + samples = this.imp.getWidth() / 2; + xvalues = getXValues(samples, samplingRate); + initComponents(); + } catch (Exception e) { + e.printStackTrace(); + } } - - private void initComponents() + + /* Load the image with a size of 256 pixels. */ + private ImagePlus getThumbnail(String imagefile) + { + ImagePlus imp = null; + try { - setTitle("CTF Analyzer"); - fc = new XmippFileChooser(); - - constraints = new GridBagConstraints(); - constraints.insets = new Insets(0, 5, 0, 5); - constraints.anchor = GridBagConstraints.NORTHWEST; - // constraints.fill = GridBagConstraints.HORIZONTAL; - setLayout(new GridBagLayout()); - JPanel contentpn = new JPanel(new GridBagLayout()); - contentpn.setBorder(BorderFactory.createEtchedBorder()); - add(contentpn, XmippWindowUtil.getConstraints(constraints, 0, 0)); - imagepn = new JPanel(new GridBagLayout()); - imagepn.setBorder(BorderFactory.createTitledBorder("PSD Image")); - imageprofilepn = new CTFAnalyzerImagePane(imp, this); - imagepn.add(imageprofilepn, XmippWindowUtil.getConstraints(constraints, 0, 0)); - contentpn.add(imagepn, XmippWindowUtil.getConstraints(constraints, 0, 0, 1)); - - initGraphicPanes(); - contentpn.add(actionspn, XmippWindowUtil.getConstraints(constraints, 0, 1, 1, 1)); - contentpn.add(graphicpn, XmippWindowUtil.getConstraints(constraints, 1, 0, 1, 3)); - - JPanel actionspn = new JPanel(); - exportbt = XmippWindowUtil.getTextButton("Export Graphics", this); - actionspn.add(exportbt, XmippWindowUtil.getConstraints(constraints, 0, 1)); + ImageGeneric img = new ImageGeneric(imagefile); + img.read(256, 256, ImageGeneric.FIRST_IMAGE); + imp = XmippImageConverter.readToImagePlus(img); + // Free the C-image memory + img.destroy(); + } catch (Exception e) { + e.printStackTrace(); + } + return imp; + } + + private void initComponents() + { + setTitle("CTF Analyzer"); + fc = new XmippFileChooser(); + + constraints = new GridBagConstraints(); + constraints.insets = new Insets(0, 5, 0, 5); + constraints.anchor = GridBagConstraints.NORTHWEST; + // constraints.fill = GridBagConstraints.HORIZONTAL; + setLayout(new GridBagLayout()); + JPanel contentpn = new JPanel(new GridBagLayout()); + contentpn.setBorder(BorderFactory.createEtchedBorder()); + add(contentpn, XmippWindowUtil.getConstraints(constraints, 0, 0)); + imagepn = new JPanel(new GridBagLayout()); + imagepn.setBorder(BorderFactory.createTitledBorder("PSD Image")); + imageprofilepn = new CTFAnalyzerImagePane(imp, this); + imagepn.add(imageprofilepn, XmippWindowUtil.getConstraints(constraints, 0, 0)); + contentpn.add(imagepn, XmippWindowUtil.getConstraints(constraints, 0, 0, 1)); + + initGraphicPanes(); + contentpn.add(actionspn, XmippWindowUtil.getConstraints(constraints, 0, 1, 1, 1)); + contentpn.add(graphicpn, XmippWindowUtil.getConstraints(constraints, 1, 0, 1, 3)); + + JPanel actionspn = new JPanel(); + exportbt = XmippWindowUtil.getTextButton("Export Graphics", this); + actionspn.add(exportbt, XmippWindowUtil.getConstraints(constraints, 0, 1)); // exportavgbt = XmippWindowUtil.getTextButton("Export Average Graphics", this); // actionspn.add(exportavgbt, XmippWindowUtil.getConstraints(constraints, 1, 1)); - add(actionspn, XmippWindowUtil.getConstraints(constraints, 0, 1)); - enableDisplay(); - pack(); - setVisible(true); - } + add(actionspn, XmippWindowUtil.getConstraints(constraints, 0, 1)); + enableDisplay(); + pack(); + setVisible(true); + } private void initGraphicPanes() { @@ -257,9 +271,8 @@ private void fillAvgGraphics() line = new Line(x0, y0, x1, y1); imp.setRoi(line); - profileimp.setRoi(line); + profileimp.setRoi(line); // Get profile. - ProfilePlot profilePlot = new ProfilePlot(profileimp); psdprofile_avgplot = profilePlot.getProfile(); @@ -312,7 +325,7 @@ private void fillRadialGraphics() line = new Line(x0, y0, imageprofilepn.getX1(), imageprofilepn.getY1()); imp.setRoi(line); - profileimp.setRoi(line); + profileimp.setRoi(line); psdprofileplot = new ProfilePlot(profileimp).getProfile(); diff --git a/software/em/xmipp/java/src/xmipp/viewer/models/GalleryData.java b/software/em/xmipp/java/src/xmipp/viewer/models/GalleryData.java index 124e8d90f7..ad021c76c4 100644 --- a/software/em/xmipp/java/src/xmipp/viewer/models/GalleryData.java +++ b/software/em/xmipp/java/src/xmipp/viewer/models/GalleryData.java @@ -1745,24 +1745,30 @@ public void showCTF(boolean profile, int row, boolean[] selection, TasksEngine c String psd = md.getPSDFile(id); String psden = md.getPSDEnhanced(id); - ImageGeneric img; - if(psden != null) - img = new ImageGeneric(psden); - else - img = new ImageGeneric(psd); - ImagePlus imp = XmippImageConverter.readToImagePlus(img); - - - if (profile) { - if( psden == null) - new CTFAnalyzerJFrame(imp, md.getCTFDescription(id), psd, md.getEllipseCTF(id).getSamplingRate()); + + boolean noPsdEnhanced = (psden == null); + // Use the same PSD image in case no PSD enhanced + + if (noPsdEnhanced) + psden = psd; + + if (profile) + { + if (noPsdEnhanced) + new CTFAnalyzerJFrame(psden, md.getCTFDescription(id), psd, md.getEllipseCTF(id).getSamplingRate()); else - new CTFAnalyzerJFrame(imp, md.getCTFFile(id), psd); - } else { + new CTFAnalyzerJFrame(psden, md.getCTFFile(id), psd); + } + else + { + ImageGeneric img = new ImageGeneric(psden); + ImagePlus imp = XmippImageConverter.readToImagePlus(img); + img.destroy(); EllipseCTF ctfparams = md.getEllipseCTF(id, imp.getWidth()); String sortfn = createSortFile(psd, row); - XmippUtil.showImageJ(Tool.VIEWER);// removed Toolbar.FREEROI - CTFRecalculateImageWindow ctfiw = new CTFRecalculateImageWindow(this, selection, imp, psd, ctfparams, ctfTasks, row, sortfn); + XmippUtil.showImageJ(Tool.VIEWER); // removed Toolbar.FREEROI + CTFRecalculateImageWindow ctfiw = new CTFRecalculateImageWindow(this, selection, imp, psd, ctfparams, + ctfTasks, row, sortfn); } } catch (Exception e) { diff --git a/software/em/xmipp/java/src/xmipp/viewer/particlepicker/extract/ExtractPickerJFrame.java b/software/em/xmipp/java/src/xmipp/viewer/particlepicker/extract/ExtractPickerJFrame.java index 204386aa0d..53bc572402 100644 --- a/software/em/xmipp/java/src/xmipp/viewer/particlepicker/extract/ExtractPickerJFrame.java +++ b/software/em/xmipp/java/src/xmipp/viewer/particlepicker/extract/ExtractPickerJFrame.java @@ -163,9 +163,7 @@ public void actionPerformed(ActionEvent arg0) String psd = getMicrograph().getPSD(); String ctf = getMicrograph().getCTF(); if (psd != null && ctf != null) - new CTFAnalyzerJFrame(getMicrograph().getPSDImage(), getMicrograph().getCTF(), getMicrograph().getPSD()); - - + new CTFAnalyzerJFrame(psd, ctf, psd); } }); micrographsmd = new ExtractMicrographsTableModel(); diff --git a/software/em/xmipp/java/src/xmipp/viewer/particlepicker/training/gui/SupervisedPickerJFrame.java b/software/em/xmipp/java/src/xmipp/viewer/particlepicker/training/gui/SupervisedPickerJFrame.java index e302dfcc57..407192aa74 100644 --- a/software/em/xmipp/java/src/xmipp/viewer/particlepicker/training/gui/SupervisedPickerJFrame.java +++ b/software/em/xmipp/java/src/xmipp/viewer/particlepicker/training/gui/SupervisedPickerJFrame.java @@ -628,7 +628,7 @@ public void actionPerformed(ActionEvent arg0) { String ctf = getMicrograph().getCTF(); if (psd != null && ctf != null) { try { - new CTFAnalyzerJFrame(getMicrograph().getPSDImage(), getMicrograph().getCTF(), getMicrograph().getPSD()); + new CTFAnalyzerJFrame(psd, ctf, psd); } catch (Exception ex) { Logger.getLogger(SupervisedPickerJFrame.class.getName()).log(Level.SEVERE, null, ex); }