scipion-em-xmipp 24.12.2__py3-none-any.whl → 25.6.1__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.
Files changed (139) hide show
  1. {scipion_em_xmipp-24.12.2.dist-info → scipion_em_xmipp-25.6.1.dist-info}/METADATA +10 -10
  2. scipion_em_xmipp-25.6.1.dist-info/RECORD +255 -0
  3. {scipion_em_xmipp-24.12.2.dist-info → scipion_em_xmipp-25.6.1.dist-info}/WHEEL +1 -1
  4. {scipion_em_xmipp-24.12.2.dist-info → scipion_em_xmipp-25.6.1.dist-info}/entry_points.txt +0 -1
  5. xmipp3/__init__.py +105 -72
  6. xmipp3/base.py +2 -1
  7. xmipp3/convert/convert.py +1 -1
  8. xmipp3/legacy/protocols/protocol_angular_resolution_alignment.py +204 -0
  9. xmipp3/legacy/protocols/protocol_apply_deformation_zernike3d.py +113 -0
  10. xmipp3/legacy/protocols/protocol_classification_gpuCorr.py +821 -0
  11. xmipp3/legacy/protocols/protocol_classification_gpuCorr_full.py +1014 -0
  12. xmipp3/legacy/protocols/protocol_classification_gpuCorr_semi.py +462 -0
  13. xmipp3/legacy/protocols/protocol_classify_kmeans2d.py +285 -0
  14. xmipp3/legacy/protocols/protocol_deep_align.py +859 -0
  15. xmipp3/legacy/protocols/protocol_deep_denoising.py +425 -0
  16. xmipp3/legacy/protocols/protocol_kmeans_clustering.py +122 -0
  17. xmipp3/legacy/protocols/protocol_metaprotocol_create_output.py +146 -0
  18. xmipp3/legacy/protocols/protocol_metaprotocol_create_subset.py +96 -0
  19. xmipp3/legacy/protocols/protocol_metaprotocol_discrete_heterogeneity_scheduler.py +516 -0
  20. xmipp3/legacy/protocols/protocol_metaprotocol_golden_highres.py +663 -0
  21. xmipp3/legacy/protocols/protocol_mltomo.py +576 -0
  22. xmipp3/legacy/protocols/protocol_movie_average.py +202 -0
  23. xmipp3/legacy/protocols/protocol_movie_opticalflow.py +416 -0
  24. xmipp3/legacy/protocols/protocol_particle_boxsize.py +133 -0
  25. xmipp3/legacy/protocols/protocol_reconstruct_heterogeneous.py +1031 -0
  26. xmipp3/legacy/protocols/protocol_rotational_spectra.py +212 -0
  27. xmipp3/legacy/protocols/protocol_solid_angles.py +632 -0
  28. xmipp3/legacy/protocols/protocol_split_volume.py +112 -0
  29. xmipp3/legacy/protocols/protocol_split_volume_hierarchical_cluster.py +865 -0
  30. xmipp3/legacy/protocols/protocol_subtract_projection.py +265 -0
  31. xmipp3/legacy/tests/test_protocol_deep_denoising.py +64 -0
  32. xmipp3/legacy/tests/test_protocols_angular_resolution_alignment.py +88 -0
  33. xmipp3/legacy/tests/test_protocols_gpuCorr_classifier.py +141 -0
  34. xmipp3/legacy/tests/test_protocols_gpuCorr_fullStreaming.py +172 -0
  35. xmipp3/legacy/tests/test_protocols_gpuCorr_semiStreaming.py +68 -0
  36. xmipp3/legacy/tests/test_protocols_metaprotocol_golden_highres.py +96 -0
  37. xmipp3/legacy/tests/test_protocols_metaprotocol_heterogeneity.py +78 -0
  38. xmipp3/legacy/tests/test_protocols_mixed_movies.py +148 -0
  39. xmipp3/legacy/tests/test_protocols_solid_angles.py +161 -0
  40. xmipp3/legacy/tests/test_protocols_subtract_projection.py +595 -0
  41. xmipp3/legacy/tests/test_protocols_xmipp_movies.py +229 -0
  42. xmipp3/legacy/viewers/viewer_angular_resolution_alignment.py +148 -0
  43. xmipp3/legacy/viewers/viewer_deep_align.py +121 -0
  44. xmipp3/legacy/viewers/viewer_metaprotocol_golden_highres.py +140 -0
  45. xmipp3/legacy/viewers/viewer_mltomo.py +297 -0
  46. xmipp3/legacy/viewers/viewer_solid_angles.py +91 -0
  47. xmipp3/legacy/viewers/viewer_split_volume.py +57 -0
  48. xmipp3/protocols/__init__.py +1 -2
  49. xmipp3/protocols/protocol_align_volume.py +34 -8
  50. xmipp3/protocols/protocol_apply_alignment.py +1 -1
  51. xmipp3/protocols/protocol_apply_tilt_to_ctf.py +2 -3
  52. xmipp3/protocols/protocol_apply_zernike3d.py +2 -1
  53. xmipp3/protocols/protocol_assignment_tilt_pair.py +1 -2
  54. xmipp3/protocols/protocol_center_particles.py +1 -1
  55. xmipp3/protocols/protocol_cl2d.py +1 -2
  56. xmipp3/protocols/protocol_cl2d_align.py +1 -1
  57. xmipp3/protocols/protocol_cl2d_clustering.py +1 -1
  58. xmipp3/protocols/protocol_classify_pca.py +25 -9
  59. xmipp3/protocols/protocol_classify_pca_streaming.py +67 -42
  60. xmipp3/protocols/protocol_compute_likelihood.py +368 -0
  61. xmipp3/protocols/protocol_consensus_local_ctf.py +1 -1
  62. xmipp3/protocols/protocol_convert_pdb.py +9 -1
  63. xmipp3/protocols/protocol_create_gallery.py +1 -1
  64. xmipp3/protocols/protocol_ctf_consensus.py +14 -8
  65. xmipp3/protocols/protocol_ctf_correct_wiener2d.py +1 -1
  66. xmipp3/protocols/protocol_ctf_micrographs.py +1 -1
  67. xmipp3/protocols/protocol_deep_center_predict.py +10 -1
  68. xmipp3/protocols/protocol_deep_hand.py +19 -2
  69. xmipp3/protocols/protocol_deep_micrograph_screen.py +1 -1
  70. xmipp3/protocols/protocol_extract_asymmetric_unit.py +1 -1
  71. xmipp3/protocols/protocol_extract_particles.py +22 -10
  72. xmipp3/protocols/protocol_extract_particles_movies.py +1 -1
  73. xmipp3/protocols/protocol_extract_particles_pairs.py +1 -1
  74. xmipp3/protocols/protocol_flexalign.py +3 -4
  75. xmipp3/protocols/protocol_helical_parameters.py +1 -4
  76. xmipp3/protocols/protocol_movie_alignment_consensus.py +122 -40
  77. xmipp3/protocols/protocol_movie_dose_analysis.py +79 -82
  78. xmipp3/protocols/protocol_movie_max_shift.py +6 -2
  79. xmipp3/protocols/protocol_movie_split_frames.py +165 -88
  80. xmipp3/protocols/protocol_particle_pick_automatic.py +1 -2
  81. xmipp3/protocols/protocol_particle_pick_consensus.py +7 -0
  82. xmipp3/protocols/protocol_particle_pick_pairs.py +1 -1
  83. xmipp3/protocols/protocol_phantom_create.py +1 -1
  84. xmipp3/protocols/protocol_pick_noise.py +1 -1
  85. xmipp3/protocols/protocol_postProcessing_deepPostProcessing.py +5 -5
  86. xmipp3/protocols/protocol_preprocess/protocol_crop_resize.py +3 -2
  87. xmipp3/protocols/protocol_preprocess/protocol_filter.py +2 -2
  88. xmipp3/protocols/protocol_preprocess/protocol_image_operate.py +2 -2
  89. xmipp3/protocols/protocol_preprocess/protocol_mask.py +1 -1
  90. xmipp3/protocols/protocol_preprocess/protocol_preprocess.py +6 -4
  91. xmipp3/protocols/protocol_preprocess/protocol_process.py +20 -7
  92. xmipp3/protocols/protocol_preprocess_micrographs.py +3 -2
  93. xmipp3/protocols/protocol_projmatch/projmatch_steps.py +1 -1
  94. xmipp3/protocols/protocol_projmatch/protocol_projmatch.py +1 -1
  95. xmipp3/protocols/protocol_random_conical_tilt.py +1 -2
  96. xmipp3/protocols/protocol_ransac.py +41 -37
  97. xmipp3/protocols/protocol_reconstruct_fourier.py +5 -1
  98. xmipp3/protocols/protocol_reconstruct_highres.py +13 -7
  99. xmipp3/protocols/protocol_reconstruct_significant.py +14 -21
  100. xmipp3/protocols/protocol_resolution3d.py +1 -1
  101. xmipp3/protocols/protocol_resolution_deepres.py +1 -1
  102. xmipp3/protocols/protocol_resolution_directional.py +1 -1
  103. xmipp3/protocols/protocol_resolution_fso.py +1 -1
  104. xmipp3/protocols/protocol_resolution_monogenic_signal.py +19 -4
  105. xmipp3/protocols/protocol_rotate_volume.py +1 -1
  106. xmipp3/protocols/protocol_screen_deepConsensus.py +25 -5
  107. xmipp3/protocols/protocol_shift_volume.py +1 -1
  108. xmipp3/protocols/protocol_simulate_ctf.py +5 -3
  109. xmipp3/protocols/protocol_structure_map.py +9 -1
  110. xmipp3/protocols/protocol_subtract_projection.py +25 -10
  111. xmipp3/protocols/protocol_tilt_analysis.py +3 -3
  112. xmipp3/protocols/protocol_validate_fscq.py +2 -2
  113. xmipp3/protocols/protocol_validate_nontilt.py +1 -1
  114. xmipp3/protocols/protocol_volume_adjust_sub.py +8 -4
  115. xmipp3/protocols/protocol_volume_deform_zernike3d.py +1 -1
  116. xmipp3/protocols/protocol_volume_local_sharpening.py +1 -1
  117. xmipp3/protocols/protocol_volume_strain.py +1 -1
  118. xmipp3/protocols.conf +1 -3
  119. xmipp3/tests/test_protocol_likelihood.py +240 -0
  120. xmipp3/tests/test_protocol_split_frames.py +136 -0
  121. xmipp3/tests/test_protocol_validate_fscq.py +2 -2
  122. xmipp3/tests/test_protocols_highres.py +44 -5
  123. xmipp3/tests/test_protocols_xmipp_2d.py +1 -48
  124. xmipp3/tests/test_protocols_xmipp_mics.py +20 -16
  125. xmipp3/tests/test_protocols_xmipp_movies.py +4 -4
  126. xmipp3/version.py +5 -5
  127. xmipp3/viewers/__init__.py +1 -1
  128. xmipp3/viewers/viewer_LL_matrix.py +273 -0
  129. xmipp3/viewers/viewer_deep_consensus.py +1 -7
  130. xmipp3/viewers/viewer_dose_analysis.py +18 -2
  131. xmipp3/viewers/viewer_resolution_fso.py +18 -6
  132. xmipp3/viewers/viewer_structure_map.py +53 -11
  133. xmipp3/wizards.py +3 -2
  134. xmipp3/xmipp_logo_devel.png +0 -0
  135. scipion_em_xmipp-24.12.2.dist-info/RECORD +0 -210
  136. {scipion_em_xmipp-24.12.2.dist-info → scipion_em_xmipp-25.6.1.dist-info}/LICENSE +0 -0
  137. {scipion_em_xmipp-24.12.2.dist-info → scipion_em_xmipp-25.6.1.dist-info}/top_level.txt +0 -0
  138. /xmipp3/{protocols → legacy/protocols}/protocol_enrich.py +0 -0
  139. /xmipp3/{protocols → legacy/protocols}/protocol_screen_deeplearning.py +0 -0
@@ -0,0 +1,821 @@
1
+ # ******************************************************************************
2
+ # *
3
+ # * Authors: Amaya Jimenez Moreno (ajimenez@cnb.csic.es)
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
+ from shutil import copy
28
+ from os.path import join, exists, splitext
29
+ from os import mkdir, remove, listdir, environ
30
+
31
+ from pyworkflow import VERSION_2_0
32
+ import pyworkflow.protocol.params as params
33
+ import pyworkflow.protocol.constants as const
34
+
35
+ from pwem.protocols import ProtAlign2D
36
+ import pwem.emlib.metadata as md
37
+ from pwem.emlib.metadata import iterRows, getSize
38
+ from pwem.objects import SetOfClasses2D
39
+ from pwem.constants import ALIGN_2D, ALIGN_NONE
40
+ from pwem.emlib import MD_APPEND
41
+
42
+ from xmipp3.constants import CUDA_ALIGN_SIGNIFICANT
43
+ from xmipp3.convert import (rowToAlignment, xmippToLocation,
44
+ writeSetOfParticles, writeSetOfClasses2D)
45
+ from xmipp3.base import isXmippCudaPresent
46
+
47
+
48
+ class XmippProtGpuCrrCL2D(ProtAlign2D):
49
+ """ 2D alignment using Xmipp GPU Correlation algorithm. """
50
+ _label = 'gl2d'
51
+ _lastUpdateVersion = VERSION_2_0
52
+
53
+
54
+ # --------------------------- DEFINE param functions -----------------------
55
+ def _defineAlignParams(self, form):
56
+ form.addHidden(params.GPU_LIST, params.StringParam, default='0',
57
+ expertLevel=const.LEVEL_ADVANCED,
58
+ label="Choose GPU IDs",
59
+ help="Add a list of GPU devices that can be used")
60
+ form.addParam('useReferenceImages', params.BooleanParam, default=False,
61
+ label='Use a Set of Reference Images ?',
62
+ help='If you set to *Yes*, you should provide a '
63
+ 'set of reference images.\n'
64
+ 'If *No*, the default generation is done by '
65
+ 'averaging subsets of the input images.')
66
+ form.addParam('referenceImages', params.PointerParam,
67
+ condition='useReferenceImages',
68
+ pointerClass='SetOfParticles, SetOfAverages, '
69
+ 'SetOfClasses2D',
70
+ allowsNull=True,
71
+ label="Reference images",
72
+ help='Set of images that will serve as class reference')
73
+ form.addParam('numberOfClasses', params.IntParam, default=32,
74
+ label='Number of classes:', important=True,
75
+ help='Number of classes (or references) to be generated')
76
+ form.addParam('maxShift', params.IntParam, default=10,
77
+ label='Maximum shift (%):',
78
+ help='Maximum shift allowed during the alignment as '
79
+ 'percentage of the input set size',
80
+ expertLevel=const.LEVEL_ADVANCED)
81
+ form.addParam('keepBest', params.IntParam, default=1,
82
+ label='Number of best images:',
83
+ help='Number of classes to assign every input image '
84
+ 'during the alignment',
85
+ expertLevel=const.LEVEL_ADVANCED)
86
+ form.addParam('numberOfSplitIterations', params.IntParam, default=3,
87
+ label='Number of iterations in split stage:',
88
+ help='Maximum number of iterations in split stage',
89
+ expertLevel=const.LEVEL_ADVANCED)
90
+ form.addParam('numberOfClassifyIterations', params.IntParam, default=5,
91
+ label='Number of iterations in classify stage:',
92
+ help='Maximum number of iterations when the '
93
+ 'classification of the whole image set is carried '
94
+ 'out',
95
+ expertLevel=const.LEVEL_ADVANCED,)
96
+ form.addParam('useAttraction', params.BooleanParam, default=True,
97
+ label='Allow attraction ?',
98
+ help='If you set to *Yes*, you allow to generate classes '
99
+ 'with low number of images associated.\n'
100
+ 'If *No*, all the generated classes will be '
101
+ 'balanced',
102
+ expertLevel=const.LEVEL_ADVANCED,)
103
+ form.addParallelSection(threads=0, mpi=8)
104
+
105
+
106
+ # --------------------------- INSERT steps functions -----------------------
107
+ def _insertAllSteps(self):
108
+ """Mainly prepare the command line for call cuda corrrelation program"""
109
+
110
+ # Convert input images if necessary
111
+ if self.useReferenceImages:
112
+ self.refSet = self._getExtraPath('imagesRef.xmd')
113
+ else:
114
+ self.refSet = None
115
+
116
+ xOrig = self.inputParticles.get().getXDim()
117
+ self.maximumShift = int(self.maxShift.get()*xOrig/100)
118
+ self.p = 0.2
119
+ self.percentStopClassify = 5
120
+ self.listContinueClass=[]
121
+ self.iterReturnSplit = 0
122
+ self.iterReturnClass = 0
123
+ self.depthSplit = 0
124
+ self.depth = 0
125
+ self.imgsExp = self._getExtraPath('imagesExp.xmd')
126
+
127
+ self._insertFunctionStep('convertSetStep')
128
+ self._insertFunctionStep('classifyStep')
129
+ self._insertFunctionStep('createOutputStep')
130
+
131
+
132
+
133
+ # --------------------------- STEPS functions --------------------------
134
+ def convertSetStep(self):
135
+ writeSetOfParticles(self.inputParticles.get(), self.imgsExp,
136
+ alignType=ALIGN_NONE)
137
+ if self.useReferenceImages:
138
+ if isinstance(self.referenceImages.get(), SetOfClasses2D):
139
+ writeSetOfClasses2D(self.referenceImages.get(), self.refSet,
140
+ writeParticles=False)
141
+ else:
142
+ writeSetOfParticles(self.referenceImages.get(), self.refSet,
143
+ alignType=ALIGN_NONE)
144
+
145
+
146
+ def classifyStep(self):
147
+
148
+ listNumImgs = []
149
+ listNameImgs = []
150
+ change = False
151
+
152
+ level=0
153
+ while len(listNumImgs) is not self.numberOfClasses.get() \
154
+ or change is True:
155
+
156
+ if self.useReferenceImages and self.numberOfClasses.get() \
157
+ == getSize(self.refSet):
158
+ if not exists(join(self._getExtraPath(), 'level%03d' % level)):
159
+ mkdir(join(self._getExtraPath(), 'level%03d' % level))
160
+ copy(self.refSet, self._getExtraPath(join('level%03d' % level,
161
+ 'intermediate_classes.xmd')))
162
+ else:
163
+ self.splitStep(level)
164
+
165
+ #######################################
166
+ if not self.useAttraction:
167
+ self.attractionSplitStep(level)
168
+ #######################################
169
+
170
+ self.generateMetadata(listNameImgs, listNumImgs, level)
171
+
172
+ self.ref = self._getExtraPath(join('level%03d' % level,
173
+ 'intermediate_classes.xmd'))
174
+ lengthMd = getSize(self.ref)
175
+ if lengthMd==self.numberOfClasses.get():
176
+ self.classifyWholeSetStep(level)
177
+ #######################################################
178
+ if not self.useAttraction:
179
+ change, listNumImgs, listNameImgs = \
180
+ self.attractionGeneralStep(level)
181
+ if change:
182
+ level = level + 1
183
+ continue
184
+ #######################################################
185
+ copy(self._getExtraPath(join('level%03d' % level,
186
+ 'general_level%03d' % level
187
+ + '_classes.xmd')),
188
+ self._getExtraPath('last_classes.xmd'), )
189
+ if exists(self._getExtraPath(join('level%03d' % level,
190
+ 'general_images_level%03d'
191
+ % level + '.xmd'))):
192
+ copy(self._getExtraPath(join('level%03d' % level,
193
+ 'general_images_level%03d'
194
+ % level + '.xmd')),
195
+ self._getExtraPath('last_images.xmd'), )
196
+ return
197
+
198
+ listNumImgs, listNameImgs = self.checkOutput(level)
199
+ self.cleaningPath(level)
200
+ level = level + 1
201
+
202
+
203
+ def createOutputStep(self):
204
+ classes2DSet = self._createSetOfClasses2D(self.inputParticles)
205
+ self._fillClassesFromLevel(classes2DSet)
206
+ result = {'outputClasses': classes2DSet}
207
+ self._defineOutputs(**result)
208
+ self._defineSourceRelation(self.inputParticles, classes2DSet)
209
+
210
+
211
+ # --------------------------- Other functions --------------------------
212
+
213
+ def splitStep(self, level):
214
+
215
+ expSet = self.imgsExp
216
+ if level > 0:
217
+ expSet = self._getExtraPath(join('level%03d' % (level-1),
218
+ 'images_level%03d' % (level-1)
219
+ + '_major.xmd'))
220
+ boolReferenceImages = False
221
+ else:
222
+ boolReferenceImages = self.useReferenceImages
223
+
224
+ i=0
225
+ while i <self.numberOfSplitIterations:
226
+ self.iterationStep(self.refSet, expSet, i, boolReferenceImages,
227
+ level, True, False)
228
+ self.refSet = self._getExtraPath(join('level%03d' % level,
229
+ 'level%03d' % level +
230
+ '_classes.xmd'))
231
+ i+=1
232
+ if not self.useAttraction:
233
+ if self.fastCheckingAtt(level, True):
234
+ self.iterReturnSplit=i
235
+ return
236
+
237
+
238
+ def classifyWholeSetStep(self, level):
239
+
240
+ i=self.iterReturnClass
241
+ if i == self.numberOfClassifyIterations:
242
+ copy(self._getExtraPath(join('level%03d' % level,
243
+ 'intermediate_classes.xmd')),
244
+ self._getExtraPath(join('level%03d' % level,
245
+ 'general_level%03d_classes' % level
246
+ + '.xmd')))
247
+
248
+ while i <self.numberOfClassifyIterations:
249
+ self.iterationStep(self.ref, self.imgsExp, i, False, level, False,
250
+ False)
251
+ self.ref = self._getExtraPath(join('level%03d' % level,
252
+ 'general_level%03d' % level +
253
+ '_classes.xmd'))
254
+ i+=1
255
+
256
+ if self.checkContinueClassification(level, i-1):
257
+ return
258
+
259
+ #check attraction
260
+ if not self.useAttraction:
261
+ if self.fastCheckingAtt(level, False):
262
+ self.iterReturnClass=i
263
+ return
264
+
265
+
266
+ #check attraction
267
+ def fastCheckingAtt (self, level, flag_split):
268
+ listAuxNum = []
269
+ if flag_split:
270
+ metadata = md.MetaData(self._getExtraPath(join('level%03d' % level,
271
+ 'level%03d' % level + '_classes.xmd')))
272
+ else:
273
+ metadata = md.MetaData(self._getExtraPath(join('level%03d' % level,
274
+ 'general_level%03d' % level + '_classes.xmd')))
275
+ for item in metadata:
276
+ numImgs = metadata.getValue(md.MDL_CLASS_COUNT, item)
277
+ listAuxNum.append(numImgs)
278
+ total = sum(listAuxNum)
279
+ th = (self.p * total / len(listAuxNum))
280
+ aux = [i for i in listAuxNum if i<th]
281
+ if len(aux)>0:
282
+ return True
283
+ else:
284
+ return False
285
+
286
+
287
+ def checkContinueClassification(self, level, iter):
288
+
289
+ diff=0
290
+ i=0
291
+ metadata = md.MetaData(self._getExtraPath(join('level%03d' % level,
292
+ 'general_images_level%03d' % level + '.xmd')))
293
+
294
+ for item in metadata:
295
+ refImg = metadata.getValue(md.MDL_REF, item)
296
+ nameImg = metadata.getValue(md.MDL_IMAGE, item)
297
+ if iter==0:
298
+ self.listContinueClass.append(nameImg)
299
+ self.listContinueClass.append(refImg)
300
+ else:
301
+ if nameImg in self.listContinueClass:
302
+ idx = self.listContinueClass.index(nameImg) + 1
303
+ if refImg!=self.listContinueClass[idx]:
304
+ diff+=1
305
+ self.listContinueClass[idx]=refImg
306
+ else:
307
+ diff += 1
308
+ self.listContinueClass.append(nameImg)
309
+ self.listContinueClass.append(refImg)
310
+ i+=1
311
+ num=(diff*100/i)
312
+ if num<self.percentStopClassify and iter>0:
313
+ return True
314
+ else:
315
+ return False
316
+
317
+
318
+ def iterationStep (self, refSet, imgsExp, iter, useReferenceImages,
319
+ level, flag_split, flag_attraction):
320
+
321
+ if not exists(join(self._getExtraPath(), 'level%03d' % level)):
322
+ mkdir(join(self._getExtraPath(), 'level%03d' % level))
323
+
324
+ if not useReferenceImages and iter==0 and flag_split==True:
325
+
326
+ # First step: divide the metadata input file to generate
327
+ # a couple of references
328
+ if level==0:
329
+ if not flag_attraction:
330
+ outDirName = imgsExp[0:imgsExp.find('extra')+6] + \
331
+ 'level%03d' % level + imgsExp[imgsExp.find(
332
+ 'extra')+5:-4]
333
+ else:
334
+ outDirName = imgsExp[0:imgsExp.find('extra') + 6] + \
335
+ 'level%03d' % level + imgsExp[imgsExp.find(
336
+ 'level%03d' % level) + 8:-4]
337
+ else:
338
+ if not flag_attraction:
339
+ outDirName = imgsExp[0:imgsExp.find('extra') + 6] + \
340
+ 'level%03d' % level + imgsExp[imgsExp.find(
341
+ 'level%03d' % (level-1)) + 8:-4]
342
+ else:
343
+ outDirName = imgsExp[0:imgsExp.find('extra') + 6] + \
344
+ 'level%03d' % level + imgsExp[imgsExp.find(
345
+ 'level%03d' % level) + 8:-4]
346
+ self._params = {'imgsExp': imgsExp,
347
+ 'outDir': outDirName}
348
+ args = ('-i %(imgsExp)s -n 2 --oroot %(outDir)s')
349
+ self.runJob("xmipp_metadata_split", args % self._params,
350
+ numberOfMpi=1)
351
+
352
+ # Second step: calculate the means of the previous metadata
353
+ expSet1 = outDirName + '000001.xmd'
354
+ avg1 = outDirName + '_000001'
355
+ expSet2 = outDirName + '000002.xmd'
356
+ avg2 = outDirName + '_000002'
357
+ self._params = {'imgsSet': expSet1,
358
+ 'outputAvg': avg1}
359
+ args = ('-i %(imgsSet)s --save_image_stats %(outputAvg)s -v 0')
360
+ self.runJob("xmipp_image_statistics", args % self._params,
361
+ numberOfMpi=1)
362
+
363
+ self._params = {'imgsSet': expSet2,
364
+ 'outputAvg': avg2}
365
+ args = ('-i %(imgsSet)s --save_image_stats %(outputAvg)s -v 0')
366
+ self.runJob("xmipp_image_statistics", args % self._params,
367
+ numberOfMpi=1)
368
+
369
+ # Third step: generate a single metadata with the two previous
370
+ # averages
371
+ refSet = self._getExtraPath(join('level%03d' % level,'refSet.xmd'))
372
+ self._params = {'avg1': avg1 + 'average.xmp',
373
+ 'avg2': avg2 + 'average.xmp',
374
+ 'outputMd': refSet}
375
+ args = ('-i %(avg1)s --set union %(avg2)s -o %(outputMd)s')
376
+ self.runJob("xmipp_metadata_utilities", args % self._params,
377
+ numberOfMpi=1)
378
+
379
+ # Fourth step: calling program xmipp_cuda_align_significant
380
+ metadataRef = md.MetaData(refSet)
381
+ if metadataRef.containsLabel(md.MDL_REF) is False:
382
+ args = ('-i %s --fill ref lineal 1 1 -o %s'%(refSet, refSet))
383
+ self.runJob("xmipp_metadata_utilities", args,
384
+ numberOfMpi=1)
385
+
386
+ count = 0
387
+ GpuListCuda = ''
388
+ if self.useQueueForSteps() or self.useQueue():
389
+ GpuList = environ["CUDA_VISIBLE_DEVICES"]
390
+ GpuList = GpuList.split(",")
391
+ for elem in GpuList:
392
+ GpuListCuda = GpuListCuda + str(count) + ' '
393
+ count += 1
394
+ else:
395
+ GpuListAux = ''
396
+ for elem in self.getGpuList():
397
+ GpuListCuda = GpuListCuda + str(count) + ' '
398
+ GpuListAux = GpuListAux + str(elem) + ','
399
+ count += 1
400
+ environ["CUDA_VISIBLE_DEVICES"] = GpuListAux
401
+
402
+ if flag_split:
403
+ filename = 'level%03d' % level+'_classes.xmd'
404
+ self._params = {'imgsRef': refSet,
405
+ 'imgsExp': imgsExp,
406
+ 'outputFile': 'images_level%03d' % level+'.xmd',
407
+ 'tmpDir': join(self._getExtraPath(),'level%03d'
408
+ % level),
409
+ 'keepBest': self.keepBest.get(),
410
+ 'maxshift': self.maximumShift,
411
+ 'outputClassesFile': filename,
412
+ 'device': GpuListCuda,
413
+ 'outputClassesFileNoExt': splitext(filename)[0],
414
+ }
415
+ else:
416
+ filename = 'general_level%03d' % level + '_classes.xmd'
417
+ self._params = {'imgsRef': refSet,
418
+ 'imgsExp': imgsExp,
419
+ 'outputFile': 'general_images_level%03d' % level
420
+ + '.xmd',
421
+ 'tmpDir': join(self._getExtraPath(),'level%03d'
422
+ % level),
423
+ 'keepBest': self.keepBest.get(),
424
+ 'maxshift': self.maximumShift,
425
+ 'outputClassesFile': filename,
426
+ 'device': GpuListCuda,
427
+ 'outputClassesFileNoExt': splitext(filename)[0],
428
+ }
429
+ Nrefs = getSize(refSet)
430
+ if Nrefs>2:
431
+
432
+ args = '-i %(imgsExp)s -r %(imgsRef)s -o %(outputFile)s ' \
433
+ '--keepBestN 1 --oUpdatedRefs %(outputClassesFileNoExt)s ' \
434
+ '--odir %(tmpDir)s --dev %(device)s'
435
+ self.runJob(CUDA_ALIGN_SIGNIFICANT, args % self._params, numberOfMpi=1)
436
+
437
+ else:
438
+ self._params['Nrefs'] = Nrefs
439
+ self._params['cl2dDir'] = self._getExtraPath(join('level%03d' % level))
440
+ self._params['cl2dDirNew'] = self._getExtraPath(join('level%03d' % level, "level_00"))
441
+ args='-i %(imgsExp)s --ref0 %(imgsRef)s --nref %(Nrefs)d '\
442
+ '--iter 1 --distance correlation --classicalMultiref '\
443
+ '--maxShift %(maxshift)d --odir %(cl2dDir)s --dontMirrorImages '
444
+ self.runJob("xmipp_classify_CL2D",
445
+ args % self._params, numberOfMpi=self.numberOfMpi.get())
446
+
447
+ if flag_split:
448
+ copy(self._getExtraPath(join('level%03d' % level,
449
+ "level_00","class_classes.xmd")),
450
+ self._getExtraPath(join('level%03d' % level,
451
+ 'level%03d' % level
452
+ + '_classes.xmd')))
453
+ copy(self._getExtraPath(join('level%03d' % level,"images.xmd")),
454
+ self._getExtraPath(join('level%03d' % level,
455
+ 'images_level%03d' % level +
456
+ '.xmd')))
457
+ else:
458
+ copy(self._getExtraPath(join('level%03d' % level,
459
+ "level_00", "class_classes.xmd")),
460
+ self._getExtraPath(join('level%03d' % level,
461
+ 'general_level%03d' % level +
462
+ '_classes.xmd')))
463
+ copy(self._getExtraPath(join('level%03d' % level,
464
+ "images.xmd")),
465
+ self._getExtraPath(join('level%03d' % level,
466
+ 'general_images_level%03d' %
467
+ level + '.xmd')))
468
+
469
+
470
+ def attractionSplitStep(self, level):
471
+
472
+ change, labelMaxClass, labelMinClass, mdToReduce, mdToCheck, \
473
+ listNumImgs, listNameImgs = self.checkAttraction(level, True)
474
+
475
+ while change:
476
+
477
+ #Every time we need to make a change (for unbalanced classes) we
478
+ # update with +1 this value
479
+ self.depthSplit += 1
480
+
481
+ self.imgsExp = self._getExtraPath(join('level%03d' % level,
482
+ 'images_level%03d' % level
483
+ + '_NoAtt.xmd'))
484
+ self._params = {'input': 'class%06d_images' % (labelMaxClass) +
485
+ '@' + mdToCheck,
486
+ 'outputMd': self.imgsExp}
487
+ args = ('-i %(input)s -o %(outputMd)s')
488
+ self.runJob("xmipp_metadata_utilities", args % self._params,
489
+ numberOfMpi=1)
490
+
491
+ i = 0
492
+ while i < self.numberOfSplitIterations:
493
+ self.iterationStep(self.refSet, self.imgsExp, i, False,
494
+ level, True, True)
495
+ self.refSet = self._getExtraPath(join('level%03d' % level,
496
+ 'level%03d' % level +
497
+ '_classes.xmd'))
498
+ i+=1
499
+ if self.fastCheckingAtt(level, True):
500
+ break
501
+
502
+ #Recursive calling of this function
503
+ self.attractionSplitStep(level)
504
+
505
+ #When we detect the classes are balanced, we update with -1 this
506
+ # value, because we finish one recursive calling of the function
507
+ if self.depthSplit>1:
508
+ self.depthSplit-=1
509
+ return
510
+ if self.depthSplit==1:
511
+ self.depthSplit=0
512
+
513
+ if (level - 1) >= 0:
514
+ self.imgsExp = self._getExtraPath(join('level%03d' % (
515
+ level-1), 'images_level%03d'%(level-1) + '_major.xmd'))
516
+ else:
517
+ self.imgsExp = self._getExtraPath('imagesExp.xmd')
518
+
519
+ i = self.iterReturnSplit
520
+ if i==self.numberOfSplitIterations:
521
+ i-=1
522
+ while i < self.numberOfSplitIterations:
523
+ self.iterationStep(self.refSet, self.imgsExp, i, True, level,
524
+ True, False)
525
+ self.refSet = self._getExtraPath(join('level%03d' % level,
526
+ 'level%03d' % level +
527
+ '_classes.xmd'))
528
+ i+=1
529
+ if self.fastCheckingAtt(level, True):
530
+ break
531
+
532
+ change, labelMaxClass, __, mdToReduce, mdToCheck, \
533
+ __, __ = self.checkAttraction(level, True)
534
+
535
+ def attractionGeneralStep(self, level):
536
+
537
+ change, labelMaxClass, labelMinClass, mdToReduce, mdToCheck, \
538
+ listNumImgs, listNameImgs = self.checkAttraction(level, False)
539
+
540
+ if change:
541
+ self.depth+=1
542
+
543
+ if change:
544
+ self._params = {'input': 'class%06d_images' % (labelMaxClass) +
545
+ '@' + mdToCheck,
546
+ 'outputMd': self._getExtraPath(join('level%03d'
547
+ % level, 'images_level%03d' % level
548
+ + '_major.xmd'))
549
+ }
550
+ args = ('-i %(input)s -o %(outputMd)s')
551
+ self.runJob("xmipp_metadata_utilities", args % self._params,
552
+ numberOfMpi=1)
553
+
554
+ return change, listNumImgs, listNameImgs
555
+
556
+ def checkAttraction(self, level, flag_split):
557
+
558
+ if flag_split:
559
+ mdToCheck = self._getExtraPath(join('level%03d' % level,
560
+ 'level%03d' % level
561
+ + '_classes.xmd'))
562
+ mdToReduce = self._getExtraPath(join('level%03d' % level,
563
+ 'images_level%03d' % level
564
+ + '.xmd'))
565
+ else:
566
+ mdToCheck = self._getExtraPath(join('level%03d' % level,
567
+ 'general_level%03d' % level
568
+ + '_classes.xmd'))
569
+ mdToReduce = self._getExtraPath(join('level%03d' % level,
570
+ 'general_images_level%03d'
571
+ % level + '.xmd'))
572
+
573
+ listAuxNum=[]
574
+ listAuxName = []
575
+ listAuxRef = []
576
+ metadataItem = md.MetaData(mdToCheck)
577
+ for item in metadataItem:
578
+ numImgs = metadataItem.getValue(md.MDL_CLASS_COUNT, item)
579
+ name = metadataItem.getValue(md.MDL_IMAGE, item)
580
+ ref = metadataItem.getValue(md.MDL_REF, item)
581
+ listAuxNum.append(numImgs)
582
+ listAuxName.append(name)
583
+ listAuxRef.append(ref)
584
+ total = sum(listAuxNum)
585
+
586
+ th = (self.p*total/len(listAuxNum))
587
+ labelMinClass=[]
588
+ for i in range(len(listAuxNum)):
589
+ if listAuxNum[i]<th:
590
+ labelMinClass.append(listAuxRef[i])
591
+ listAuxNum[i] = -1
592
+
593
+ labelMaxClass = listAuxRef[listAuxNum.index(max(listAuxNum))]
594
+ listAuxNum[labelMaxClass-1] = -1
595
+
596
+ if len(labelMinClass)>0:
597
+ change = True
598
+ else:
599
+ change = False
600
+
601
+ return change, labelMaxClass, labelMinClass, mdToReduce, mdToCheck, \
602
+ listAuxNum, listAuxName
603
+
604
+
605
+ def checkOutput(self, level):
606
+
607
+ listAuxString = []
608
+ listAuxNum = []
609
+ listAuxRefs = []
610
+
611
+ outSet = self._getExtraPath(join('level%03d' % level,
612
+ 'intermediate_classes.xmd'))
613
+
614
+ metadataItem = md.MetaData(outSet)
615
+ for item in metadataItem:
616
+ nameImg = metadataItem.getValue(md.MDL_IMAGE, item)
617
+ listAuxString.append(nameImg)
618
+ numImgs = metadataItem.getValue(md.MDL_CLASS_COUNT, item)
619
+ listAuxNum.append(numImgs)
620
+ refImg = metadataItem.getValue(md.MDL_REF, item)
621
+ listAuxRefs.append(refImg)
622
+
623
+ maxValue = max(listAuxNum)
624
+ maxPos = listAuxNum.index(maxValue)
625
+
626
+ listAuxNum[maxPos] = -1
627
+ bestRef = listAuxRefs[maxPos]
628
+
629
+ self._params = {'input': 'class%06d_images' % (bestRef) + '@' + outSet,
630
+ 'outputMd': self._getExtraPath(join('level%03d' %
631
+ level,'images_level%03d' % level
632
+ + '_major.xmd'))
633
+ }
634
+ args = ('-i %(input)s -o %(outputMd)s')
635
+ self.runJob("xmipp_metadata_utilities", args % self._params,
636
+ numberOfMpi=1)
637
+
638
+ return listAuxNum, listAuxString
639
+
640
+
641
+ def generateMetadata(self, listNameImgs, listNumImgs, level):
642
+
643
+ # Renumerate unchanged classes
644
+ listNewNumImages = [-1] * len(listNumImgs)
645
+ count = 1
646
+ for i in range(len(listNumImgs)):
647
+ if listNumImgs[i] != -1:
648
+ listNewNumImages[i] = count
649
+ count += 1
650
+
651
+ # Construct the new classes with the renumerated old classes
652
+ mdNewClasses = md.MetaData()
653
+ for i in range(len(listNumImgs)):
654
+ if listNumImgs[i] != -1:
655
+ name = listNameImgs[i]
656
+ fn = name[name.find('@') + 1:-4] + '.xmd'
657
+ numRef = int(name[0:6])
658
+
659
+ mdClass = md.MetaData("classes@" + fn)
660
+ for row in iterRows(mdClass):
661
+ if mdClass.getValue(md.MDL_REF, row.getObjId()) == numRef:
662
+ row.setValue(md.MDL_REF, listNewNumImages[i])
663
+ row.addToMd(mdNewClasses)
664
+
665
+ # Add the two new classes to the list of renumerated classes
666
+ outSet = self._getExtraPath(join('level%03d' % level, 'level%03d' %
667
+ level + '_classes.xmd'))
668
+ mdClass = md.MetaData("classes@" + outSet)
669
+ rows = iterRows(mdClass)
670
+ for row in rows:
671
+ row.setValue(md.MDL_REF, count)
672
+ row.addToMd(mdNewClasses)
673
+ count = count + 1
674
+ mdNewClasses.write('classes@' + self._getExtraPath(join('level%03d'
675
+ % level,'intermediate_classes.xmd')),
676
+ MD_APPEND)
677
+
678
+ # Generate the intermediate images and the blocks of the intermediate
679
+ # classes for the unchanged classes
680
+ for i in range(len(listNumImgs)):
681
+ if listNumImgs[i] != -1:
682
+ name = listNameImgs[i]
683
+ fn = name[name.find('@') + 1:-4] + '.xmd'
684
+ numRef = int(name[0:6])
685
+
686
+ # Read the list of images in this class
687
+ mdImgsInClass = md.MetaData(
688
+ 'class%06d_images@%s' % (numRef, fn))
689
+ mdImgsInClass.fillConstant(md.MDL_REF, listNewNumImages[i])
690
+ mdImgsInClass.write('class%06d' % (listNewNumImages[i])
691
+ + '_images@' + self._getExtraPath(join(
692
+ 'level%03d' % level,
693
+ 'intermediate_classes.xmd')),
694
+ MD_APPEND)
695
+
696
+ # Add the two new classes
697
+ if len(listNumImgs) == 0:
698
+ count = 1
699
+ else:
700
+ count = len(listNumImgs)
701
+ for newRef in range(getSize(outSet)):
702
+ mdImgsInClass = md.MetaData('class%06d_images@%s' % (newRef + 1, outSet))
703
+ mdImgsInClass.fillConstant(md.MDL_REF, count)
704
+ mdImgsInClass.write('class%06d' % (count) + '_images@'
705
+ + self._getExtraPath(join('level%03d' %
706
+ level,'intermediate_classes.xmd')),
707
+ MD_APPEND)
708
+ count = count + 1
709
+
710
+ def cleaningPath(self, level):
711
+ if exists(self._getExtraPath(join('level%03d' % level,'refSet.xmd'))):
712
+ remove(self._getExtraPath(join('level%03d' % level,'refSet.xmd')))
713
+ if exists(self._getExtraPath(join('level%03d' % level,"images.xmd"))):
714
+ remove(self._getExtraPath(join('level%03d' % level,"images.xmd")))
715
+ level_1=level-1
716
+ if level>0 and exists(self._getExtraPath(join('level%03d' %
717
+ level_1,"images_level%03d_major.xmd" %level_1))):
718
+ remove(self._getExtraPath(join('level%03d' % level_1,
719
+ "images_level%03d_major.xmd"
720
+ %level_1)))
721
+ for f in listdir(join(join(self._getExtraPath(),'level%03d'%level))):
722
+ if not f.find('average')==-1 \
723
+ or not f.find('stddev')==-1 \
724
+ or not f.find('NoAtt')==-1:
725
+ remove(join(join(self._getExtraPath(),'level%03d'%level,f)))
726
+ if level>0 and not f.find('major0') == -1:
727
+ remove(join(join(self._getExtraPath(), 'level%03d' % level, f)))
728
+ if level==0 and not f.find('imagesExp0') == -1:
729
+ remove(join(join(self._getExtraPath(), 'level%03d' % level, f)))
730
+
731
+
732
+
733
+ # --------------------------- UTILS functions ------------------------------
734
+
735
+ def _fillClassesFromLevel(self, clsSet):
736
+ """ Create the SetOfClasses2D from a given iteration. """
737
+ myFileClasses = self._getExtraPath('last_classes.xmd')
738
+ myFileImages = self._getExtraPath('last_images.xmd')
739
+ self._loadClassesInfo(myFileClasses)
740
+ xmpMd = myFileImages
741
+ iterator = md.SetMdIterator(xmpMd, sortByLabel=md.MDL_ITEM_ID,
742
+ updateItemCallback=self._updateParticle,
743
+ skipDisabled=True)
744
+ clsSet.classifyItems(updateItemCallback=iterator.updateItem,
745
+ updateClassCallback=self._updateClass)
746
+
747
+ def _updateParticle(self, item, row):
748
+ item.setClassId(row.getValue(md.MDL_REF))
749
+ item.setTransform(rowToAlignment(row, ALIGN_2D))
750
+
751
+ def _updateClass(self, item):
752
+ classId = item.getObjId()
753
+ if classId in self._classesInfo:
754
+ index, fn, _ = self._classesInfo[classId]
755
+ item.setAlignment2D()
756
+ rep = item.getRepresentative()
757
+ rep.setLocation(index, fn)
758
+ rep.setSamplingRate(self.inputParticles.get().getSamplingRate())
759
+
760
+ def _loadClassesInfo(self, filename):
761
+ """ Read some information about the produced 2D classes
762
+ from the metadata file.
763
+ """
764
+ self._classesInfo = {} # store classes info, indexed by class id
765
+
766
+ mdClasses = md.MetaData(filename)
767
+ for classNumber, row in enumerate(md.iterRows(mdClasses)):
768
+ index, fn = xmippToLocation(row.getValue(md.MDL_IMAGE))
769
+ self._classesInfo[classNumber + 1] = (index, fn, row.clone())
770
+
771
+
772
+ # --------------------------- INFO functions -------------------------------
773
+ def _validate(self):
774
+ errors = []
775
+ if self.useReferenceImages:
776
+ if self.numberOfClasses<self.referenceImages.get().getSize():
777
+ errors.append('The number of classes must be equal or greater'
778
+ ' than the number of references')
779
+ if self.referenceImages.hasValue():
780
+ [x1, y1, _] = self.referenceImages.get().getDimensions()
781
+ [x2, y2, _] = self.inputParticles.get().getDim()
782
+ if x1 != x2 or y1 != y2:
783
+ errors.append('The input images (%s, %s) and the reference images (%s, %s) '
784
+ 'have different sizes' % (x2, y2, x1, y1))
785
+ else:
786
+ errors.append("Please, enter the reference images")
787
+
788
+ return errors
789
+
790
+ def _summary(self):
791
+ summary = []
792
+ if not hasattr(self, 'outputClasses'):
793
+ summary.append("Output alignment not ready yet.")
794
+ else:
795
+ summary.append("Input Particles: %s"
796
+ % self.inputParticles.get().getSize())
797
+ if self.useReferenceImages:
798
+ summary.append("Aligned with reference images: %s"
799
+ % self.referenceImages.get().getSize())
800
+ else:
801
+ summary.append("Aligned with no reference images.")
802
+ return summary
803
+
804
+ def _methods(self):
805
+ methods = []
806
+ if not hasattr(self, 'outputClasses'):
807
+ methods.append("Output alignment not ready yet.")
808
+ else:
809
+ if self.useReferenceImages:
810
+ methods.append("We aligned images %s with respect to the "
811
+ "reference image set %s using Xmipp GPU "
812
+ "correlation method"
813
+ % (self.getObjectTag('inputParticles'),
814
+ self.getObjectTag('referenceImages')))
815
+ else:
816
+ methods.append(
817
+ "We aligned images %s with no references using Xmipp GPU "
818
+ "correlation method" % self.getObjectTag('inputParticles'))
819
+ methods.append(" and produced %s images."
820
+ % self.getObjectTag('outputClasses'))
821
+ return methods