scipion-em-xmipp 25.6.0__py3-none-any.whl → 26.0.0__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-25.6.0.dist-info → scipion_em_xmipp-26.0.0.dist-info}/METADATA +5 -2
- {scipion_em_xmipp-25.6.0.dist-info → scipion_em_xmipp-26.0.0.dist-info}/RECORD +60 -55
- {scipion_em_xmipp-25.6.0.dist-info → scipion_em_xmipp-26.0.0.dist-info}/WHEEL +1 -1
- xmipp3/__init__.py +11 -11
- xmipp3/constants.py +1 -1
- xmipp3/legacy/__init__.py +0 -0
- xmipp3/legacy/protocols/__init__.py +0 -0
- xmipp3/legacy/tests/test_protocols_xmipp_movies.py +134 -0
- xmipp3/logParser.py +53 -0
- xmipp3/protocols/__init__.py +1 -1
- xmipp3/protocols/protocol_align_volume.py +1 -1
- xmipp3/protocols/protocol_align_volume_and_particles.py +18 -10
- xmipp3/protocols/protocol_break_symmetry.py +5 -5
- xmipp3/protocols/protocol_classify_pca.py +21 -21
- xmipp3/protocols/protocol_classify_pca_streaming.py +18 -10
- xmipp3/protocols/protocol_compare_reprojections.py +2 -2
- xmipp3/protocols/protocol_compute_likelihood.py +1 -1
- xmipp3/protocols/protocol_convert_pdb.py +1 -1
- xmipp3/protocols/protocol_ctf_correct_phase.py +89 -0
- xmipp3/protocols/protocol_ctf_micrographs.py +0 -4
- xmipp3/protocols/protocol_deep_center.py +21 -10
- xmipp3/protocols/protocol_deep_center_predict.py +18 -8
- xmipp3/protocols/protocol_deep_hand.py +1 -1
- xmipp3/protocols/protocol_deep_micrograph_screen.py +23 -9
- xmipp3/protocols/protocol_extract_asymmetric_unit.py +21 -11
- xmipp3/protocols/protocol_extract_particles.py +1 -1
- xmipp3/protocols/protocol_movie_alignment_consensus.py +1 -1
- xmipp3/protocols/protocol_movie_max_shift.py +18 -12
- xmipp3/protocols/protocol_movie_split_frames.py +1 -1
- xmipp3/protocols/protocol_particle_pick_consensus.py +1 -1
- xmipp3/protocols/protocol_preprocess/protocol_create_mask3d.py +6 -6
- xmipp3/protocols/protocol_preprocess/protocol_crop_resize.py +23 -5
- xmipp3/protocols/protocol_preprocess/protocol_process.py +1 -1
- xmipp3/protocols/protocol_ransac.py +1 -1
- xmipp3/protocols/protocol_reconstruct_highres.py +32 -56
- xmipp3/protocols/protocol_reconstruct_significant.py +1 -1
- xmipp3/protocols/protocol_reconstruct_swarm.py +10 -10
- xmipp3/protocols/protocol_resolution3d.py +34 -29
- xmipp3/protocols/protocol_resolution_fso.py +1 -1
- xmipp3/protocols/protocol_resolution_monogenic_signal.py +1 -1
- xmipp3/protocols/protocol_screen_deepConsensus.py +22 -27
- xmipp3/protocols/protocol_shift_particles.py +6 -7
- xmipp3/protocols/protocol_shift_volume.py +23 -4
- xmipp3/protocols/protocol_simulate_ctf.py +1 -1
- xmipp3/protocols/protocol_subtract_projection.py +1 -1
- xmipp3/protocols/protocol_validate_fscq.py +1 -1
- xmipp3/protocols/protocol_volume_adjust_sub.py +1 -1
- xmipp3/protocols/protocol_volume_strain.py +4 -4
- xmipp3/protocolsCollectInfo.py +280 -0
- xmipp3/tests/test_protocols_highres.py +1 -1
- xmipp3/tests/test_protocols_xmipp_2d.py +11 -17
- xmipp3/tests/test_protocols_xmipp_3d.py +3 -3
- xmipp3/tests/test_protocols_xmipp_movies.py +10 -149
- xmipp3/version.py +13 -6
- xmipp3/viewers/viewer_consensus_classes.py +18 -4
- xmipp3/viewers/viewer_structure_map.py +166 -5
- {scipion_em_xmipp-25.6.0.dist-info → scipion_em_xmipp-26.0.0.dist-info}/entry_points.txt +0 -0
- {scipion_em_xmipp-25.6.0.dist-info → scipion_em_xmipp-26.0.0.dist-info/licenses}/LICENSE +0 -0
- {scipion_em_xmipp-25.6.0.dist-info → scipion_em_xmipp-26.0.0.dist-info}/top_level.txt +0 -0
- /xmipp3/{protocols → legacy/protocols}/protocol_extract_particles_movies.py +0 -0
|
@@ -38,6 +38,7 @@ from pyworkflow.utils import weakImport
|
|
|
38
38
|
from pyworkflow.utils.path import cleanPath
|
|
39
39
|
|
|
40
40
|
from xmipp3.constants import SYM_URL
|
|
41
|
+
from pyworkflow import BETA, UPDATED, NEW, PROD
|
|
41
42
|
|
|
42
43
|
ALIGN_MASK_CIRCULAR = 0
|
|
43
44
|
ALIGN_MASK_BINARY_FILE = 1
|
|
@@ -63,13 +64,14 @@ class XmippProtAlignVolumeParticles(ProtAlignVolume):
|
|
|
63
64
|
"""
|
|
64
65
|
_label = 'align volume and particles'
|
|
65
66
|
_possibleOutputs = AlignVolPartOutputs
|
|
67
|
+
_devStatus = UPDATED
|
|
66
68
|
nVols = 0
|
|
69
|
+
|
|
67
70
|
|
|
68
71
|
def __init__(self, **args):
|
|
69
72
|
ProtAlignVolume.__init__(self, **args)
|
|
70
73
|
|
|
71
74
|
# These 2 must match the output enum above.
|
|
72
|
-
self._alignmentMatrix = None
|
|
73
75
|
self.Volume = None
|
|
74
76
|
self.Particles = None
|
|
75
77
|
|
|
@@ -89,6 +91,8 @@ class XmippProtAlignVolumeParticles(ProtAlignVolume):
|
|
|
89
91
|
'calculated with the reference and input volumes.')
|
|
90
92
|
form.addParam('alignmentMode', params.EnumParam, default=ALIGN_GLOBAL, choices=["Global","Local"],
|
|
91
93
|
label="Alignment mode")
|
|
94
|
+
form.addParam('considerMirrors', params.BooleanParam, default=False,
|
|
95
|
+
label='Consider mirrors')
|
|
92
96
|
form.addParam('symmetryGroup', params.StringParam, default='c1',
|
|
93
97
|
label="Symmetry group",
|
|
94
98
|
help='See %s page for a description of the symmetries '
|
|
@@ -160,6 +164,8 @@ class XmippProtAlignVolumeParticles(ProtAlignVolume):
|
|
|
160
164
|
args += " --frm"
|
|
161
165
|
else:
|
|
162
166
|
args += " --local"
|
|
167
|
+
if self.considerMirrors:
|
|
168
|
+
args += " --consider_mirror"
|
|
163
169
|
args += " --copyGeo %s" % fhInputTranMat
|
|
164
170
|
if not self.wrap:
|
|
165
171
|
args += ' --dontWrap'
|
|
@@ -168,13 +174,16 @@ class XmippProtAlignVolumeParticles(ProtAlignVolume):
|
|
|
168
174
|
cleanPath(self.fnInputVol)
|
|
169
175
|
|
|
170
176
|
def getAlignmentMatrix(self):
|
|
171
|
-
|
|
172
|
-
if self._alignmentMatrix is None:
|
|
177
|
+
if not (hasattr(self, '_lhsAlignmentMatrix') and hasattr(self, '_rhsAlignmentMatrix')):
|
|
173
178
|
fhInputTranMat = self.getTransformationFile()
|
|
174
179
|
transMatFromFile = np.loadtxt(fhInputTranMat)
|
|
175
|
-
self.
|
|
180
|
+
self._lhsAlignmentMatrix = np.reshape(transMatFromFile, (4, 4))
|
|
181
|
+
self._rhsAlignmentMatrix = np.eye(4)
|
|
182
|
+
|
|
183
|
+
if np.linalg.det(self._lhsAlignmentMatrix[:3,:3]) < 0:
|
|
184
|
+
self._rhsAlignmentMatrix[2,2] = -1
|
|
176
185
|
|
|
177
|
-
return self.
|
|
186
|
+
return self._lhsAlignmentMatrix, self._rhsAlignmentMatrix
|
|
178
187
|
|
|
179
188
|
def getTransformationFile(self):
|
|
180
189
|
return self._getExtraPath('transformation-matrix.txt')
|
|
@@ -217,12 +226,11 @@ class XmippProtAlignVolumeParticles(ProtAlignVolume):
|
|
|
217
226
|
self._defineSourceRelation(self.inputParticles, outputParticles)
|
|
218
227
|
|
|
219
228
|
def _updateParticleTransform(self, particle, row):
|
|
229
|
+
lhs, rhs = self.getAlignmentMatrix()
|
|
230
|
+
alignment = np.array(particle.getTransform().getMatrix())
|
|
231
|
+
alignment2 = lhs @ alignment @ rhs
|
|
220
232
|
|
|
221
|
-
|
|
222
|
-
partTransformMat = particle.getTransform().getMatrix()
|
|
223
|
-
partTransformMatrix = np.matrix(partTransformMat)
|
|
224
|
-
newTransformMatrix = np.matmul(aliMatrix, partTransformMatrix)
|
|
225
|
-
particle.getTransform().setMatrix(newTransformMatrix)
|
|
233
|
+
particle.getTransform().setMatrix(alignment2)
|
|
226
234
|
|
|
227
235
|
def getOutputAlignedVolumePath(self):
|
|
228
236
|
outVolFn = self._getExtraPath("inputVolumeAligned.mrc")
|
|
@@ -40,7 +40,7 @@ class XmippProtAngBreakSymmetry(ProtProcessParticles):
|
|
|
40
40
|
equivalent angular assignment for a given symmetry.
|
|
41
41
|
|
|
42
42
|
Be aware that input symmetry values follows Xmipp conventions as described in:
|
|
43
|
-
|
|
43
|
+
https://i2pc.github.io/docs/Utils/Conventions/index.html#symmetry
|
|
44
44
|
"""
|
|
45
45
|
_label = 'break symmetry'
|
|
46
46
|
|
|
@@ -49,7 +49,7 @@ class XmippProtAngBreakSymmetry(ProtProcessParticles):
|
|
|
49
49
|
|
|
50
50
|
form.addParam('symmetryGroup', StringParam, default="c1",
|
|
51
51
|
label='Symmetry group',
|
|
52
|
-
help="See
|
|
52
|
+
help="See https://i2pc.github.io/docs/Utils/Conventions/index.html#symmetry"
|
|
53
53
|
" for a description of the symmetry groups format in Xmipp.\n"
|
|
54
54
|
"If no symmetry is present, use _c1_.")
|
|
55
55
|
|
|
@@ -63,9 +63,9 @@ class XmippProtAngBreakSymmetry(ProtProcessParticles):
|
|
|
63
63
|
# Create a metadata with the geometrical information
|
|
64
64
|
# as expected by Xmipp
|
|
65
65
|
imgsFn = self._getPath('input_particles.xmd')
|
|
66
|
-
self._insertFunctionStep(
|
|
67
|
-
self._insertFunctionStep(
|
|
68
|
-
self._insertFunctionStep(
|
|
66
|
+
self._insertFunctionStep(self.convertInputStep, imgsFn)
|
|
67
|
+
self._insertFunctionStep(self.breakSymmetryStep, imgsFn)
|
|
68
|
+
self._insertFunctionStep(self.createOutputStep)
|
|
69
69
|
|
|
70
70
|
#--------------------------- STEPS functions --------------------------------------------
|
|
71
71
|
|
|
@@ -84,23 +84,14 @@ ALIGNMENT_DICT = {"shiftX": XMIPPCOLUMNS.shiftX.value,
|
|
|
84
84
|
"angleTilt": XMIPPCOLUMNS.angleTilt.value
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def updateEnviron(gpuNum):
|
|
90
|
-
""" Create the needed environment for pytorch programs. """
|
|
91
|
-
print("updating environ to select gpu %s" % (gpuNum))
|
|
92
|
-
if gpuNum == '':
|
|
93
|
-
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
|
|
94
|
-
else:
|
|
95
|
-
os.environ['CUDA_VISIBLE_DEVICES'] = str(gpuNum)
|
|
96
|
-
|
|
97
87
|
CONTRAST_AVERAGES_FILE = 'classes_contrast_classes.star'
|
|
98
88
|
AVERAGES_IMAGES_FILE = 'classes_images.star'
|
|
99
89
|
|
|
100
90
|
class XmippProtClassifyPca(ProtClassify2D, XmippProtocol):
|
|
101
|
-
""" Classifies a set of images. """
|
|
91
|
+
""" Classifies a set of images using Principal Component Analysis (PCA). This 2D classification groups (the number of groups can be set) are based on their similarities, assisting in the identification of different conformational states or particle populations. """
|
|
102
92
|
|
|
103
|
-
_label
|
|
93
|
+
_label= '2D classification pca'
|
|
94
|
+
|
|
104
95
|
_lastUpdateVersion = VERSION_3_0
|
|
105
96
|
_conda_env = 'xmipp_pyTorch'
|
|
106
97
|
_devStatus = BETA
|
|
@@ -171,7 +162,6 @@ class XmippProtClassifyPca(ProtClassify2D, XmippProtocol):
|
|
|
171
162
|
def _insertAllSteps(self):
|
|
172
163
|
|
|
173
164
|
""" Mainly prepare the command line for call classification program"""
|
|
174
|
-
self.setGPU()
|
|
175
165
|
self.imgsOrigXmd = self._getExtraPath('images_original.xmd')
|
|
176
166
|
self.imgsXmd = self._getTmpPath('images.xmd')
|
|
177
167
|
self.imgsFn = self._getTmpPath('images.mrc')
|
|
@@ -198,13 +188,21 @@ class XmippProtClassifyPca(ProtClassify2D, XmippProtocol):
|
|
|
198
188
|
|
|
199
189
|
self._insertFunctionStep('createOutputStep')
|
|
200
190
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
191
|
+
|
|
192
|
+
def getGpusList(self, separator):
|
|
193
|
+
strGpus = ""
|
|
194
|
+
for elem in self._stepsExecutor.getGpuList():
|
|
195
|
+
strGpus = strGpus + str(elem) + separator
|
|
196
|
+
return strGpus[:-1]
|
|
197
|
+
|
|
198
|
+
def setGPU(self, oneGPU=False):
|
|
199
|
+
if oneGPU:
|
|
200
|
+
gpus = self.getGpusList(",")[0]
|
|
204
201
|
else:
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
self.
|
|
202
|
+
gpus = self.getGpusList(",")
|
|
203
|
+
os.environ["CUDA_VISIBLE_DEVICES"] = gpus
|
|
204
|
+
self.info(f'Visible GPUS: {gpus}')
|
|
205
|
+
return gpus
|
|
208
206
|
|
|
209
207
|
|
|
210
208
|
#--------------------------- STEPS functions -------------------------------
|
|
@@ -234,8 +232,9 @@ class XmippProtClassifyPca(ProtClassify2D, XmippProtocol):
|
|
|
234
232
|
|
|
235
233
|
|
|
236
234
|
def pcaTraining(self, inputIm, resolutionTrain, numTrain):
|
|
235
|
+
gpuId = self.setGPU(oneGPU=True)
|
|
237
236
|
args = ' -i %s -s %s -hr %s -lr 530 -p %s -t %s -o %s/train_pca --batchPCA -g %s'% \
|
|
238
|
-
(inputIm, self.sampling, resolutionTrain, self.coef.get(), numTrain, self._getExtraPath(),
|
|
237
|
+
(inputIm, self.sampling, resolutionTrain, self.coef.get(), numTrain, self._getExtraPath(), gpuId)
|
|
239
238
|
|
|
240
239
|
env = self.getCondaEnv()
|
|
241
240
|
env['LD_LIBRARY_PATH'] = ''
|
|
@@ -243,9 +242,10 @@ class XmippProtClassifyPca(ProtClassify2D, XmippProtocol):
|
|
|
243
242
|
|
|
244
243
|
|
|
245
244
|
def classification(self, inputIm, numClass, stfile, mask, sigma):
|
|
245
|
+
gpuId = self.setGPU(oneGPU=True)
|
|
246
246
|
args = ' -i %s -c %s -b %s/train_pca_bands.pt -v %s/train_pca_vecs.pt -o %s/classes -stExp %s -g %s' % \
|
|
247
247
|
(inputIm, numClass, self._getExtraPath(), self._getExtraPath(), self._getExtraPath(),
|
|
248
|
-
stfile,
|
|
248
|
+
stfile, gpuId)
|
|
249
249
|
if mask:
|
|
250
250
|
args += ' --mask --sigma %s '%(sigma)
|
|
251
251
|
|
|
@@ -162,8 +162,6 @@ class XmippProtClassifyPcaStreaming(ProtStreamingBase, XmippProtClassifyPca):
|
|
|
162
162
|
self._initFnStep()
|
|
163
163
|
|
|
164
164
|
def _initFnStep(self):
|
|
165
|
-
self.setGPU()
|
|
166
|
-
self.info(f'NUM GPUS: {self.numGPU}')
|
|
167
165
|
self.inputFn = self.inputParticles.get().getFileName()
|
|
168
166
|
self.imgsPcaXmd = self._getExtraPath('images_pca.xmd')
|
|
169
167
|
self.imgsPcaXmdOut = self._getTmpPath('images_pca.xmd') # Wiener
|
|
@@ -190,13 +188,21 @@ class XmippProtClassifyPcaStreaming(ProtStreamingBase, XmippProtClassifyPca):
|
|
|
190
188
|
else:
|
|
191
189
|
self.numberClasses = self.numberOfClasses.get()
|
|
192
190
|
|
|
193
|
-
def
|
|
194
|
-
|
|
195
|
-
|
|
191
|
+
def getGpusList(self, separator):
|
|
192
|
+
strGpus = ""
|
|
193
|
+
for elem in self._stepsExecutor.getGpuList():
|
|
194
|
+
strGpus = strGpus + str(elem) + separator
|
|
195
|
+
return strGpus[:-1]
|
|
196
|
+
|
|
197
|
+
def setGPU(self, oneGPU=False):
|
|
198
|
+
if oneGPU:
|
|
199
|
+
gpus = self.getGpusList(",")[0]
|
|
196
200
|
else:
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
self.
|
|
201
|
+
gpus = self.getGpusList(",")
|
|
202
|
+
os.environ["CUDA_VISIBLE_DEVICES"] = gpus
|
|
203
|
+
self.info(f'Visible GPUS: {gpus}')
|
|
204
|
+
return gpus
|
|
205
|
+
|
|
200
206
|
|
|
201
207
|
def runPCASteps(self, newParticlesSet):
|
|
202
208
|
# Run PCA steps
|
|
@@ -267,17 +273,19 @@ class XmippProtClassifyPcaStreaming(ProtStreamingBase, XmippProtClassifyPca):
|
|
|
267
273
|
self.firstTimeDone = True
|
|
268
274
|
|
|
269
275
|
def pcaTraining(self, inputIm, resolutionTrain, numTrain):
|
|
276
|
+
gpuID = self.setGPU(oneGPU=True)
|
|
270
277
|
args = ' -i %s -s %s -hr %s -lr 530 -p %s -t %s -o %s/train_pca --batchPCA -g %s' % \
|
|
271
|
-
(inputIm, self.sampling, resolutionTrain, self.coef.get(), numTrain, self._getExtraPath(),
|
|
278
|
+
(inputIm, self.sampling, resolutionTrain, self.coef.get(), numTrain, self._getExtraPath(), gpuID)
|
|
272
279
|
|
|
273
280
|
env = self.getCondaEnv()
|
|
274
281
|
env = self._setEnvVariables(env)
|
|
275
282
|
self.runJob("xmipp_classify_pca_train", args, numberOfMpi=1, env=env)
|
|
276
283
|
|
|
277
284
|
def classification(self, inputIm, numClass, stfile, mask, sigma):
|
|
285
|
+
gpuID = self.setGPU(oneGPU=True)
|
|
278
286
|
args = ' -i %s -c %s -b %s/train_pca_bands.pt -v %s/train_pca_vecs.pt -o %s/classes -stExp %s -g %s' % \
|
|
279
287
|
(inputIm, numClass, self._getExtraPath(), self._getExtraPath(), self._getExtraPath(),
|
|
280
|
-
stfile,
|
|
288
|
+
stfile, gpuID)
|
|
281
289
|
if mask:
|
|
282
290
|
args += ' --mask --sigma %s ' % (sigma)
|
|
283
291
|
|
|
@@ -96,7 +96,7 @@ class XmippProtCompareReprojections(ProtAnalysis3D, ProjMatcher):
|
|
|
96
96
|
help='If this option is chosen, then the residual covariance matrix is calculated and '
|
|
97
97
|
'characterized. But this option takes time and disk space')
|
|
98
98
|
form.addParam('symmetryGroup', StringParam, default="c1", label='Symmetry group',
|
|
99
|
-
help='See
|
|
99
|
+
help='See https://i2pc.github.io/docs/Utils/Conventions/index.html#symmetry for a description of the symmetry'
|
|
100
100
|
' groups format. If no symmetry is present, give c1')
|
|
101
101
|
form.addParam('angularSampling', FloatParam, default=5, expertLevel=LEVEL_ADVANCED,
|
|
102
102
|
label='Angular sampling rate',
|
|
@@ -634,4 +634,4 @@ def createSetOfParticles(classesSet, path):
|
|
|
634
634
|
images = classesSet.getImages()
|
|
635
635
|
particles = SetOfParticles.create(outputPath=path)
|
|
636
636
|
particles.copyInfo(images)
|
|
637
|
-
return particles
|
|
637
|
+
return particles
|
|
@@ -57,7 +57,7 @@ class XmippProtComputeLikelihood(ProtAnalysis3D):
|
|
|
57
57
|
_label = 'log likelihood'
|
|
58
58
|
_lastUpdateVersion = VERSION_1_1
|
|
59
59
|
_possibleOutputs = {"reprojections": SetOfParticles}
|
|
60
|
-
_devStatus =
|
|
60
|
+
_devStatus = PROD
|
|
61
61
|
stepsExecutionMode = STEPS_PARALLEL
|
|
62
62
|
|
|
63
63
|
# Normalization enum constants
|
|
@@ -45,7 +45,7 @@ from pyworkflow import UPDATED, PROD
|
|
|
45
45
|
class XmippProtConvertPdb(ProtInitialVolume):
|
|
46
46
|
""" Converts atomic structure files in PDB (Protein Data Bank) format into volumetric maps. Converting a PDB to a volume generates a simulated electron density map, useful for validating atomic models, fitting into experimental maps or performing docking."""
|
|
47
47
|
_label = 'convert pdbs to volumes'
|
|
48
|
-
_devStatus =
|
|
48
|
+
_devStatus = PROD
|
|
49
49
|
OUTPUT_NAME1 = "outputVolume"
|
|
50
50
|
OUTPUT_NAME2 = "outputVolumes"
|
|
51
51
|
OUTPUT_NAME3 = "outputPdb"
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# **************************************************************************
|
|
2
|
+
# *
|
|
3
|
+
# * Authors: Federico P. de Isidro Gomez
|
|
4
|
+
# *
|
|
5
|
+
# * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
|
|
6
|
+
# *
|
|
7
|
+
# * This program is free software; you can redistribute it and/or modify
|
|
8
|
+
# * it under the terms of the GNU General Public License as published by
|
|
9
|
+
# * the Free Software Foundation; either version 2 of the License, or
|
|
10
|
+
# * (at your option) any later version.
|
|
11
|
+
# *
|
|
12
|
+
# * This program is distributed in the hope that it will be useful,
|
|
13
|
+
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
# * GNU General Public License for more details.
|
|
16
|
+
# *
|
|
17
|
+
# * You should have received a copy of the GNU General Public License
|
|
18
|
+
# * along with this program; if not, write to the Free Software
|
|
19
|
+
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
20
|
+
# * 02111-1307 USA
|
|
21
|
+
# *
|
|
22
|
+
# * All comments concerning this program package may be sent to the
|
|
23
|
+
# * e-mail address 'scipion@cnb.csic.es'
|
|
24
|
+
# *
|
|
25
|
+
# **************************************************************************
|
|
26
|
+
|
|
27
|
+
import pwem.emlib.metadata as md
|
|
28
|
+
import pyworkflow.protocol.params as params
|
|
29
|
+
from pwem.protocols import ProtProcessParticles
|
|
30
|
+
|
|
31
|
+
from xmipp3.convert import writeSetOfParticles, xmippToLocation, readSetOfParticles
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class XmippProtCTFCorrectPhase2D(ProtProcessParticles):
|
|
35
|
+
"""
|
|
36
|
+
Perform CTF correction by phase flip.
|
|
37
|
+
"""
|
|
38
|
+
_label = 'ctf_correct_phase'
|
|
39
|
+
|
|
40
|
+
def __init__(self, *args, **kwargs):
|
|
41
|
+
ProtProcessParticles.__init__(self, *args, **kwargs)
|
|
42
|
+
#self.stepsExecutionMode = STEPS_PARALLEL
|
|
43
|
+
|
|
44
|
+
#--------------------------- DEFINE param functions --------------------------------------------
|
|
45
|
+
def _defineParams(self, form):
|
|
46
|
+
form.addSection(label='Input')
|
|
47
|
+
|
|
48
|
+
form.addParam('inputParticles', params.PointerParam, pointerClass='SetOfParticles',
|
|
49
|
+
label="Input particles",
|
|
50
|
+
help='Select the input projection images .')
|
|
51
|
+
form.addParallelSection(threads=1, mpi=1)
|
|
52
|
+
|
|
53
|
+
#--------------------------- INSERT steps functions --------------------------------------------
|
|
54
|
+
def _insertAllSteps(self):
|
|
55
|
+
self._insertFunctionStep('convertInputStep',self.inputParticles.get().getObjId())
|
|
56
|
+
self._insertFunctionStep('phaseStep')
|
|
57
|
+
self._insertFunctionStep('createOutputStep')
|
|
58
|
+
|
|
59
|
+
def convertInputStep(self, particlesId):
|
|
60
|
+
""" Write the input images as a Xmipp metadata file.
|
|
61
|
+
particlesId: is only need to detect changes in
|
|
62
|
+
input particles and cause restart from here.
|
|
63
|
+
"""
|
|
64
|
+
writeSetOfParticles(self.inputParticles.get(),
|
|
65
|
+
self._getPath('input_particles.xmd'))
|
|
66
|
+
|
|
67
|
+
def phaseStep(self):
|
|
68
|
+
params = ' -i %s' % self._getPath('input_particles.xmd')
|
|
69
|
+
params += ' -o %s' % self._getPath('corrected_ctf_particles.stk')
|
|
70
|
+
params += ' --save_metadata_stack %s' % self._getPath('corrected_ctf_particles.xmd')
|
|
71
|
+
params += ' --sampling_rate %s' % self.inputParticles.get().getSamplingRate()
|
|
72
|
+
|
|
73
|
+
nproc = self.numberOfMpi.get()
|
|
74
|
+
nT=self.numberOfThreads.get()
|
|
75
|
+
|
|
76
|
+
self.runJob('xmipp_ctf_correct_phase',
|
|
77
|
+
params, numberOfMpi=nproc,numberOfThreads=nT)
|
|
78
|
+
|
|
79
|
+
def createOutputStep(self):
|
|
80
|
+
imgSet = self.inputParticles.get()
|
|
81
|
+
partSet = self._createSetOfParticles()
|
|
82
|
+
imgFn = self._getPath('corrected_ctf_particles.xmd')
|
|
83
|
+
|
|
84
|
+
partSet.copyInfo(imgSet)
|
|
85
|
+
partSet.setIsPhaseFlipped(True)
|
|
86
|
+
readSetOfParticles(imgFn, partSet)
|
|
87
|
+
|
|
88
|
+
self._defineOutputs(outputParticles=partSet)
|
|
89
|
+
self._defineSourceRelation(imgSet, partSet)
|
|
@@ -261,10 +261,6 @@ class XmippProtCTFMicrographs(ProtCTFMicrographs):
|
|
|
261
261
|
if min(psd.shape) < self.windowSize.get():
|
|
262
262
|
localParams['pieceDim'] = self.windowSize.get()/2
|
|
263
263
|
localParams['ctfmodelSize'] = self.windowSize.get()/2
|
|
264
|
-
else:
|
|
265
|
-
# This is needed to make sure that the micrograph has the correct sampling
|
|
266
|
-
# Otherwise, it brings the last sampling tested
|
|
267
|
-
copyFile(micFn, finalName)
|
|
268
264
|
|
|
269
265
|
# Update _params dictionary with mic and micDir
|
|
270
266
|
localParams['micFn'] = finalName
|
|
@@ -104,17 +104,26 @@ class XmippProtDeepCenter(ProtAlign2D, xmipp3.XmippProtocol):
|
|
|
104
104
|
def _insertAllSteps(self):
|
|
105
105
|
self.fnImgs = self._getTmpPath('imgs.xmd')
|
|
106
106
|
self.fnImgsTrain = self._getTmpPath('imgsTrain.xmd')
|
|
107
|
-
if self.useQueueForSteps() or self.useQueue():
|
|
108
|
-
myStr = os.environ["CUDA_VISIBLE_DEVICES"]
|
|
109
|
-
else:
|
|
110
|
-
myStr = self.gpuList.get()
|
|
111
|
-
os.environ["CUDA_VISIBLE_DEVICES"] = self.gpuList.get()
|
|
112
|
-
numGPU = myStr.split(',')
|
|
113
107
|
self._insertFunctionStep("convertInputStep", self.inputParticles.get())
|
|
114
|
-
self._insertFunctionStep("train"
|
|
115
|
-
self._insertFunctionStep("predict"
|
|
108
|
+
self._insertFunctionStep("train")
|
|
109
|
+
self._insertFunctionStep("predict" )
|
|
116
110
|
self._insertFunctionStep("createOutputStep")
|
|
117
111
|
|
|
112
|
+
def getGpusList(self, separator):
|
|
113
|
+
strGpus = ""
|
|
114
|
+
for elem in self._stepsExecutor.getGpuList():
|
|
115
|
+
strGpus = strGpus + str(elem) + separator
|
|
116
|
+
return strGpus[:-1]
|
|
117
|
+
|
|
118
|
+
def setGpu(self, oneGPU=False):
|
|
119
|
+
if oneGPU:
|
|
120
|
+
gpus = self.getGpusList(",")[0]
|
|
121
|
+
else:
|
|
122
|
+
gpus = self.getGpusList(",")
|
|
123
|
+
os.environ["CUDA_VISIBLE_DEVICES"] = gpus
|
|
124
|
+
self.info(f'Visible GPUS: {gpus}')
|
|
125
|
+
return gpus
|
|
126
|
+
|
|
118
127
|
# --------------------------- STEPS functions ---------------------------------------------------
|
|
119
128
|
def convertInputStep(self, inputSet):
|
|
120
129
|
writeSetOfParticles(inputSet, self.fnImgs)
|
|
@@ -124,13 +133,15 @@ class XmippProtDeepCenter(ProtAlign2D, xmipp3.XmippProtocol):
|
|
|
124
133
|
else:
|
|
125
134
|
createLink(self.fnImgs, self.fnImgsTrain)
|
|
126
135
|
|
|
127
|
-
def train(self
|
|
136
|
+
def train(self):
|
|
137
|
+
gpuId = self.setGpu(oneGPU=True)
|
|
128
138
|
args = "-i %s --omodel %s --sigma %f --maxEpochs %d --batchSize %d --gpu %s --learningRate %f --precision %f"%\
|
|
129
139
|
(self.fnImgsTrain, self._getExtraPath("model.h5"), self.sigma, self.numEpochs, self.batchSize, gpuId,
|
|
130
140
|
self.learningRate, self.precision)
|
|
131
141
|
self.runJob(f"xmipp_deep_center", args, numberOfMpi=1, env=self.getCondaEnv())
|
|
132
142
|
|
|
133
|
-
def predict(self
|
|
143
|
+
def predict(self):
|
|
144
|
+
gpuId = self.setGpu(oneGPU=True)
|
|
134
145
|
fnModel = self._getExtraPath("model.h5")
|
|
135
146
|
args = "-i %s --gpu %s --model %s -o %s" % (self.fnImgs, gpuId, fnModel, self._getExtraPath('particles.xmd'))
|
|
136
147
|
self.runJob("xmipp_deep_center_predict", args, numberOfMpi=1, env=self.getCondaEnv())
|
|
@@ -83,16 +83,25 @@ class XmippProtDeepCenterPredict(ProtAlign2D, xmipp3.XmippProtocol):
|
|
|
83
83
|
# --------------------------- INSERT steps functions --------------------------------------------
|
|
84
84
|
def _insertAllSteps(self):
|
|
85
85
|
self.fnImgs = self._getExtraPath('imgs.xmd')
|
|
86
|
-
if self.useQueueForSteps() or self.useQueue():
|
|
87
|
-
myStr = os.environ["CUDA_VISIBLE_DEVICES"]
|
|
88
|
-
else:
|
|
89
|
-
myStr = self.gpuList.get()
|
|
90
|
-
os.environ["CUDA_VISIBLE_DEVICES"] = self.gpuList.get()
|
|
91
|
-
numGPU = myStr.split(',')
|
|
92
86
|
self._insertFunctionStep("convertInputStep", self.inputParticles.get())
|
|
93
|
-
self._insertFunctionStep("predict"
|
|
87
|
+
self._insertFunctionStep("predict")
|
|
94
88
|
self._insertFunctionStep("createOutputStep")
|
|
95
89
|
|
|
90
|
+
def getGpusList(self, separator):
|
|
91
|
+
strGpus = ""
|
|
92
|
+
for elem in self._stepsExecutor.getGpuList():
|
|
93
|
+
strGpus = strGpus + str(elem) + separator
|
|
94
|
+
return strGpus[:-1]
|
|
95
|
+
|
|
96
|
+
def setGpu(self, oneGPU=False):
|
|
97
|
+
if oneGPU:
|
|
98
|
+
gpus = self.getGpusList(",")[0]
|
|
99
|
+
else:
|
|
100
|
+
gpus = self.getGpusList(",")
|
|
101
|
+
os.environ["CUDA_VISIBLE_DEVICES"] = gpus
|
|
102
|
+
self.info(f'Visible GPUS: {gpus}')
|
|
103
|
+
return gpus
|
|
104
|
+
|
|
96
105
|
# --------------------------- STEPS functions ---------------------------------------------------
|
|
97
106
|
def convertInputStep(self, inputSet):
|
|
98
107
|
writeSetOfParticles(inputSet, self.fnImgs)
|
|
@@ -108,13 +117,14 @@ class XmippProtDeepCenterPredict(ProtAlign2D, xmipp3.XmippProtocol):
|
|
|
108
117
|
self.runJob("xmipp_image_resize", "-i %s -o %s --fourier 64" % (self.fnImgs, fnTmp))
|
|
109
118
|
self.fnImgs = self._getTmpPath("imgs.xmd")
|
|
110
119
|
|
|
111
|
-
def predict(self
|
|
120
|
+
def predict(self):
|
|
112
121
|
if self.modelSource==self.PRETRAINED:
|
|
113
122
|
fnModel = self.getModel('deepCenter', 'deepCenterModel.h5')
|
|
114
123
|
elif self.getRunMode()==self.PREVIOUS:
|
|
115
124
|
fnModel = self.protocolPointer.get()._getExtraPath("model.h5")
|
|
116
125
|
else:
|
|
117
126
|
fnModel = self.modelFile.get()
|
|
127
|
+
gpuId = self.setGpu(oneGPU=True)
|
|
118
128
|
args = "-i %s --gpu %s --model %s -o %s --scale %f" % (self.fnImgs, gpuId, fnModel,
|
|
119
129
|
self.fnImgs, self.scaleFactor)
|
|
120
130
|
self.runJob("xmipp_deep_center_predict", args, numberOfMpi=1, env=self.getCondaEnv())
|
|
@@ -37,12 +37,14 @@ from xmipp3.base import XmippProtocol
|
|
|
37
37
|
from xmipp_base import createMetaDataFromPattern
|
|
38
38
|
from xmipp3.convert import (writeMicCoordinates, readSetOfCoordinates)
|
|
39
39
|
from xmipp3.constants import SAME_AS_PICKING, OTHER
|
|
40
|
+
from pyworkflow import BETA, UPDATED, NEW, PROD
|
|
40
41
|
|
|
41
42
|
|
|
42
43
|
class XmippProtDeepMicrographScreen(ProtExtractParticles, XmippProtocol):
|
|
43
44
|
"""Removes coordinates located in carbon regions or large impurities in micrographs using a pre-trained deep learning model. This screening improves particle picking accuracy by filtering out false positives from contaminated areas."""
|
|
44
45
|
_label = 'deep micrograph cleaner'
|
|
45
46
|
_conda_env= "xmipp_MicCleaner"
|
|
47
|
+
_devStatus = UPDATED
|
|
46
48
|
|
|
47
49
|
def __init__(self, **kwargs):
|
|
48
50
|
ProtExtractParticles.__init__(self, **kwargs)
|
|
@@ -122,7 +124,24 @@ class XmippProtDeepMicrographScreen(ProtExtractParticles, XmippProtocol):
|
|
|
122
124
|
help="Add a list of GPU devices that can be used.")
|
|
123
125
|
|
|
124
126
|
# form.addParallelSection(threads=4, mpi=1)
|
|
125
|
-
|
|
127
|
+
|
|
128
|
+
def getGpusList(self, separator):
|
|
129
|
+
strGpus = ""
|
|
130
|
+
for elem in self._stepsExecutor.getGpuList():
|
|
131
|
+
strGpus = strGpus + str(elem) + separator
|
|
132
|
+
return strGpus[:-1]
|
|
133
|
+
|
|
134
|
+
def setGPU(self, oneGPU=False):
|
|
135
|
+
if oneGPU:
|
|
136
|
+
gpus = self.getGpusList(",")[0]
|
|
137
|
+
else:
|
|
138
|
+
gpus = self.getGpusList(",")
|
|
139
|
+
os.environ["CUDA_VISIBLE_DEVICES"] = gpus
|
|
140
|
+
os.environ['TF_FORCE_GPU_ALLOW_GROWTH'] = 'true'
|
|
141
|
+
self.info(f'Visible GPUS: {gpus}')
|
|
142
|
+
return gpus
|
|
143
|
+
|
|
144
|
+
|
|
126
145
|
#--------------------------- INSERT steps functions ------------------------
|
|
127
146
|
def _insertInitialSteps(self):
|
|
128
147
|
# Just overwrite this function to load some info
|
|
@@ -199,7 +218,7 @@ class XmippProtDeepMicrographScreen(ProtExtractParticles, XmippProtocol):
|
|
|
199
218
|
args += ' -o %s' % self._getExtraPath('outputCoords')
|
|
200
219
|
args += ' -b %d' % self.getBoxSize()
|
|
201
220
|
args += ' -s 1' #Downsampling is automatically managed by scipion
|
|
202
|
-
args += ' -d %s' % self.getModel('
|
|
221
|
+
args += ' -d %s' % self.getModel('deepMicrographCleanerTF2', 'defaultModel.h5')
|
|
203
222
|
|
|
204
223
|
if self.threshold.get() > 0:
|
|
205
224
|
args += ' --deepThr %f ' % (1-self.threshold.get())
|
|
@@ -208,14 +227,9 @@ class XmippProtDeepMicrographScreen(ProtExtractParticles, XmippProtocol):
|
|
|
208
227
|
args += ' --predictedMaskDir %s ' % (self._getExtraPath("predictedMasks"))
|
|
209
228
|
|
|
210
229
|
if self.useGpu.get():
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
else:
|
|
214
|
-
args += ' -g %s'%(",".join([str(elem) for elem in self.getGpuList()]))
|
|
215
|
-
else:
|
|
216
|
-
args += ' -g -1'
|
|
230
|
+
gpuId = self.setGPU(oneGPU=False)
|
|
231
|
+
args += f' -g {gpuId} '
|
|
217
232
|
|
|
218
|
-
os.environ['TF_FORCE_GPU_ALLOW_GROWTH'] = 'true'
|
|
219
233
|
self.runJob('xmipp_deep_micrograph_cleaner', args)
|
|
220
234
|
|
|
221
235
|
|
|
@@ -31,7 +31,7 @@ from pwem.objects import Transform
|
|
|
31
31
|
from pwem.convert import Ccp4Header
|
|
32
32
|
from pwem.protocols import EMProtocol
|
|
33
33
|
from pyworkflow.protocol.params import (PointerParam, FloatParam,
|
|
34
|
-
EnumParam, IntParam)
|
|
34
|
+
EnumParam, IntParam, GE)
|
|
35
35
|
|
|
36
36
|
from xmipp3.constants import (XMIPP_SYM_NAME, XMIPP_TO_SCIPION, XMIPP_CYCLIC,
|
|
37
37
|
XMIPP_DIHEDRAL_X, XMIPP_TETRAHEDRAL, XMIPP_OCTAHEDRAL,
|
|
@@ -76,7 +76,7 @@ class XmippProtExtractUnit(EMProtocol):
|
|
|
76
76
|
" (" + SCIPION_SYM_NAME[XMIPP_TO_SCIPION[XMIPP_In25r]] + ")"],
|
|
77
77
|
default=XMIPP_I222,
|
|
78
78
|
label="Symmetry",
|
|
79
|
-
help="See
|
|
79
|
+
help="See https://i2pc.github.io/docs/Utils/Conventions/index.html#symmetry"
|
|
80
80
|
"Symmetry for a description of the symmetry groups "
|
|
81
81
|
"format in Xmipp.\n"
|
|
82
82
|
"If no symmetry is present, use _c1_."
|
|
@@ -89,9 +89,9 @@ class XmippProtExtractUnit(EMProtocol):
|
|
|
89
89
|
condition='symmetryGroup<=%d' % SYM_DIHEDRAL_X,
|
|
90
90
|
label="offset",
|
|
91
91
|
help="rotate unit cell around z-axis by offset degrees")
|
|
92
|
-
form.addParam('innerRadius', FloatParam, default
|
|
93
|
-
label="Inner Radius (px)",
|
|
94
|
-
help="inner Mask radius
|
|
92
|
+
form.addParam('innerRadius', FloatParam, default=0.0,
|
|
93
|
+
label="Inner Radius (px)", validators=[GE(0.0)],
|
|
94
|
+
help="inner Mask radius")
|
|
95
95
|
form.addParam('outerRadius', FloatParam, default=-1,
|
|
96
96
|
label="Outer Radius (px)",
|
|
97
97
|
help="outer Mask radius, if -1, the radius will be "
|
|
@@ -103,8 +103,8 @@ class XmippProtExtractUnit(EMProtocol):
|
|
|
103
103
|
# --------------------------- INSERT steps functions ----------------------
|
|
104
104
|
|
|
105
105
|
def _insertAllSteps(self):
|
|
106
|
-
self._insertFunctionStep(
|
|
107
|
-
self._insertFunctionStep(
|
|
106
|
+
self._insertFunctionStep(self.extractUnit)
|
|
107
|
+
self._insertFunctionStep(self.createOutputStep)
|
|
108
108
|
|
|
109
109
|
# --------------------------- STEPS functions -----------------------------
|
|
110
110
|
|
|
@@ -128,8 +128,8 @@ class XmippProtExtractUnit(EMProtocol):
|
|
|
128
128
|
args = "-i %s -o %s" % \
|
|
129
129
|
(inFileName, self._getOutputVol())
|
|
130
130
|
args += " --unitcell %s " % sym
|
|
131
|
-
args += " %f " % self.
|
|
132
|
-
args += " %f " % self.
|
|
131
|
+
args += " %f " % self._getInnerRadius()
|
|
132
|
+
args += " %f " % self._getOuterRadius()
|
|
133
133
|
args += " %f " % self.expandFactor.get()
|
|
134
134
|
args += " %f " % self.offset.get()
|
|
135
135
|
sampling = self.inputVolumes.get().getSamplingRate()
|
|
@@ -177,11 +177,21 @@ class XmippProtExtractUnit(EMProtocol):
|
|
|
177
177
|
return []
|
|
178
178
|
|
|
179
179
|
# --------------------------- UTILS functions -----------------------------
|
|
180
|
-
|
|
180
|
+
def _getInnerRadius(self):
|
|
181
|
+
return self.innerRadius.get()
|
|
182
|
+
|
|
183
|
+
def _getOuterRadius(self):
|
|
184
|
+
outerRadius = self.outerRadius.get()
|
|
185
|
+
if outerRadius < 0:
|
|
186
|
+
volume: Volume = self.inputVolumes.get()
|
|
187
|
+
dim = volume.getDimensions()
|
|
188
|
+
outerRadius = dim[0] / 2
|
|
189
|
+
return outerRadius
|
|
190
|
+
|
|
181
191
|
def _getOutputVol(self):
|
|
182
192
|
prefix = os.path.basename(self.inputVolumes.get().getFileName()).split(".")[0]
|
|
183
193
|
|
|
184
194
|
return self._getExtraPath(prefix + "_output_volume.mrc")
|
|
185
195
|
|
|
186
196
|
def replace_at_index(self, tup, ix, val):
|
|
187
|
-
return tup[:ix] + (val,) + tup[ix + 1:]
|
|
197
|
+
return tup[:ix] + (val,) + tup[ix + 1:]
|
|
@@ -50,7 +50,7 @@ FACTOR_BOXSIZE = 1.5
|
|
|
50
50
|
class XmippProtExtractParticles(ProtExtractParticles, XmippProtocol):
|
|
51
51
|
"""Extracts particle images from micrographs based on provided coordinates. This essential step prepares particle stacks for further processing such as classification and reconstruction."""
|
|
52
52
|
_label = 'extract particles'
|
|
53
|
-
_devStatus =
|
|
53
|
+
_devStatus = PROD
|
|
54
54
|
RESIZE_FACTOR = 0
|
|
55
55
|
RESIZE_DIMENSIONS = 1
|
|
56
56
|
RESIZE_SAMPLINGRATE = 2
|