scipion-em-xmipp 24.6.0.0__py3-none-any.whl → 24.12.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {scipion_em_xmipp-24.6.0.0.dist-info → scipion_em_xmipp-24.12.2.dist-info}/METADATA +8 -7
- {scipion_em_xmipp-24.6.0.0.dist-info → scipion_em_xmipp-24.12.2.dist-info}/RECORD +51 -47
- {scipion_em_xmipp-24.6.0.0.dist-info → scipion_em_xmipp-24.12.2.dist-info}/WHEEL +1 -1
- xmipp3/__init__.py +110 -92
- xmipp3/checkProtocolsConf.py +117 -0
- xmipp3/constants.py +3 -0
- xmipp3/convert/convert.py +31 -10
- xmipp3/protocols/__init__.py +4 -2
- xmipp3/protocols/protocol_apply_tilt_to_ctf.py +114 -0
- xmipp3/protocols/protocol_cl2d.py +1 -1
- xmipp3/protocols/protocol_cl2d_clustering.py +303 -0
- xmipp3/protocols/protocol_classify_pca.py +3 -1
- xmipp3/protocols/protocol_classify_pca_streaming.py +1 -0
- xmipp3/protocols/protocol_compare_reprojections.py +2 -2
- xmipp3/protocols/protocol_convert_pdb.py +9 -4
- xmipp3/protocols/protocol_create_gallery.py +84 -12
- xmipp3/protocols/protocol_ctf_consensus.py +186 -273
- xmipp3/protocols/protocol_ctf_defocus_group.py +4 -4
- xmipp3/protocols/protocol_ctf_micrographs.py +12 -1
- xmipp3/protocols/protocol_deep_center.py +2 -2
- xmipp3/protocols/protocol_deep_center_predict.py +140 -0
- xmipp3/protocols/protocol_extract_particles.py +1 -1
- xmipp3/protocols/protocol_flexalign.py +46 -47
- xmipp3/protocols/protocol_mics_defocus_balancer.py +341 -0
- xmipp3/protocols/protocol_movie_alignment_consensus.py +1 -1
- xmipp3/protocols/protocol_movie_dose_analysis.py +159 -77
- xmipp3/protocols/protocol_movie_gain.py +5 -1
- xmipp3/protocols/protocol_movie_max_shift.py +246 -178
- xmipp3/protocols/protocol_reconstruct_fourier.py +29 -14
- xmipp3/protocols/protocol_reconstruct_highres.py +15 -2
- xmipp3/protocols/protocol_simulate_ctf.py +1 -1
- xmipp3/protocols/protocol_subtract_projection.py +89 -28
- xmipp3/protocols/protocol_tilt_analysis.py +95 -191
- xmipp3/protocols/protocol_trigger_data.py +22 -12
- xmipp3/protocols/protocol_validate_fscq.py +1 -1
- xmipp3/protocols/protocol_volume_adjust_sub.py +0 -4
- xmipp3/protocols/protocol_volume_local_sharpening.py +34 -24
- xmipp3/protocols.conf +141 -115
- xmipp3/tests/test_protocols_deepcenter_predict.py +66 -0
- xmipp3/tests/test_protocols_xmipp_2d.py +27 -7
- xmipp3/tests/test_protocols_xmipp_3d.py +16 -755
- xmipp3/tests/test_protocols_xmipp_mics.py +43 -4
- xmipp3/tests/test_protocols_xmipp_movies.py +0 -169
- xmipp3/version.py +38 -0
- xmipp3/viewers/__init__.py +3 -1
- xmipp3/viewers/viewer_apply_tilt_to_ctf.py +81 -0
- xmipp3/viewers/viewer_cl2d_clustering.py +131 -0
- xmipp3/viewers/viewer_movie_alignment.py +3 -9
- xmipp3/protocols/protocol_angular_resolution_alignment.py +0 -204
- xmipp3/protocols/protocol_movie_opticalflow.py +0 -416
- xmipp3/tests/test_protocols_angular_resolution_alignment.py +0 -88
- xmipp3/tests/test_protocols_mixed_movies.py +0 -149
- xmipp3/viewers/viewer_angular_resolution_alignment.py +0 -148
- {scipion_em_xmipp-24.6.0.0.dist-info → scipion_em_xmipp-24.12.2.dist-info}/LICENSE +0 -0
- {scipion_em_xmipp-24.6.0.0.dist-info → scipion_em_xmipp-24.12.2.dist-info}/entry_points.txt +0 -0
- {scipion_em_xmipp-24.6.0.0.dist-info → scipion_em_xmipp-24.12.2.dist-info}/top_level.txt +0 -0
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# * Roberto Marabini (roberto@cnb.csic.es)
|
|
5
5
|
# * Tomas Majtner (tmajtner@cnb.csic.es) -- streaming version
|
|
6
6
|
# * Amaya Jimenez (ajimenez@cnb.csic.es)
|
|
7
|
+
# * Daniel Marchan (da.marchan@cnb.csic.es) --refactor streaming
|
|
7
8
|
# *
|
|
8
9
|
# * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
|
|
9
10
|
# *
|
|
@@ -41,7 +42,7 @@ import pyworkflow.utils as pwutils
|
|
|
41
42
|
from pwem.protocols import ProtCTFMicrographs
|
|
42
43
|
from pwem.emlib.metadata import Row
|
|
43
44
|
from pyworkflow.protocol.constants import (STATUS_NEW)
|
|
44
|
-
from pyworkflow import
|
|
45
|
+
from pyworkflow import UPDATED
|
|
45
46
|
|
|
46
47
|
from pwem import emlib
|
|
47
48
|
import xmipp3
|
|
@@ -52,6 +53,11 @@ DISCARDED = 'Discarded'
|
|
|
52
53
|
INPUT1 = 1
|
|
53
54
|
INPUT2 = 2
|
|
54
55
|
|
|
56
|
+
OUTPUT_CTF = "outputCTF"
|
|
57
|
+
OUTPUT_MICS = "outputMicrographs"
|
|
58
|
+
OUTPUT_CTF_DISCARDED = "outputCTFDiscarded"
|
|
59
|
+
OUTPUT_MICS_DISCARDED = "outputMicrographsDiscarded"
|
|
60
|
+
|
|
55
61
|
class XmippProtCTFConsensus(ProtCTFMicrographs):
|
|
56
62
|
"""
|
|
57
63
|
Protocol to make a selection of meaningful CTFs in basis of the defocus
|
|
@@ -59,13 +65,18 @@ class XmippProtCTFConsensus(ProtCTFMicrographs):
|
|
|
59
65
|
the agreement with a secondary CTF for the same set of micrographs.
|
|
60
66
|
"""
|
|
61
67
|
_label = 'ctf consensus'
|
|
62
|
-
_devStatus =
|
|
68
|
+
_devStatus = UPDATED
|
|
63
69
|
_lastUpdateVersion = VERSION_3_0
|
|
70
|
+
_possibleOutputs = {OUTPUT_MICS: SetOfMicrographs,
|
|
71
|
+
OUTPUT_MICS_DISCARDED: SetOfMicrographs,
|
|
72
|
+
OUTPUT_CTF: SetOfCTF,
|
|
73
|
+
OUTPUT_CTF_DISCARDED: SetOfCTF
|
|
74
|
+
}
|
|
75
|
+
|
|
64
76
|
|
|
65
77
|
def __init__(self, **args):
|
|
66
78
|
ProtCTFMicrographs.__init__(self, **args)
|
|
67
79
|
self._freqResol = {}
|
|
68
|
-
self.stepsExecutionMode = params.STEPS_PARALLEL
|
|
69
80
|
|
|
70
81
|
def _defineParams(self, form):
|
|
71
82
|
form.addSection(label='Input')
|
|
@@ -191,29 +202,30 @@ class XmippProtCTFConsensus(ProtCTFMicrographs):
|
|
|
191
202
|
'If *No*, only the primary metadata (plus consensus '
|
|
192
203
|
'scores) will be in the resulting CTF.')
|
|
193
204
|
|
|
194
|
-
form.addParallelSection(threads=4, mpi=1)
|
|
195
205
|
|
|
196
206
|
# --------------------------- INSERT steps functions -------------------------
|
|
197
207
|
def _insertAllSteps(self):
|
|
198
208
|
self.initializeParams()
|
|
199
209
|
if self.calculateConsensus:
|
|
200
210
|
self.ctfFn2 = self.inputCTF2.get().getFileName()
|
|
201
|
-
self.allCtf2 = {}
|
|
202
211
|
|
|
203
|
-
self._insertFunctionStep(
|
|
204
|
-
prerequisites=[], wait=True)
|
|
212
|
+
self._insertFunctionStep(self.createOutputStep,
|
|
213
|
+
prerequisites=[], wait=True, needsGPU=False)
|
|
205
214
|
|
|
206
215
|
def createOutputStep(self):
|
|
207
216
|
self._closeOutputSet()
|
|
208
217
|
|
|
209
218
|
def initializeParams(self):
|
|
210
219
|
self.finished = False
|
|
211
|
-
self.
|
|
220
|
+
self.isStreamClosed = False
|
|
221
|
+
# Important to have both:
|
|
222
|
+
self.insertedIds = [] # Contains images that have been inserted in a Step (checkNewInput).
|
|
223
|
+
# Contains images that have been processed in a Step (checkNewOutput).
|
|
224
|
+
self.acceptedIds = {}
|
|
225
|
+
self.discardedIds = {}
|
|
212
226
|
self.initializeRejDict()
|
|
213
227
|
self.setSecondaryAttributes()
|
|
214
228
|
self.ctfFn1 = self.inputCTF.get().getFileName()
|
|
215
|
-
self.allCtf1 = {}
|
|
216
|
-
pwutils.makePath(self._getExtraPath('DONE'))
|
|
217
229
|
|
|
218
230
|
def _getFirstJoinStepName(self):
|
|
219
231
|
# This function will be used for streaming, to check which is
|
|
@@ -228,43 +240,15 @@ class XmippProtCTFConsensus(ProtCTFMicrographs):
|
|
|
228
240
|
return s
|
|
229
241
|
return None
|
|
230
242
|
|
|
231
|
-
|
|
232
|
-
def _insertNewCtfsSteps(self, newIDs1, newIDs2, insertedDict):
|
|
243
|
+
def _insertNewCtfsSteps(self, newIds):
|
|
233
244
|
deps = []
|
|
245
|
+
stepId = self._insertFunctionStep(self.selectCtfStep, newIds, needsGPU=False,
|
|
246
|
+
prerequisites=[])
|
|
247
|
+
deps.append(stepId)
|
|
234
248
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
md2 = emlib.MetaData()
|
|
238
|
-
|
|
239
|
-
for ctfID in newIDs:
|
|
240
|
-
if ctfID not in insertedDict:
|
|
241
|
-
ctf1 = self.allCtf1.get(ctfID)
|
|
242
|
-
ctf2 = self.allCtf2.get(ctfID)
|
|
243
|
-
try:
|
|
244
|
-
self._ctfToMd(ctf1, md1)
|
|
245
|
-
self._ctfToMd(ctf2, md2)
|
|
246
|
-
self._freqResol[ctfID] = emlib.errorMaxFreqCTFs2D(md1, md2)
|
|
247
|
-
except TypeError as exc:
|
|
248
|
-
print("Error reading ctf for id:%s. %s" % (ctfID, exc))
|
|
249
|
-
self._freqResol[ctfID] = 9999
|
|
250
|
-
|
|
251
|
-
stepId = self._insertFunctionStep('selectCtfStep', ctfID,
|
|
252
|
-
prerequisites=[])
|
|
253
|
-
deps.append(stepId)
|
|
254
|
-
insertedDict[ctfID] = stepId
|
|
255
|
-
|
|
256
|
-
return deps
|
|
249
|
+
for ctfId in newIds:
|
|
250
|
+
self.insertedIds.append(ctfId)
|
|
257
251
|
|
|
258
|
-
def _insertNewSelectionSteps(self, insertedDict, newIDs):
|
|
259
|
-
deps = []
|
|
260
|
-
# For each ctf insert the step to process it
|
|
261
|
-
for ctfID in newIDs:
|
|
262
|
-
|
|
263
|
-
if ctfID not in insertedDict:
|
|
264
|
-
stepId = self._insertFunctionStep('selectCtfStep', ctfID,
|
|
265
|
-
prerequisites=[])
|
|
266
|
-
deps.append(stepId)
|
|
267
|
-
insertedDict[ctfID] = stepId
|
|
268
252
|
return deps
|
|
269
253
|
|
|
270
254
|
def _stepsCheck(self):
|
|
@@ -282,88 +266,70 @@ class XmippProtCTFConsensus(ProtCTFMicrographs):
|
|
|
282
266
|
pwutils.prettyTime(mTime)))
|
|
283
267
|
# If the input movies.sqlite have not changed since our last check,
|
|
284
268
|
# it does not make sense to check for new input data
|
|
285
|
-
if self.lastCheck > mTime and
|
|
269
|
+
if self.lastCheck > mTime and self.insertedIds: # If this is empty it is dut to a static "continue" action or it is the first round
|
|
286
270
|
return None
|
|
287
271
|
|
|
288
272
|
ctfsSet1 = self._loadInputCtfSet(self.ctfFn1)
|
|
289
273
|
ctfsSet2 = self._loadInputCtfSet(self.ctfFn2)
|
|
290
274
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
ctfDict2 = {ctf.getObjId(): ctf.clone() for ctf
|
|
295
|
-
in ctfsSet2.iterItems()}
|
|
275
|
+
ctfSet1Ids = ctfsSet1.getIdSet()
|
|
276
|
+
ctfSet2Ids = ctfsSet2.getIdSet()
|
|
296
277
|
|
|
297
|
-
newIds1 = [
|
|
298
|
-
self.
|
|
278
|
+
newIds1 = [idCTF for idCTF in ctfSet1Ids if idCTF not in self.insertedIds]
|
|
279
|
+
newIds2 = [idCTF for idCTF in ctfSet2Ids if idCTF not in self.insertedIds]
|
|
299
280
|
|
|
300
|
-
|
|
301
|
-
self.allCtf2.update(ctfDict2)
|
|
281
|
+
newIds = list(set(newIds1).intersection(set(newIds2)))
|
|
302
282
|
|
|
303
283
|
self.lastCheck = datetime.now()
|
|
304
284
|
self.isStreamClosed = ctfsSet1.isStreamClosed() and \
|
|
305
285
|
ctfsSet2.isStreamClosed()
|
|
306
286
|
ctfsSet1.close()
|
|
307
287
|
ctfsSet2.close()
|
|
308
|
-
|
|
309
|
-
outputStep = self._getFirstJoinStep()
|
|
310
|
-
if len(set(self.allCtf1)) > len(set(self.insertedDict)) and \
|
|
311
|
-
len(set(self.allCtf2)) > len(set(self.insertedDict)):
|
|
312
|
-
fDeps = self._insertNewCtfsSteps(newIds1, newIds2,
|
|
313
|
-
self.insertedDict)
|
|
314
|
-
if outputStep is not None:
|
|
315
|
-
outputStep.addPrerequisites(*fDeps)
|
|
316
|
-
self.updateSteps()
|
|
317
288
|
else:
|
|
318
|
-
|
|
319
|
-
self.lastCheck = getattr(self, 'lastCheck', now)
|
|
289
|
+
self.lastCheck = getattr(self, 'lastCheck', datetime.now())
|
|
320
290
|
mTime = datetime.fromtimestamp(os.path.getmtime(self.ctfFn1))
|
|
321
291
|
self.debug('Last check: %s, modification: %s'
|
|
322
292
|
% (pwutils.prettyTime(self.lastCheck),
|
|
323
293
|
pwutils.prettyTime(mTime)))
|
|
324
294
|
# If the input ctfs.sqlite have not changed since our last check,
|
|
325
295
|
# it does not make sense to check for new input data
|
|
326
|
-
if self.lastCheck > mTime and
|
|
296
|
+
if self.lastCheck > mTime and self.insertedIds:
|
|
327
297
|
return None
|
|
328
298
|
|
|
329
299
|
# Open input ctfs.sqlite and close it as soon as possible
|
|
330
300
|
ctfSet = self._loadInputCtfSet(self.ctfFn1)
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
newIds = [idCTF for idCTF in ctfDict.keys() if idCTF not in self.insertedDict]
|
|
335
|
-
self.allCtf1.update(ctfDict)
|
|
301
|
+
ctfSetIds = ctfSet.getIdSet()
|
|
302
|
+
newIds = [idCTF for idCTF in ctfSetIds if idCTF not in self.insertedIds]
|
|
336
303
|
|
|
304
|
+
self.lastCheck = datetime.now()
|
|
337
305
|
self.isStreamClosed = ctfSet.isStreamClosed()
|
|
338
306
|
ctfSet.close()
|
|
339
307
|
|
|
340
|
-
|
|
341
|
-
newCtf = any(ctf.getObjId() not in
|
|
342
|
-
self.insertedDict for ctf in self.allCtf1.values())
|
|
343
|
-
outputStep = self._getFirstJoinStep()
|
|
308
|
+
outputStep = self._getFirstJoinStep()
|
|
344
309
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
310
|
+
if self.isContinued() and not self.insertedIds: # For "Continue" action and the first round
|
|
311
|
+
doneIds, _, _, _ = self._getAllDoneIds()
|
|
312
|
+
skipIds = list(set(newIds).intersection(set(doneIds)))
|
|
313
|
+
newIds = list(set(newIds).difference(set(doneIds)))
|
|
314
|
+
self.info("Skipping CTFs with ID: %s, seems to be done" % skipIds)
|
|
315
|
+
self.insertedIds = doneIds # During the first round of "Continue" action it has to be filled
|
|
316
|
+
|
|
317
|
+
if newIds:
|
|
318
|
+
fDeps = self._insertNewCtfsSteps(newIds)
|
|
319
|
+
if outputStep is not None:
|
|
320
|
+
outputStep.addPrerequisites(*fDeps)
|
|
321
|
+
self.updateSteps()
|
|
351
322
|
|
|
352
323
|
|
|
353
324
|
def _checkNewOutput(self):
|
|
354
325
|
""" Check for already selected CTF and update the output set. """
|
|
355
|
-
|
|
356
|
-
# Load previously done items (from text file)
|
|
357
|
-
doneListDiscarded = self._readCertainDoneList(DISCARDED)
|
|
358
|
-
doneListAccepted = self._readCertainDoneList(ACCEPTED)
|
|
359
|
-
|
|
326
|
+
_, _, doneListAccepted, doneListDiscarded = self._getAllDoneIds()
|
|
360
327
|
# Check for newly done items
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
newDoneAccepted = [ctfId for ctfId in ctfListIdAccepted
|
|
328
|
+
acceptedIds = list(self.acceptedIds)
|
|
329
|
+
discardedIds = list(self.discardedIds)
|
|
330
|
+
newDoneAccepted = [ctfId for ctfId in acceptedIds
|
|
365
331
|
if ctfId not in doneListAccepted]
|
|
366
|
-
newDoneDiscarded = [ctfId for ctfId in
|
|
332
|
+
newDoneDiscarded = [ctfId for ctfId in discardedIds
|
|
367
333
|
if ctfId not in doneListDiscarded]
|
|
368
334
|
|
|
369
335
|
firstTimeAccepted = len(doneListAccepted) == 0
|
|
@@ -374,14 +340,21 @@ class XmippProtCTFConsensus(ProtCTFMicrographs):
|
|
|
374
340
|
# We have finished when there is not more input ctf (stream closed)
|
|
375
341
|
# and the number of processed ctf is equal to the number of inputs
|
|
376
342
|
if self.calculateConsensus:
|
|
377
|
-
|
|
343
|
+
inputCtfSet = self._loadInputCtfSet(self.ctfFn1)
|
|
344
|
+
inputCtfSet2 = self._loadInputCtfSet(self.ctfFn2)
|
|
345
|
+
maxCtfSize = min(inputCtfSet.getSize(), inputCtfSet2.getSize())
|
|
378
346
|
else:
|
|
379
|
-
maxCtfSize =
|
|
347
|
+
maxCtfSize = self._loadInputCtfSet(self.ctfFn1).getSize()
|
|
380
348
|
|
|
381
349
|
self.finished = (self.isStreamClosed and allDone == maxCtfSize)
|
|
382
350
|
|
|
383
351
|
streamMode = Set.STREAM_CLOSED if self.finished else Set.STREAM_OPEN
|
|
384
352
|
|
|
353
|
+
if not self.finished and (not newDoneDiscarded and not newDoneAccepted):
|
|
354
|
+
# If we are not finished and no new output have been produced
|
|
355
|
+
# it does not make sense to proceed and updated the outputs
|
|
356
|
+
# so we exit from the function here
|
|
357
|
+
return
|
|
385
358
|
|
|
386
359
|
def readOrCreateOutputs(doneList, newDone, label=''):
|
|
387
360
|
if len(doneList) > 0 or len(newDone) > 0:
|
|
@@ -399,28 +372,20 @@ class XmippProtCTFConsensus(ProtCTFMicrographs):
|
|
|
399
372
|
newDoneDiscarded,
|
|
400
373
|
DISCARDED)
|
|
401
374
|
|
|
402
|
-
if not self.finished and not newDoneDiscarded and not newDoneAccepted:
|
|
403
|
-
# If we are not finished and no new output have been produced
|
|
404
|
-
# it does not make sense to proceed and updated the outputs
|
|
405
|
-
# so we exit from the function here
|
|
406
|
-
return
|
|
407
|
-
|
|
408
375
|
def updateRelationsAndClose(cSet, mSet, first, label=''):
|
|
409
376
|
|
|
410
377
|
if os.path.exists(self._getPath('ctfs'+label+'.sqlite')):
|
|
411
378
|
|
|
412
|
-
micsAttrName =
|
|
379
|
+
micsAttrName = OUTPUT_MICS+label
|
|
413
380
|
self._updateOutputSet(micsAttrName, mSet, streamMode)
|
|
414
|
-
# Set micrograph as pointer to protocol to prevent
|
|
381
|
+
# Set micrograph as pointer to protocol to prevent pointer end up as another attribute (String, Booelan,...)
|
|
415
382
|
# that happens somewhere while scheduling.
|
|
416
383
|
cSet.setMicrographs(Pointer(self, extended=micsAttrName))
|
|
417
384
|
|
|
418
|
-
self._updateOutputSet(
|
|
385
|
+
self._updateOutputSet(OUTPUT_CTF+label, cSet, streamMode)
|
|
419
386
|
|
|
420
387
|
if first:
|
|
421
|
-
self._defineTransformRelation(self.inputCTF.get().getMicrographs(),
|
|
422
|
-
mSet)
|
|
423
|
-
# self._defineTransformRelation(cSet, mSet)
|
|
388
|
+
self._defineTransformRelation(self.inputCTF.get().getMicrographs(), mSet)
|
|
424
389
|
self._defineTransformRelation(self.inputCTF, cSet)
|
|
425
390
|
self._defineCtfRelation(mSet, cSet)
|
|
426
391
|
|
|
@@ -436,6 +401,8 @@ class XmippProtCTFConsensus(ProtCTFMicrographs):
|
|
|
436
401
|
if outputStep and outputStep.isWaiting():
|
|
437
402
|
outputStep.setStatus(STATUS_NEW)
|
|
438
403
|
|
|
404
|
+
self._store() # Update the summary dictionary
|
|
405
|
+
|
|
439
406
|
|
|
440
407
|
def fillOutput(self, ctfSet, micSet, newDone, label):
|
|
441
408
|
if newDone:
|
|
@@ -446,8 +413,8 @@ class XmippProtCTFConsensus(ProtCTFMicrographs):
|
|
|
446
413
|
ctf = inputCtfSet[ctfId].clone()
|
|
447
414
|
mic = ctf.getMicrograph().clone()
|
|
448
415
|
|
|
449
|
-
ctf.setEnabled(self._getEnable(ctfId))
|
|
450
|
-
mic.setEnabled(self._getEnable(ctfId))
|
|
416
|
+
ctf.setEnabled(self._getEnable(ctfId, label))
|
|
417
|
+
mic.setEnabled(self._getEnable(ctfId, label))
|
|
451
418
|
|
|
452
419
|
if self.calculateConsensus:
|
|
453
420
|
ctf2 = inputCtfSet2[ctfId]
|
|
@@ -502,7 +469,6 @@ class XmippProtCTFConsensus(ProtCTFMicrographs):
|
|
|
502
469
|
|
|
503
470
|
ctfSet.append(ctf)
|
|
504
471
|
micSet.append(mic)
|
|
505
|
-
self._writeCertainDoneList(ctfId, label)
|
|
506
472
|
|
|
507
473
|
inputCtfSet.close()
|
|
508
474
|
if self.calculateConsensus:
|
|
@@ -573,18 +539,17 @@ class XmippProtCTFConsensus(ProtCTFMicrographs):
|
|
|
573
539
|
setattr(self, "rejBy"+k, Integer(0))
|
|
574
540
|
self._store()
|
|
575
541
|
|
|
576
|
-
def selectCtfStep(self,
|
|
577
|
-
# Depending on the flags selected by the user, we set the values of
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
542
|
+
def selectCtfStep(self, ctfIds):
|
|
543
|
+
# Depending on the flags selected by the user, we set the values of the params to compare with
|
|
544
|
+
minDef, maxDef = self._getDefociValues()
|
|
545
|
+
maxAstig = self._getMaxAstisgmatism()
|
|
546
|
+
maxAstigPer = self._getMaxAstigmatismPer()
|
|
547
|
+
minResol = self._getMinResol()
|
|
581
548
|
|
|
582
|
-
|
|
583
|
-
self.info("Skipping CTF with ID: %s, seems to be done" % ctfId)
|
|
584
|
-
return
|
|
549
|
+
inputCtfSet = self._loadInputCtfSet(self.ctfFn1)
|
|
585
550
|
|
|
586
|
-
|
|
587
|
-
|
|
551
|
+
if self.calculateConsensus:
|
|
552
|
+
inputCtfSet2 = self._loadInputCtfSet(self.ctfFn2)
|
|
588
553
|
|
|
589
554
|
def compareValue(ctf, label, comp, crit):
|
|
590
555
|
""" Returns True if the ctf.label NOT complain the crit by comp
|
|
@@ -603,125 +568,112 @@ class XmippProtCTFConsensus(ProtCTFMicrographs):
|
|
|
603
568
|
self.discDict[label] += 1
|
|
604
569
|
return discard
|
|
605
570
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
maxAstigPer = self._getMaxAstigmatismPer()
|
|
609
|
-
minResol = self._getMinResol()
|
|
571
|
+
for ctfId in ctfIds:
|
|
572
|
+
ctf = inputCtfSet.getItem("id", ctfId).clone()
|
|
610
573
|
|
|
611
|
-
|
|
574
|
+
defocusU = ctf.getDefocusU()
|
|
575
|
+
defocusV = ctf.getDefocusV()
|
|
576
|
+
astigm = abs(defocusU - defocusV)
|
|
577
|
+
astigmPer = abs(defocusU - defocusV)/((defocusU+defocusV)/2)
|
|
578
|
+
resol = self._getCtfResol(ctf)
|
|
612
579
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
resol = self._getCtfResol(ctf)
|
|
580
|
+
defRangeCrit = (defocusU < minDef or defocusU > maxDef or
|
|
581
|
+
defocusV < minDef or defocusV > maxDef)
|
|
582
|
+
if defRangeCrit:
|
|
583
|
+
self.discDict['defocus'] += 1
|
|
618
584
|
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
self.discDict['defocus'] += 1
|
|
585
|
+
astigCrit = astigm > maxAstig
|
|
586
|
+
if astigCrit:
|
|
587
|
+
self.discDict['astigmatism'] += 1
|
|
623
588
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
589
|
+
astigPer = (astigmPer > maxAstigPer)
|
|
590
|
+
if astigPer:
|
|
591
|
+
self.discDict['astigmatismPer'] += 1
|
|
627
592
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
593
|
+
singleResolCrit = resol > minResol
|
|
594
|
+
if singleResolCrit:
|
|
595
|
+
self.discDict['singleResolution'] += 1
|
|
631
596
|
|
|
632
|
-
|
|
633
|
-
if singleResolCrit:
|
|
634
|
-
self.discDict['singleResolution'] += 1
|
|
597
|
+
firstCondition = defRangeCrit or astigCrit or singleResolCrit or astigPer
|
|
635
598
|
|
|
636
|
-
|
|
599
|
+
consResolCrit = False
|
|
637
600
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
consResolCrit = self.minConsResol < self._freqResol[ctfId]
|
|
601
|
+
if self.calculateConsensus:
|
|
602
|
+
ctf2 = inputCtfSet2.getItem("id", ctfId)
|
|
603
|
+
freqResolConsensus = self.calculateConsensusResolution(ctfId, ctf, ctf2)
|
|
604
|
+
consResolCrit = self.minConsResol < freqResolConsensus
|
|
643
605
|
if consResolCrit:
|
|
644
606
|
self.discDict['consensusResolution'] += 1
|
|
645
|
-
else:
|
|
646
|
-
consResolCrit = True
|
|
647
|
-
self.discDict['consensusResolution'] += 1
|
|
648
|
-
self._freqResol[ctfId] = 9999
|
|
649
|
-
|
|
650
|
-
secondCondition = False
|
|
651
|
-
if self.useCritXmipp:
|
|
652
|
-
firstZero = self._getCritFirstZero()
|
|
653
|
-
minFirstZero, maxFirstZero = self._getCritFirstZeroRatio()
|
|
654
|
-
corr = self._getCritCorr()
|
|
655
|
-
iceness = self._getIceness()
|
|
656
|
-
ctfMargin = self._getCritCtfMargin()
|
|
657
|
-
minNonAstigmatic, maxNonAstigmatic = \
|
|
658
|
-
self._getCritNonAstigmaticValidity()
|
|
659
|
-
|
|
660
|
-
if self.xmippCTF == INPUT1:
|
|
661
|
-
ctfX = ctf
|
|
662
|
-
else:
|
|
663
|
-
ctfX = self.allCtf2.get(ctfId)
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
secondCondition = (
|
|
667
|
-
compareValue(ctfX, '_xmipp_ctfCritFirstZero', 'lt', firstZero) or
|
|
668
|
-
compareValue(ctfX, '_xmipp_ctfCritfirstZeroRatio', 'lt', minFirstZero) or
|
|
669
|
-
compareValue(ctfX, '_xmipp_ctfCritfirstZeroRatio', 'bt', maxFirstZero) or
|
|
670
|
-
compareValue(ctfX, '_xmipp_ctfCritCorr13', 'lt', corr) or
|
|
671
|
-
compareValue(ctfX, '_xmipp_ctfCritIceness', 'bt', iceness) or
|
|
672
|
-
compareValue(ctfX, '_xmipp_ctfCritCtfMargin', 'lt', ctfMargin) or
|
|
673
|
-
compareValue(ctfX, '_xmipp_ctfCritNonAstigmaticValidty', 'lt', minNonAstigmatic) or
|
|
674
|
-
compareValue(ctfX, '_xmipp_ctfCritNonAstigmaticValidty', 'bt', maxNonAstigmatic))
|
|
675
|
-
|
|
676
|
-
""" Write to a text file the items that have been done. """
|
|
677
|
-
if firstCondition or consResolCrit or secondCondition:
|
|
678
|
-
fn = self._getCtfSelecFileDiscarded()
|
|
679
|
-
with open(fn, 'a') as f:
|
|
680
|
-
f.write('%d F\n' % ctf.getObjId())
|
|
681
|
-
else:
|
|
682
|
-
if (ctf.isEnabled()):
|
|
683
|
-
fn = self._getCtfSelecFileAccepted()
|
|
684
|
-
with open(fn, 'a') as f:
|
|
685
|
-
f.write('%d T\n' % ctf.getObjId())
|
|
686
|
-
else:
|
|
687
|
-
fn = self._getCtfSelecFileAccepted()
|
|
688
|
-
with open(fn, 'a') as f:
|
|
689
|
-
f.write('%d F\n' % ctf.getObjId())
|
|
690
|
-
|
|
691
|
-
for k, v in self.discDict.items():
|
|
692
|
-
setattr(self, "rejBy"+k, Integer(v))
|
|
693
|
-
|
|
694
|
-
self._store()
|
|
695
|
-
# Mark this ctf as finished
|
|
696
|
-
open(doneFn, 'w').close()
|
|
697
|
-
|
|
698
607
|
|
|
699
|
-
|
|
700
|
-
""" Read from a file the id's of the items that have been done. """
|
|
701
|
-
doneFile = self._getAllDone()
|
|
702
|
-
doneList = []
|
|
703
|
-
# Check what items have been previously done
|
|
704
|
-
if os.path.exists(doneFile):
|
|
705
|
-
with open(doneFile) as f:
|
|
706
|
-
doneList += [int(line.strip()) for line in f]
|
|
707
|
-
return doneList
|
|
608
|
+
self._freqResol[ctfId] = freqResolConsensus
|
|
708
609
|
|
|
709
|
-
|
|
710
|
-
|
|
610
|
+
secondCondition = False
|
|
611
|
+
if self.useCritXmipp:
|
|
612
|
+
firstZero = self._getCritFirstZero()
|
|
613
|
+
minFirstZero, maxFirstZero = self._getCritFirstZeroRatio()
|
|
614
|
+
corr = self._getCritCorr()
|
|
615
|
+
iceness = self._getIceness()
|
|
616
|
+
ctfMargin = self._getCritCtfMargin()
|
|
617
|
+
minNonAstigmatic, maxNonAstigmatic = \
|
|
618
|
+
self._getCritNonAstigmaticValidity()
|
|
711
619
|
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
620
|
+
if self.xmippCTF == INPUT1:
|
|
621
|
+
ctfX = ctf
|
|
622
|
+
else:
|
|
623
|
+
ctfX = ctf2
|
|
624
|
+
|
|
625
|
+
secondCondition = (
|
|
626
|
+
compareValue(ctfX, '_xmipp_ctfCritFirstZero', 'lt', firstZero) or
|
|
627
|
+
compareValue(ctfX, '_xmipp_ctfCritfirstZeroRatio', 'lt', minFirstZero) or
|
|
628
|
+
compareValue(ctfX, '_xmipp_ctfCritfirstZeroRatio', 'bt', maxFirstZero) or
|
|
629
|
+
compareValue(ctfX, '_xmipp_ctfCritCorr13', 'lt', corr) or
|
|
630
|
+
compareValue(ctfX, '_xmipp_ctfCritIceness', 'bt', iceness) or
|
|
631
|
+
compareValue(ctfX, '_xmipp_ctfCritCtfMargin', 'lt', ctfMargin) or
|
|
632
|
+
compareValue(ctfX, '_xmipp_ctfCritNonAstigmaticValidty', 'lt', minNonAstigmatic) or
|
|
633
|
+
compareValue(ctfX, '_xmipp_ctfCritNonAstigmaticValidty', 'bt', maxNonAstigmatic))
|
|
634
|
+
|
|
635
|
+
""" Write to a text file the items that have been done. """
|
|
636
|
+
if firstCondition or consResolCrit or secondCondition:
|
|
637
|
+
self.discardedIds[ctfId] = 'F'
|
|
638
|
+
else:
|
|
639
|
+
if (ctf.isEnabled()):
|
|
640
|
+
self.acceptedIds[ctfId] = 'T'
|
|
641
|
+
else:
|
|
642
|
+
self.acceptedIds[ctfId] = 'F'
|
|
717
643
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
return os.path.exists(self._getCTFDone(id))
|
|
644
|
+
for k, v in self.discDict.items():
|
|
645
|
+
setattr(self, "rejBy"+k, Integer(v))
|
|
721
646
|
|
|
722
|
-
def
|
|
723
|
-
|
|
724
|
-
|
|
647
|
+
def calculateConsensusResolution(self, ctfId, ctf1, ctf2):
|
|
648
|
+
md1 = emlib.MetaData()
|
|
649
|
+
md2 = emlib.MetaData()
|
|
650
|
+
try:
|
|
651
|
+
self._ctfToMd(ctf1, md1)
|
|
652
|
+
self._ctfToMd(ctf2, md2)
|
|
653
|
+
freqResol = emlib.errorMaxFreqCTFs2D(md1, md2)
|
|
654
|
+
except TypeError as exc:
|
|
655
|
+
print("Error reading ctf for id:%s. %s" % (ctfId, exc))
|
|
656
|
+
freqResol = 9999
|
|
657
|
+
|
|
658
|
+
return freqResol
|
|
659
|
+
|
|
660
|
+
def _getAllDoneIds(self):
|
|
661
|
+
doneIds = []
|
|
662
|
+
acceptedIds = []
|
|
663
|
+
discardedIds = []
|
|
664
|
+
sizeOutput = 0
|
|
665
|
+
|
|
666
|
+
if hasattr(self, OUTPUT_CTF):
|
|
667
|
+
sizeOutput += self.outputCTF.getSize()
|
|
668
|
+
acceptedIds.extend(list(self.outputCTF.getIdSet()))
|
|
669
|
+
doneIds.extend(acceptedIds)
|
|
670
|
+
|
|
671
|
+
if hasattr(self, OUTPUT_CTF_DISCARDED):
|
|
672
|
+
sizeOutput += self.outputCTFDiscarded.getSize()
|
|
673
|
+
discardedIds.extend(list(self.outputCTFDiscarded.getIdSet()))
|
|
674
|
+
doneIds.extend(discardedIds)
|
|
675
|
+
|
|
676
|
+
return doneIds, sizeOutput, acceptedIds, discardedIds
|
|
725
677
|
|
|
726
678
|
def _citations(self):
|
|
727
679
|
return ['Marabini2014a']
|
|
@@ -764,13 +716,13 @@ class XmippProtCTFConsensus(ProtCTFMicrographs):
|
|
|
764
716
|
addDiscardedStr('astigmatismPer')))
|
|
765
717
|
|
|
766
718
|
if self.useResolution:
|
|
767
|
-
message.append(" - _Resolution_. Threshold: %.
|
|
719
|
+
message.append(" - _Resolution_. Threshold: %.2f %s"
|
|
768
720
|
% (self.resolution,
|
|
769
721
|
addDiscardedStr('singleResolution')))
|
|
770
722
|
|
|
771
723
|
if self.useCritXmipp:
|
|
772
724
|
message.append("*Xmipp criteria*:")
|
|
773
|
-
message.append(" - _First zero_. Threshold: %.
|
|
725
|
+
message.append(" - _First zero_. Threshold: %.2f %s"
|
|
774
726
|
% (self.critFirstZero,
|
|
775
727
|
addDiscardedStr('_xmipp_ctfCritFirstZero')))
|
|
776
728
|
message.append(" - _First zero astigmatism_. Range: %.2f - %.2f %s"
|
|
@@ -804,7 +756,7 @@ class XmippProtCTFConsensus(ProtCTFMicrographs):
|
|
|
804
756
|
return infoStr
|
|
805
757
|
|
|
806
758
|
message.append("*CTF consensus*:")
|
|
807
|
-
message.append(" - _Consensus resolution. Threshold_: %.
|
|
759
|
+
message.append(" - _Consensus resolution. Threshold_: %.2f %s"
|
|
808
760
|
% (self.minConsResol,
|
|
809
761
|
addDiscardedStr('consensusResolution')))
|
|
810
762
|
message.append(" > _Primary CTF_: %s"
|
|
@@ -849,55 +801,16 @@ class XmippProtCTFConsensus(ProtCTFMicrographs):
|
|
|
849
801
|
else:
|
|
850
802
|
return 0
|
|
851
803
|
|
|
852
|
-
def
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
if
|
|
859
|
-
|
|
860
|
-
doneList += [int(line.strip()) for line in f]
|
|
861
|
-
return doneList
|
|
862
|
-
|
|
863
|
-
def _writeCertainDoneList(self, ctfId, label):
|
|
864
|
-
""" Write to a text file the items that have been done. """
|
|
865
|
-
doneFile = self._getCertainDone(label)
|
|
866
|
-
with open(doneFile, 'a') as f:
|
|
867
|
-
f.write('%d\n' % ctfId)
|
|
868
|
-
|
|
869
|
-
def _getCertainDone(self, label):
|
|
870
|
-
return self._getExtraPath('DONE_'+label+'.TXT')
|
|
871
|
-
|
|
872
|
-
def _getCtfSelecFileAccepted(self):
|
|
873
|
-
return self._getExtraPath('selection-ctf-accepted.txt')
|
|
874
|
-
|
|
875
|
-
def _getCtfSelecFileDiscarded(self):
|
|
876
|
-
return self._getExtraPath('selection-ctf-discarded.txt')
|
|
877
|
-
|
|
878
|
-
def _readtCtfId(self, accepted):
|
|
879
|
-
if accepted:
|
|
880
|
-
fn = self._getCtfSelecFileAccepted()
|
|
804
|
+
def _getEnable(self, ctfId, label):
|
|
805
|
+
if label == ACCEPTED:
|
|
806
|
+
enableValue = self.acceptedIds[ctfId]
|
|
807
|
+
else:
|
|
808
|
+
enableValue = self.discardedIds[ctfId]
|
|
809
|
+
|
|
810
|
+
if enableValue == 'T':
|
|
811
|
+
return True
|
|
881
812
|
else:
|
|
882
|
-
|
|
883
|
-
ctfList = []
|
|
884
|
-
# Check what items have been previously done
|
|
885
|
-
if os.path.exists(fn):
|
|
886
|
-
with open(fn) as f:
|
|
887
|
-
ctfList += [int(line.strip().split()[0]) for line in f]
|
|
888
|
-
return ctfList
|
|
889
|
-
|
|
890
|
-
def _getEnable(self, ctfId):
|
|
891
|
-
fn = self._getCtfSelecFileAccepted()
|
|
892
|
-
# Check what items have been previously done
|
|
893
|
-
if os.path.exists(fn):
|
|
894
|
-
with open(fn) as f:
|
|
895
|
-
for line in f:
|
|
896
|
-
if ctfId == int(line.strip().split()[0]):
|
|
897
|
-
if line.strip().split()[1] == 'T':
|
|
898
|
-
return True
|
|
899
|
-
else:
|
|
900
|
-
return False
|
|
813
|
+
return False
|
|
901
814
|
|
|
902
815
|
def _loadInputCtfSet(self, ctfFn):
|
|
903
816
|
self.debug("Loading input db: %s" % ctfFn)
|