scipion-em-xmipp 24.12.2__py3-none-any.whl → 25.6.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-24.12.2.dist-info → scipion_em_xmipp-25.6.0.dist-info}/METADATA +10 -10
- scipion_em_xmipp-25.6.0.dist-info/RECORD +255 -0
- {scipion_em_xmipp-24.12.2.dist-info → scipion_em_xmipp-25.6.0.dist-info}/WHEEL +1 -1
- {scipion_em_xmipp-24.12.2.dist-info → scipion_em_xmipp-25.6.0.dist-info}/entry_points.txt +0 -1
- xmipp3/__init__.py +106 -73
- xmipp3/base.py +2 -1
- xmipp3/convert/convert.py +1 -1
- xmipp3/legacy/protocols/protocol_angular_resolution_alignment.py +204 -0
- xmipp3/legacy/protocols/protocol_apply_deformation_zernike3d.py +113 -0
- xmipp3/legacy/protocols/protocol_classification_gpuCorr.py +821 -0
- xmipp3/legacy/protocols/protocol_classification_gpuCorr_full.py +1014 -0
- xmipp3/legacy/protocols/protocol_classification_gpuCorr_semi.py +462 -0
- xmipp3/legacy/protocols/protocol_classify_kmeans2d.py +285 -0
- xmipp3/legacy/protocols/protocol_deep_align.py +859 -0
- xmipp3/legacy/protocols/protocol_deep_denoising.py +425 -0
- xmipp3/legacy/protocols/protocol_kmeans_clustering.py +122 -0
- xmipp3/legacy/protocols/protocol_metaprotocol_create_output.py +146 -0
- xmipp3/legacy/protocols/protocol_metaprotocol_create_subset.py +96 -0
- xmipp3/legacy/protocols/protocol_metaprotocol_discrete_heterogeneity_scheduler.py +516 -0
- xmipp3/legacy/protocols/protocol_metaprotocol_golden_highres.py +663 -0
- xmipp3/legacy/protocols/protocol_mltomo.py +576 -0
- xmipp3/legacy/protocols/protocol_movie_average.py +202 -0
- xmipp3/legacy/protocols/protocol_movie_opticalflow.py +416 -0
- xmipp3/legacy/protocols/protocol_particle_boxsize.py +133 -0
- xmipp3/legacy/protocols/protocol_reconstruct_heterogeneous.py +1031 -0
- xmipp3/legacy/protocols/protocol_rotational_spectra.py +212 -0
- xmipp3/legacy/protocols/protocol_solid_angles.py +632 -0
- xmipp3/legacy/protocols/protocol_split_volume.py +112 -0
- xmipp3/legacy/protocols/protocol_split_volume_hierarchical_cluster.py +865 -0
- xmipp3/legacy/protocols/protocol_subtract_projection.py +265 -0
- xmipp3/legacy/tests/test_protocol_deep_denoising.py +64 -0
- xmipp3/legacy/tests/test_protocols_angular_resolution_alignment.py +88 -0
- xmipp3/legacy/tests/test_protocols_gpuCorr_classifier.py +141 -0
- xmipp3/legacy/tests/test_protocols_gpuCorr_fullStreaming.py +172 -0
- xmipp3/legacy/tests/test_protocols_gpuCorr_semiStreaming.py +68 -0
- xmipp3/legacy/tests/test_protocols_metaprotocol_golden_highres.py +96 -0
- xmipp3/legacy/tests/test_protocols_metaprotocol_heterogeneity.py +78 -0
- xmipp3/legacy/tests/test_protocols_mixed_movies.py +148 -0
- xmipp3/legacy/tests/test_protocols_solid_angles.py +161 -0
- xmipp3/legacy/tests/test_protocols_subtract_projection.py +595 -0
- xmipp3/legacy/tests/test_protocols_xmipp_movies.py +229 -0
- xmipp3/legacy/viewers/viewer_angular_resolution_alignment.py +148 -0
- xmipp3/legacy/viewers/viewer_deep_align.py +121 -0
- xmipp3/legacy/viewers/viewer_metaprotocol_golden_highres.py +140 -0
- xmipp3/legacy/viewers/viewer_mltomo.py +297 -0
- xmipp3/legacy/viewers/viewer_solid_angles.py +91 -0
- xmipp3/legacy/viewers/viewer_split_volume.py +57 -0
- xmipp3/protocols/__init__.py +1 -2
- xmipp3/protocols/protocol_align_volume.py +34 -8
- xmipp3/protocols/protocol_apply_alignment.py +1 -1
- xmipp3/protocols/protocol_apply_tilt_to_ctf.py +2 -3
- xmipp3/protocols/protocol_apply_zernike3d.py +2 -1
- xmipp3/protocols/protocol_assignment_tilt_pair.py +1 -2
- xmipp3/protocols/protocol_center_particles.py +1 -1
- xmipp3/protocols/protocol_cl2d.py +1 -2
- xmipp3/protocols/protocol_cl2d_align.py +1 -1
- xmipp3/protocols/protocol_cl2d_clustering.py +1 -1
- xmipp3/protocols/protocol_classify_pca.py +25 -9
- xmipp3/protocols/protocol_classify_pca_streaming.py +67 -42
- xmipp3/protocols/protocol_compute_likelihood.py +368 -0
- xmipp3/protocols/protocol_consensus_local_ctf.py +1 -1
- xmipp3/protocols/protocol_convert_pdb.py +9 -1
- xmipp3/protocols/protocol_create_gallery.py +1 -1
- xmipp3/protocols/protocol_ctf_consensus.py +14 -8
- xmipp3/protocols/protocol_ctf_correct_wiener2d.py +1 -1
- xmipp3/protocols/protocol_ctf_micrographs.py +1 -1
- xmipp3/protocols/protocol_deep_center_predict.py +10 -1
- xmipp3/protocols/protocol_deep_hand.py +19 -2
- xmipp3/protocols/protocol_deep_micrograph_screen.py +1 -1
- xmipp3/protocols/protocol_extract_asymmetric_unit.py +1 -1
- xmipp3/protocols/protocol_extract_particles.py +22 -10
- xmipp3/protocols/protocol_extract_particles_movies.py +1 -1
- xmipp3/protocols/protocol_extract_particles_pairs.py +1 -1
- xmipp3/protocols/protocol_flexalign.py +3 -4
- xmipp3/protocols/protocol_helical_parameters.py +1 -4
- xmipp3/protocols/protocol_movie_alignment_consensus.py +122 -40
- xmipp3/protocols/protocol_movie_dose_analysis.py +79 -82
- xmipp3/protocols/protocol_movie_max_shift.py +6 -2
- xmipp3/protocols/protocol_movie_split_frames.py +165 -88
- xmipp3/protocols/protocol_particle_pick_automatic.py +1 -2
- xmipp3/protocols/protocol_particle_pick_consensus.py +7 -0
- xmipp3/protocols/protocol_particle_pick_pairs.py +1 -1
- xmipp3/protocols/protocol_phantom_create.py +1 -1
- xmipp3/protocols/protocol_pick_noise.py +1 -1
- xmipp3/protocols/protocol_postProcessing_deepPostProcessing.py +5 -5
- xmipp3/protocols/protocol_preprocess/protocol_crop_resize.py +3 -2
- xmipp3/protocols/protocol_preprocess/protocol_filter.py +2 -2
- xmipp3/protocols/protocol_preprocess/protocol_image_operate.py +2 -2
- xmipp3/protocols/protocol_preprocess/protocol_mask.py +1 -1
- xmipp3/protocols/protocol_preprocess/protocol_preprocess.py +6 -4
- xmipp3/protocols/protocol_preprocess/protocol_process.py +20 -7
- xmipp3/protocols/protocol_preprocess_micrographs.py +3 -2
- xmipp3/protocols/protocol_projmatch/projmatch_steps.py +1 -1
- xmipp3/protocols/protocol_projmatch/protocol_projmatch.py +1 -1
- xmipp3/protocols/protocol_random_conical_tilt.py +1 -2
- xmipp3/protocols/protocol_ransac.py +41 -37
- xmipp3/protocols/protocol_reconstruct_fourier.py +5 -1
- xmipp3/protocols/protocol_reconstruct_highres.py +13 -7
- xmipp3/protocols/protocol_reconstruct_significant.py +14 -21
- xmipp3/protocols/protocol_resolution3d.py +1 -1
- xmipp3/protocols/protocol_resolution_deepres.py +1 -1
- xmipp3/protocols/protocol_resolution_directional.py +1 -1
- xmipp3/protocols/protocol_resolution_fso.py +1 -1
- xmipp3/protocols/protocol_resolution_monogenic_signal.py +19 -4
- xmipp3/protocols/protocol_rotate_volume.py +1 -1
- xmipp3/protocols/protocol_screen_deepConsensus.py +25 -5
- xmipp3/protocols/protocol_shift_volume.py +1 -1
- xmipp3/protocols/protocol_simulate_ctf.py +5 -3
- xmipp3/protocols/protocol_structure_map.py +9 -1
- xmipp3/protocols/protocol_subtract_projection.py +25 -10
- xmipp3/protocols/protocol_tilt_analysis.py +3 -3
- xmipp3/protocols/protocol_validate_fscq.py +2 -2
- xmipp3/protocols/protocol_validate_nontilt.py +1 -1
- xmipp3/protocols/protocol_volume_adjust_sub.py +8 -4
- xmipp3/protocols/protocol_volume_deform_zernike3d.py +1 -1
- xmipp3/protocols/protocol_volume_local_sharpening.py +1 -1
- xmipp3/protocols/protocol_volume_strain.py +1 -1
- xmipp3/protocols.conf +1 -3
- xmipp3/tests/test_protocol_likelihood.py +240 -0
- xmipp3/tests/test_protocol_split_frames.py +136 -0
- xmipp3/tests/test_protocol_validate_fscq.py +2 -2
- xmipp3/tests/test_protocols_highres.py +44 -5
- xmipp3/tests/test_protocols_xmipp_2d.py +1 -48
- xmipp3/tests/test_protocols_xmipp_mics.py +20 -16
- xmipp3/tests/test_protocols_xmipp_movies.py +4 -4
- xmipp3/version.py +5 -5
- xmipp3/viewers/__init__.py +1 -1
- xmipp3/viewers/viewer_LL_matrix.py +273 -0
- xmipp3/viewers/viewer_deep_consensus.py +1 -7
- xmipp3/viewers/viewer_dose_analysis.py +18 -2
- xmipp3/viewers/viewer_resolution_fso.py +18 -6
- xmipp3/viewers/viewer_structure_map.py +53 -11
- xmipp3/wizards.py +3 -2
- xmipp3/xmipp_logo_devel.png +0 -0
- scipion_em_xmipp-24.12.2.dist-info/RECORD +0 -210
- {scipion_em_xmipp-24.12.2.dist-info → scipion_em_xmipp-25.6.0.dist-info}/LICENSE +0 -0
- {scipion_em_xmipp-24.12.2.dist-info → scipion_em_xmipp-25.6.0.dist-info}/top_level.txt +0 -0
- /xmipp3/{protocols → legacy/protocols}/protocol_enrich.py +0 -0
- /xmipp3/{protocols → legacy/protocols}/protocol_screen_deeplearning.py +0 -0
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
# **************************************************************************
|
|
2
|
+
# *
|
|
3
|
+
# * Authors: Javier Mota (original implementation)
|
|
4
|
+
# * Ruben Sanchez (added U-net and refactoring)
|
|
5
|
+
# *
|
|
6
|
+
# * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
|
|
7
|
+
# *
|
|
8
|
+
# * This program is free software; you can redistribute it and/or modify
|
|
9
|
+
# * it under the terms of the GNU General Public License as published by
|
|
10
|
+
# * the Free Software Foundation; either version 2 of the License, or
|
|
11
|
+
# * (at your option) any later version.
|
|
12
|
+
# *
|
|
13
|
+
# * This program is distributed in the hope that it will be useful,
|
|
14
|
+
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
# * GNU General Public License for more details.
|
|
17
|
+
# *
|
|
18
|
+
# * You should have received a copy of the GNU General Public License
|
|
19
|
+
# * along with this program; if not, write to the Free Software
|
|
20
|
+
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
21
|
+
# * 02111-1307 USA
|
|
22
|
+
# *
|
|
23
|
+
# * All comments concerning this program package may be sent to the
|
|
24
|
+
# * e-mail address 'scipion@cnb.csic.es'
|
|
25
|
+
# *
|
|
26
|
+
# **************************************************************************
|
|
27
|
+
|
|
28
|
+
import json
|
|
29
|
+
from shutil import copyfile
|
|
30
|
+
import sys, os
|
|
31
|
+
import numpy as np
|
|
32
|
+
import re
|
|
33
|
+
|
|
34
|
+
from pyworkflow import VERSION_2_0
|
|
35
|
+
import pyworkflow.protocol.params as params
|
|
36
|
+
import pyworkflow.protocol.constants as cons
|
|
37
|
+
from pyworkflow.utils.path import cleanPath
|
|
38
|
+
|
|
39
|
+
import pwem.emlib.metadata as md
|
|
40
|
+
from pwem import emlib
|
|
41
|
+
|
|
42
|
+
import xmipp3
|
|
43
|
+
from xmipp3.convert import writeSetOfParticles, setXmippAttributes, xmippToLocation
|
|
44
|
+
from xmipp3.protocols import XmippProtCompareReprojections
|
|
45
|
+
from xmipp3.protocols import XmippProtGenerateReprojections
|
|
46
|
+
from xmipp3 import XmippProtocol
|
|
47
|
+
|
|
48
|
+
from pyworkflow import BETA, UPDATED, NEW, PROD
|
|
49
|
+
|
|
50
|
+
EXEC_MODES = ['Train & Predict', 'Predict']
|
|
51
|
+
ITER_TRAIN = 0
|
|
52
|
+
ITER_PREDICT = 1
|
|
53
|
+
|
|
54
|
+
MODEL_TYPES = ["GAN", "U-Net"]
|
|
55
|
+
MODEL_TYPE_GAN = 0
|
|
56
|
+
MODEL_TYPE_UNET = 1
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
TRAINING_DATA_MODE = ["ParticlesAndSyntheticNoise", "OnlyParticles"]
|
|
60
|
+
TRAINING_DATA_MODE_SYNNOISE = 0
|
|
61
|
+
TRAINING_DATA_MODE_PARTS = 1
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
TRAINING_LOSS = [ "MSE", "PerceptualLoss", "Both"]
|
|
65
|
+
TRAINING_LOSS_MSE = 0
|
|
66
|
+
TRAINING_LOSS_PERCEPTUAL = 1
|
|
67
|
+
TRAINING_LOSS_BOTH = 2
|
|
68
|
+
|
|
69
|
+
PRED_BATCH_SIZE=2000
|
|
70
|
+
|
|
71
|
+
class XmippProtDeepDenoising(XmippProtGenerateReprojections, XmippProtocol):
|
|
72
|
+
|
|
73
|
+
_label ="deep denoising"
|
|
74
|
+
_lastUpdateVersion = VERSION_2_0
|
|
75
|
+
_conda_env = 'xmipp_DLTK_v0.3'
|
|
76
|
+
_devStatus = BETA
|
|
77
|
+
|
|
78
|
+
def __init__(self, **args):
|
|
79
|
+
XmippProtGenerateReprojections.__init__(self, **args)
|
|
80
|
+
|
|
81
|
+
def _defineParams(self, form):
|
|
82
|
+
|
|
83
|
+
form.addSection('Input')
|
|
84
|
+
form.addHidden(params.GPU_LIST, params.StringParam,
|
|
85
|
+
expertLevel=cons.LEVEL_ADVANCED,
|
|
86
|
+
label="Choose GPU IDs", default='0',
|
|
87
|
+
help="GPU may have several cores. Set it to zero"
|
|
88
|
+
" if you do not know what we are talking about."
|
|
89
|
+
" First core index is 0, second 1 and so on."
|
|
90
|
+
" In case to use several GPUs separate with comas:"
|
|
91
|
+
"0,1,2")
|
|
92
|
+
|
|
93
|
+
form.addParam('modelTrainPredMode', params.EnumParam, choices=EXEC_MODES,
|
|
94
|
+
default=ITER_TRAIN,
|
|
95
|
+
label='Train or predict model',
|
|
96
|
+
help='*Train*: Train the model using noisy particles '
|
|
97
|
+
'or their projections in an initial volume'
|
|
98
|
+
'*Predict*: The particles are denoised with a '
|
|
99
|
+
'pretrained model')
|
|
100
|
+
|
|
101
|
+
form.addParam('continueTraining', params.BooleanParam, default = False,
|
|
102
|
+
condition='modelTrainPredMode==%d'%ITER_TRAIN,
|
|
103
|
+
label='Continue training? (or train from scratch)', help='Setting "yes" '
|
|
104
|
+
'you can continue training from pretrained model '
|
|
105
|
+
' or your previous executions. If you choose'
|
|
106
|
+
'"no" the model will be trained from scratch. yes option is experimental')
|
|
107
|
+
|
|
108
|
+
form.addParam('customModelOverPretrain', params.BooleanParam, default = False,
|
|
109
|
+
condition='modelTrainPredMode==%d or continueTraining'%ITER_PREDICT,
|
|
110
|
+
label='Use your own model (or use pretrained)', help='Setting "yes" '
|
|
111
|
+
'you can choose your own model trained. If you choose'
|
|
112
|
+
'"no" a general model pretrained will be assign')
|
|
113
|
+
|
|
114
|
+
form.addParam('ownModel', params.PointerParam,
|
|
115
|
+
pointerClass=self.getClassName(),
|
|
116
|
+
condition='customModelOverPretrain==True and (modelTrainPredMode==%d or continueTraining)'%ITER_PREDICT,
|
|
117
|
+
label='Set your model',
|
|
118
|
+
help='Choose the protocol where your model is trained')
|
|
119
|
+
|
|
120
|
+
form.addParam('modelType', params.EnumParam,
|
|
121
|
+
choices=MODEL_TYPES,
|
|
122
|
+
default=MODEL_TYPE_UNET,
|
|
123
|
+
condition='modelTrainPredMode==%d'%ITER_TRAIN,
|
|
124
|
+
label='Select model type',
|
|
125
|
+
help='If you set to *%s*, GAN will be employed '
|
|
126
|
+
'employed. If you set to *%s* U-Net will be used instead'
|
|
127
|
+
% tuple(MODEL_TYPES))
|
|
128
|
+
|
|
129
|
+
form.addParam('inputProjections', params.PointerParam, allowsNull=True,
|
|
130
|
+
pointerClass='SetOfParticles', important=False,
|
|
131
|
+
label='Input projections to train (mandatory)/compare (optional)',
|
|
132
|
+
help='use the protocol generate reprojections to generate the '
|
|
133
|
+
'projections. If compare reprojections protocol output is used as '
|
|
134
|
+
'"Input noisy particles", this field is ignored')
|
|
135
|
+
|
|
136
|
+
form.addParam('inputParticles', params.PointerParam,
|
|
137
|
+
pointerClass='SetOfParticles', important=True,
|
|
138
|
+
label='Input noisy particles to denoise', help='Input noisy '
|
|
139
|
+
'particles from the protocol generate reprojections if '
|
|
140
|
+
'you are training or from any other protocol if you are '
|
|
141
|
+
'predicting. If compare reprojections protocol output is used as '
|
|
142
|
+
'"Input noisy particles", "Input projections to train" is ignored')
|
|
143
|
+
|
|
144
|
+
form.addParam('emptyParticles', params.PointerParam, expertLevel=cons.LEVEL_ADVANCED,
|
|
145
|
+
pointerClass='SetOfParticles', allowsNull=True,
|
|
146
|
+
label='Input "empty" particles (optional)', help='Input "empty" '
|
|
147
|
+
'particles to learn how to deal with pure noise')
|
|
148
|
+
|
|
149
|
+
form.addParam('imageSize', params.IntParam, allowsNull=True, expertLevel=cons.LEVEL_ADVANCED,
|
|
150
|
+
condition='modelTrainPredMode==%d and not continueTraining'%ITER_TRAIN,
|
|
151
|
+
label='Scale images to (px)',
|
|
152
|
+
default=-1, help='Scale particles to desired size to improve training'
|
|
153
|
+
'The recommended particle size is 128 px. The size must be even.'
|
|
154
|
+
'Do not use loss=perceptualLoss or loss=Both if 96< size <150.')
|
|
155
|
+
|
|
156
|
+
form.addSection(label='Training')
|
|
157
|
+
|
|
158
|
+
form.addParam('nEpochs', params.FloatParam,
|
|
159
|
+
condition='modelTrainPredMode==%d'%ITER_TRAIN,
|
|
160
|
+
label="Number of epochs", default=25.0,
|
|
161
|
+
help='Number of epochs for neural network training. GAN requires much '
|
|
162
|
+
'more epochs (>100) to obtain succesfull results')
|
|
163
|
+
|
|
164
|
+
form.addParam('learningRate', params.FloatParam,
|
|
165
|
+
condition='modelTrainPredMode==%d'%ITER_TRAIN,
|
|
166
|
+
label="Learning rate", default=1e-4,
|
|
167
|
+
help='Learning rate for neural network training')
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
form.addParam('modelDepth', params.IntParam, default=4,
|
|
171
|
+
condition='modelTrainPredMode==%d'%ITER_TRAIN, expertLevel=cons.LEVEL_ADVANCED,
|
|
172
|
+
label='Model depth',
|
|
173
|
+
help='Indicate the model depth. For 128-64 px images, 4 is the recommend value. '
|
|
174
|
+
' larger images may require bigger models')
|
|
175
|
+
|
|
176
|
+
form.addParam('regularizationStrength', params.FloatParam, default=1e-5,
|
|
177
|
+
condition='modelTrainPredMode==%d'%ITER_TRAIN, expertLevel=cons.LEVEL_ADVANCED,
|
|
178
|
+
label='Regularization strength',
|
|
179
|
+
help='Indicate the regularization strength. Make it bigger if sufferening overfitting'
|
|
180
|
+
' and smaller if suffering underfitting')
|
|
181
|
+
|
|
182
|
+
form.addParam('trainingSetType', params.EnumParam, choices=TRAINING_DATA_MODE,
|
|
183
|
+
condition='modelTrainPredMode==%d'%ITER_TRAIN,
|
|
184
|
+
default=TRAINING_DATA_MODE_SYNNOISE, expertLevel=cons.LEVEL_ADVANCED,
|
|
185
|
+
label='Select how to generate training set',
|
|
186
|
+
help='*ParticlesAndSyntheticNoise*: Train using particles and synthetic noise\n'
|
|
187
|
+
'or\n*OnlyParticles*: using only particles\n'
|
|
188
|
+
'or\n*Both*: Train using both strategies')
|
|
189
|
+
|
|
190
|
+
form.addParam('trainingLoss', params.EnumParam, choices=TRAINING_LOSS,
|
|
191
|
+
condition='modelTrainPredMode==%d'%ITER_TRAIN,
|
|
192
|
+
default=TRAINING_LOSS_BOTH, expertLevel=cons.LEVEL_ADVANCED,
|
|
193
|
+
label='Select loss for training',
|
|
194
|
+
help='*MSE*: Train using mean squered error or\n*PerceptualLoss*: '
|
|
195
|
+
'Train using DeepConsensus perceptual loss\n or\n*Both*: Train '
|
|
196
|
+
'using both DeepConsensus perceptual loss and mean squered error\n')
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
form.addParam('numberOfDiscVsGenUpdates', params.IntParam, default=5,
|
|
200
|
+
condition='modelType==%d and modelTrainPredMode==%d'%(MODEL_TYPE_GAN, ITER_TRAIN),
|
|
201
|
+
expertLevel=cons.LEVEL_ADVANCED,
|
|
202
|
+
label='D/G trainig ratio',
|
|
203
|
+
help='Indicate the number of times the discriminator is trained for each '
|
|
204
|
+
'generator training step. If discriminator loss is going to 0, make it '
|
|
205
|
+
'smaller, whereas if the discriminator is not training, make it bigger')
|
|
206
|
+
|
|
207
|
+
form.addParam('loss_logWeight', params.FloatParam, default=3, expertLevel=cons.LEVEL_ADVANCED,
|
|
208
|
+
condition='modelType==%d and modelTrainPredMode==%d'%(MODEL_TYPE_GAN, ITER_TRAIN),
|
|
209
|
+
label='D/G loss ratio',
|
|
210
|
+
help='Indicate the 10^lossRatio times that the generator loss is stronger than '
|
|
211
|
+
' the discriminator loss. If discriminator loss is going to 0, make it '
|
|
212
|
+
'smaller, whereas if the generator is not training, make it bigger')
|
|
213
|
+
|
|
214
|
+
form.addParallelSection(threads=2, mpi=0)
|
|
215
|
+
|
|
216
|
+
# --------------------------- INSERT steps functions --------------------------------------------
|
|
217
|
+
def _insertAllSteps(self):
|
|
218
|
+
|
|
219
|
+
deps = []
|
|
220
|
+
ret= self._insertFunctionStep('preprocessData', prerequisites=[])
|
|
221
|
+
deps+= [ret]
|
|
222
|
+
if self.modelTrainPredMode.get() == ITER_TRAIN:
|
|
223
|
+
ret= self._insertFunctionStep('trainModel', prerequisites=deps)
|
|
224
|
+
deps+= [ret]
|
|
225
|
+
ret= self._insertFunctionStep('predictModel', prerequisites=deps)
|
|
226
|
+
deps+= [ret]
|
|
227
|
+
ret= self._insertFunctionStep('createOutputStep', prerequisites=deps)
|
|
228
|
+
deps+= [ret]
|
|
229
|
+
|
|
230
|
+
def _validate(self):
|
|
231
|
+
errorMsg = []
|
|
232
|
+
if not self.checkIfInputIsCompareReprojection() and self.modelTrainPredMode.get()==ITER_TRAIN and self.inputProjections.get() is None:
|
|
233
|
+
errorMsg.append("Error, in training mode, both particles and projections must be provided")
|
|
234
|
+
if self.imageSize.get() is None and self.modelTrainPredMode.get()==ITER_TRAIN:
|
|
235
|
+
errorMsg.append("Error, in training mode, image size must be provided")
|
|
236
|
+
return errorMsg
|
|
237
|
+
|
|
238
|
+
def _getResizedSize(self):
|
|
239
|
+
resizedSize= self.imageSize.get()
|
|
240
|
+
if self.modelTrainPredMode.get()==ITER_PREDICT:
|
|
241
|
+
if self.customModelOverPretrain.get()== True:
|
|
242
|
+
resizedSize= self.ownModel.get()._getResizedSize()
|
|
243
|
+
else:
|
|
244
|
+
resizedSize= 128
|
|
245
|
+
resizedSize= resizedSize if resizedSize>0 else 128
|
|
246
|
+
return resizedSize
|
|
247
|
+
|
|
248
|
+
def getStackOrResize(self, setOfParticles, mdFnameIn, stackFnameOut):
|
|
249
|
+
|
|
250
|
+
if self._getResizedSize()== self.inputParticles.get().getDimensions()[0]:
|
|
251
|
+
mdFname= re.sub(r"\.stk$", r".xmd", stackFnameOut)
|
|
252
|
+
writeSetOfParticles(setOfParticles, mdFname )
|
|
253
|
+
self.runJob("xmipp_image_convert", "-i %s -o %s " % (mdFname, stackFnameOut))
|
|
254
|
+
else:
|
|
255
|
+
writeSetOfParticles(setOfParticles, mdFnameIn)
|
|
256
|
+
self.runJob("xmipp_image_resize", "-i %s -o %s --fourier %d" % (mdFnameIn, stackFnameOut,
|
|
257
|
+
self._getResizedSize()))
|
|
258
|
+
def copyStackAndResize(self, stackIn, stackOut):
|
|
259
|
+
copyfile(stackIn, stackOut + ".tmp")
|
|
260
|
+
if self._getResizedSize() != self.inputParticles.get().getDimensions()[0]:
|
|
261
|
+
self.runJob("xmipp_image_resize",
|
|
262
|
+
"-i %s -o %s --fourier %d" % (stackOut + ".tmp", stackOut, self._getResizedSize()))
|
|
263
|
+
os.remove(stackOut + ".tmp")
|
|
264
|
+
|
|
265
|
+
def checkIfInputIsCompareReprojection(self):
|
|
266
|
+
return isinstance( self.inputParticles.getObjValue(), XmippProtCompareReprojections)
|
|
267
|
+
|
|
268
|
+
def preprocessData(self):
|
|
269
|
+
|
|
270
|
+
particlesFname = self._getExtraPath('noisyParticles.xmd')
|
|
271
|
+
fnNewParticles = self._getExtraPath('resizedParticles.stk')
|
|
272
|
+
projectionsFname = self._getExtraPath('projections.xmd')
|
|
273
|
+
fnNewProjections = self._getExtraPath('resizedProjections.stk')
|
|
274
|
+
|
|
275
|
+
if self.checkIfInputIsCompareReprojection():
|
|
276
|
+
for part in self.inputParticles.get():
|
|
277
|
+
projections_stk, particles_stk= part._xmipp_imageRef._filename.get(), part._xmipp_image._filename.get()
|
|
278
|
+
print(projections_stk, particles_stk)
|
|
279
|
+
break
|
|
280
|
+
self.copyStackAndResize(particles_stk, fnNewParticles)
|
|
281
|
+
self.copyStackAndResize(projections_stk, fnNewProjections)
|
|
282
|
+
else:
|
|
283
|
+
self.getStackOrResize(self.inputParticles.get(), particlesFname, fnNewParticles)
|
|
284
|
+
|
|
285
|
+
if not self.inputProjections.get() is None:
|
|
286
|
+
|
|
287
|
+
self.getStackOrResize(self.inputProjections.get(), projectionsFname, fnNewProjections)
|
|
288
|
+
|
|
289
|
+
if not self.emptyParticles.get() is None:
|
|
290
|
+
emptyPartsFname = self._getExtraPath('emptyParts.xmd')
|
|
291
|
+
fnNewEmptyParts = self._getExtraPath('resizedEmptyParts.stk')
|
|
292
|
+
self.getStackOrResize(self.emptyParticles.get(), emptyPartsFname, fnNewEmptyParts)
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
def trainModel(self):
|
|
296
|
+
|
|
297
|
+
modelFname = self._getPath('ModelTrained.h5')
|
|
298
|
+
builder_args= {"modelType":MODEL_TYPES[self.modelType.get()], "boxSize":self._getResizedSize(),
|
|
299
|
+
"saveModelFname":modelFname,
|
|
300
|
+
"modelDepth": self.modelDepth.get(), "gpuList":self.gpuList.get(),
|
|
301
|
+
"generatorLoss": TRAINING_LOSS[self.trainingLoss.get()],
|
|
302
|
+
"trainingDataMode": TRAINING_DATA_MODE[self.trainingSetType.get()],
|
|
303
|
+
"regularizationStrength": self.regularizationStrength.get() }
|
|
304
|
+
if self.modelType.get() == MODEL_TYPE_GAN:
|
|
305
|
+
builder_args["training_DG_ratio"]= self.numberOfDiscVsGenUpdates.get()
|
|
306
|
+
builder_args["loss_logWeight"]= self.loss_logWeight.get()
|
|
307
|
+
|
|
308
|
+
dataPathParticles= self._getExtraPath('resizedParticles.xmd')
|
|
309
|
+
dataPathProjections= self._getExtraPath('resizedProjections.xmd')
|
|
310
|
+
dataPathEmpty= self._getExtraPath('resizedEmptyParts.xmd')
|
|
311
|
+
|
|
312
|
+
argsDict={}
|
|
313
|
+
argsDict["builder"]=builder_args
|
|
314
|
+
argsDict["running"]={"lr":self.learningRate.get(), "nEpochs":self.nEpochs.get()}
|
|
315
|
+
|
|
316
|
+
jsonFname= self._getExtraPath("training_conf.json")
|
|
317
|
+
with open(jsonFname, "w") as f:
|
|
318
|
+
json.dump(argsDict, f)
|
|
319
|
+
|
|
320
|
+
args= " --mode training -i %s -p %s -c %s "%(dataPathParticles, dataPathProjections, jsonFname)
|
|
321
|
+
if os.path.isfile(dataPathEmpty):
|
|
322
|
+
args+=" --empty_particles %s"%dataPathEmpty
|
|
323
|
+
|
|
324
|
+
self.runJob("xmipp_deep_denoising", args, numberOfMpi=1,
|
|
325
|
+
env=self.getCondaEnv())
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
def _getModelFname(self):
|
|
329
|
+
if self.modelTrainPredMode.get() == ITER_PREDICT:
|
|
330
|
+
if self.customModelOverPretrain == True:
|
|
331
|
+
modelFname = self.ownModel.get()._getPath('ModelTrained.h5')
|
|
332
|
+
else:
|
|
333
|
+
modelFname = self.getModel('deepDenoising', 'ModelTrained.h5')
|
|
334
|
+
else:
|
|
335
|
+
modelFname = self._getPath('ModelTrained.h5')
|
|
336
|
+
if self.continueTraining.get():
|
|
337
|
+
if self.customModelOverPretrain == True:
|
|
338
|
+
modelFnameInit = self.ownModel.get()._getPath('ModelTrained.h5')
|
|
339
|
+
else:
|
|
340
|
+
modelFnameInit = self.getModel('deepDenoising', 'ModelTrained.h5')
|
|
341
|
+
|
|
342
|
+
copyfile(modelFnameInit, modelFname)
|
|
343
|
+
return modelFname
|
|
344
|
+
|
|
345
|
+
def predictModel(self):
|
|
346
|
+
|
|
347
|
+
builder_args = {"boxSize": self._getResizedSize(), "saveModelFname": self._getModelFname(),
|
|
348
|
+
"modelDepth": -1, "gpuList": self.gpuList.get(),"modelType":MODEL_TYPES[self.modelType.get()],
|
|
349
|
+
"generatorLoss": TRAINING_LOSS[self.trainingLoss.get()], "batchSize": PRED_BATCH_SIZE}
|
|
350
|
+
argsDict={}
|
|
351
|
+
argsDict["builder"] = builder_args
|
|
352
|
+
|
|
353
|
+
jsonFname = self._getExtraPath("predict_conf.json")
|
|
354
|
+
with open(jsonFname, "w") as f:
|
|
355
|
+
json.dump(argsDict, f)
|
|
356
|
+
|
|
357
|
+
inputParticlesMdName = self._getExtraPath('resizedParticles.xmd')
|
|
358
|
+
dataPathProjections = self._getExtraPath('resizedProjections.xmd')
|
|
359
|
+
outputParticlesMdName = self._getExtraPath('particlesDenoised.xmd')
|
|
360
|
+
|
|
361
|
+
args = " --mode denoising -i %s -c %s -o %s"% (inputParticlesMdName, jsonFname, outputParticlesMdName)
|
|
362
|
+
|
|
363
|
+
if os.path.isfile(dataPathProjections):
|
|
364
|
+
args += " -p %s" % dataPathProjections
|
|
365
|
+
elif self.checkIfInputIsCompareReprojection():
|
|
366
|
+
args += " -p %s" % self._getExtraPath('resizedProjections.stk')
|
|
367
|
+
|
|
368
|
+
self.runJob("xmipp_deep_denoising", args, numberOfMpi=1,
|
|
369
|
+
env=self.getCondaEnv())
|
|
370
|
+
|
|
371
|
+
def createOutputStep(self):
|
|
372
|
+
imgSet = self.inputParticles.get()
|
|
373
|
+
outputSet = self._createSetOfParticles()
|
|
374
|
+
outputSet.copyInfo(imgSet)
|
|
375
|
+
Ts = imgSet.getSamplingRate()
|
|
376
|
+
xdim = imgSet.getDimensions()[0]
|
|
377
|
+
outputSet.setSamplingRate((Ts*xdim)/self._getResizedSize())
|
|
378
|
+
writeSetOfParticles(self.inputParticles.get(), self._getExtraPath('inputParticles.xmd'))
|
|
379
|
+
imgFname = self._getExtraPath('particlesDenoised.xmd')
|
|
380
|
+
outputSet.copyItems(imgSet, updateItemCallback=self._processRow,
|
|
381
|
+
itemDataIterator=md.iterRows(imgFname, sortByLabel=md.MDL_ITEM_ID) )
|
|
382
|
+
|
|
383
|
+
self._defineOutputs(outputParticles=outputSet)
|
|
384
|
+
self._defineSourceRelation(self.inputParticles, outputSet)
|
|
385
|
+
|
|
386
|
+
cleanPath(self._getExtraPath('resizedParticles.xmd'))
|
|
387
|
+
cleanPath(self._getExtraPath('noisyParticles.xmd'))
|
|
388
|
+
cleanPath(self._getExtraPath('projections.xmd'))
|
|
389
|
+
if os.path.exists(self._getExtraPath('resizedProjections.xmd')):
|
|
390
|
+
cleanPath(self._getExtraPath('resizedProjections.xmd'))
|
|
391
|
+
if os.path.exists(self._getExtraPath('resizedEmptyParts.xmd')):
|
|
392
|
+
cleanPath(self._getExtraPath('resizedEmptyParts.xmd'))
|
|
393
|
+
# extra cleaning
|
|
394
|
+
if os.path.exists(self._getExtraPath('training_conf.json')):
|
|
395
|
+
cleanPath(self._getExtraPath('training_conf.json'))
|
|
396
|
+
if os.path.exists(self._getExtraPath('predict_conf.json')):
|
|
397
|
+
cleanPath(self._getExtraPath('predict_conf.json'))
|
|
398
|
+
if os.path.exists(self._getExtraPath('batchImages/')):
|
|
399
|
+
#cleanPath(self._getExtraPath('batchImages/*.png'))
|
|
400
|
+
cleanPath(self._getExtraPath('batchImages'))
|
|
401
|
+
|
|
402
|
+
def _processRow(self, particle, row):
|
|
403
|
+
particle.setLocation(xmippToLocation(row.getValue(emlib.MDL_IMAGE)))
|
|
404
|
+
if self.inputProjections.get() is not None:
|
|
405
|
+
mdToAdd= (md.MDL_IMAGE_ORIGINAL, md.MDL_IMAGE_REF, md.MDL_CORR_DENOISED_PROJECTION, md.MDL_CORR_DENOISED_NOISY)
|
|
406
|
+
else:
|
|
407
|
+
mdToAdd= (md.MDL_IMAGE_ORIGINAL, md.MDL_CORR_DENOISED_NOISY )
|
|
408
|
+
|
|
409
|
+
setXmippAttributes(particle, row, *mdToAdd)
|
|
410
|
+
|
|
411
|
+
# --------------------------- INFO functions --------------------------------------------
|
|
412
|
+
def _summary(self):
|
|
413
|
+
summary = []
|
|
414
|
+
summary.append("Particles denoised")
|
|
415
|
+
return summary
|
|
416
|
+
|
|
417
|
+
def _validate(self):
|
|
418
|
+
assertModel = (self.modelTrainPredMode.get()==ITER_PREDICT and
|
|
419
|
+
not self.customModelOverPretrain.get())
|
|
420
|
+
errors = self.validateDLtoolkit(assertModel=assertModel,
|
|
421
|
+
model=('deepDenoising', 'ModelTrained.h5'),
|
|
422
|
+
errorMsg="Required with 'Predict' mode when "
|
|
423
|
+
"no custom model is provided.")
|
|
424
|
+
|
|
425
|
+
return errors
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# # *************************************************
|
|
2
|
+
# # * This protocol will be offered in future releases (more testing is needed)
|
|
3
|
+
# # *************************************************
|
|
4
|
+
|
|
5
|
+
# # *****************************************************************************
|
|
6
|
+
# # *
|
|
7
|
+
# # * Authors: David Herreros Calero (dherreros@cnb.csic.es)
|
|
8
|
+
# # *
|
|
9
|
+
# # * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
|
|
10
|
+
# # *
|
|
11
|
+
# # * This program is free software; you can redistribute it and/or modify
|
|
12
|
+
# # * it under the terms of the GNU General Public License as published by
|
|
13
|
+
# # * the Free Software Foundation; either version 2 of the License, or
|
|
14
|
+
# # * (at your option) any later version.
|
|
15
|
+
# # *
|
|
16
|
+
# # * This program is distributed in the hope that it will be useful,
|
|
17
|
+
# # * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
18
|
+
# # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
19
|
+
# # * GNU General Public License for more details.
|
|
20
|
+
# # *
|
|
21
|
+
# # * You should have received a copy of the GNU General Public License
|
|
22
|
+
# # * along with this program; if not, write to the Free Software
|
|
23
|
+
# # * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
24
|
+
# # * 02111-1307 USA
|
|
25
|
+
# # *
|
|
26
|
+
# # * All comments concerning this program package may be sent to the
|
|
27
|
+
# # * e-mail address 'scipion@cnb.csic.es'
|
|
28
|
+
# # *
|
|
29
|
+
# # *****************************************************************************
|
|
30
|
+
#
|
|
31
|
+
# import os
|
|
32
|
+
# from sklearn.cluster import KMeans
|
|
33
|
+
# import numpy as np
|
|
34
|
+
#
|
|
35
|
+
# from pyworkflow.object import Integer
|
|
36
|
+
# import pyworkflow.protocol.params as param
|
|
37
|
+
# from pyworkflow import VERSION_2_0
|
|
38
|
+
# import pwem.emlib.metadata as md
|
|
39
|
+
# from pyworkflow.utils.properties import Message
|
|
40
|
+
# from pwem.protocols import ProtClassify2D, pwobj
|
|
41
|
+
#
|
|
42
|
+
# from xmipp3.convert import getXmippAttribute
|
|
43
|
+
#
|
|
44
|
+
#
|
|
45
|
+
# class XmippProtKmeansSPH(ProtClassify2D):
|
|
46
|
+
# """ Reduce the number of deformation coefficients based on k-means vectors """
|
|
47
|
+
#
|
|
48
|
+
# _label = 'kmeans clustering'
|
|
49
|
+
# _lastUpdateVersion = VERSION_2_0
|
|
50
|
+
#
|
|
51
|
+
# def __init__(self, **args):
|
|
52
|
+
# ProtClassify2D.__init__(self, **args)
|
|
53
|
+
# self.stepsExecutionMode = param.STEPS_PARALLEL
|
|
54
|
+
#
|
|
55
|
+
# # --------------------------- DEFINE param functions -----------------------
|
|
56
|
+
# def _defineParams(self, form):
|
|
57
|
+
# form.addSection(label=Message.LABEL_INPUT)
|
|
58
|
+
# form.addParam('inputParts', param.MultiPointerParam, pointerClass='SetOfParticles',
|
|
59
|
+
# label="Input particles",
|
|
60
|
+
# important=True)
|
|
61
|
+
# form.addParam('column', param.EnumParam, choices=['SPH', 'NMA'],
|
|
62
|
+
# label='Column to cluster', default=0,
|
|
63
|
+
# help='Selecto from the type of coefficients to be used for the '
|
|
64
|
+
# 'clustering.')
|
|
65
|
+
#
|
|
66
|
+
# # --------------------------- INSERT steps functions -----------------------
|
|
67
|
+
# def _insertAllSteps(self):
|
|
68
|
+
# self._insertFunctionStep('findClustersStep')
|
|
69
|
+
# self._insertFunctionStep('createOutputStep')
|
|
70
|
+
#
|
|
71
|
+
# def findClustersStep(self):
|
|
72
|
+
# self.kDict = []
|
|
73
|
+
# coeffs = []
|
|
74
|
+
# for inputParts in self.inputParts:
|
|
75
|
+
# particles = inputParts.get()
|
|
76
|
+
# colData = self.column.get()
|
|
77
|
+
# if colData == 0:
|
|
78
|
+
# mdLabel = md.MDL_SPH_COEFFICIENTS
|
|
79
|
+
# elif colData == 1:
|
|
80
|
+
# mdLabel = md.MDL_NMA
|
|
81
|
+
# for particle in particles.iterItems():
|
|
82
|
+
# coeffs.append(np.fromstring(getXmippAttribute(particle, mdLabel).get(), sep=','))
|
|
83
|
+
# maxClusters = 101 if len(coeffs) > 101 else len(coeffs) + 1
|
|
84
|
+
# rmse = np.zeros((maxClusters - 1))
|
|
85
|
+
# coeffs = np.asarray(coeffs)[:, :-8]
|
|
86
|
+
# for nClusters in range(1, maxClusters):
|
|
87
|
+
# kmeans = KMeans(n_clusters=nClusters).fit(coeffs)
|
|
88
|
+
# rmse[nClusters-1] = np.sqrt(kmeans.inertia_ / len(coeffs))
|
|
89
|
+
# p1 = np.array((1, rmse[0]))
|
|
90
|
+
# p2 = np.array((maxClusters - 1, rmse[-1]))
|
|
91
|
+
# d = np.zeros((maxClusters - 1))
|
|
92
|
+
# for nClusters in range(2, maxClusters - 1):
|
|
93
|
+
# p3 = np.array((nClusters, rmse[nClusters - 1]))
|
|
94
|
+
# d[nClusters-1] = np.linalg.norm(np.cross(p2 - p1, p1 - p3)) / np.linalg.norm(p2 - p1)
|
|
95
|
+
# nClusters = np.argmax(d) + 1
|
|
96
|
+
# self.kmeans = KMeans(n_clusters=nClusters).fit(np.asarray(coeffs))
|
|
97
|
+
#
|
|
98
|
+
# def createOutputStep(self):
|
|
99
|
+
# classes2DSet = self._createSetOfClasses2D(self.inputParts[0].get())
|
|
100
|
+
# classes2DSet.classifyItems(updateItemCallback=self._updateParticle,
|
|
101
|
+
# updateClassCallback=self._updateClass,
|
|
102
|
+
# itemDataIterator=iter(self.kmeans.labels_))
|
|
103
|
+
# result = {'outputClasses': classes2DSet}
|
|
104
|
+
# classes2DSet.L1 = Integer(self.inputParts[0].get().L1)
|
|
105
|
+
# classes2DSet.L2 = Integer(self.inputParts[0].get().L2)
|
|
106
|
+
# classes2DSet.Rmax = Integer(self.inputParts[0].get().Rmax)
|
|
107
|
+
# self._defineOutputs(**result)
|
|
108
|
+
# for inputParts in self.inputParts:
|
|
109
|
+
# self._defineSourceRelation(inputParts, classes2DSet)
|
|
110
|
+
#
|
|
111
|
+
# # ------------------------------- UTILS functions -------------------------------
|
|
112
|
+
# def _updateParticle(self, item, idc):
|
|
113
|
+
# item.setClassId(idc)
|
|
114
|
+
#
|
|
115
|
+
# def _updateClass(self, item):
|
|
116
|
+
# coeff = self.kmeans.cluster_centers_[item.getObjId()-1]
|
|
117
|
+
# coeff = ','.join(['%f' % num for num in coeff])
|
|
118
|
+
# representative = pwobj.CsvList()
|
|
119
|
+
# representative.set(coeff)
|
|
120
|
+
# # setattr(representative, '_classID', pwobj.Integer(item.getObjId()))
|
|
121
|
+
# # setattr(representative, '_objDoStore', True)
|
|
122
|
+
# item.setRepresentative(representative)
|