Xmipp  v3.23.11-Nereus
symmetrize.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar S. Sorzano (coss@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 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 
26 #include "symmetrize.h"
27 
28 #include <core/args.h>
29 #include <data/symmetries.h>
30 
31 /* Read parameters --------------------------------------------------------- */
33 {
35  fn_sym = getParam("--sym");
36  fn_sym2 = getParam("--sym2");
37  doMask = false;
38  if (checkParam("--mask_in"))
39  {
40  fn_Maskin = getParam("--mask_in");
41  doMask = true;
42  }
43  helical=(fn_sym=="helical");
44  dihedral=(fn_sym=="dihedral");
45  helicalDihedral=(fn_sym=="helicalDihedral");
46  if (helical || helicalDihedral)
47  {
48  Ts=getDoubleParam("--sampling");
49  zHelical=getDoubleParam("--helixParams",0)/Ts;
50  rotHelical=DEG2RAD(getDoubleParam("--helixParams",1));
51  rotPhaseHelical=DEG2RAD(getDoubleParam("--helixParams",2));
52 
53  Cn=std::stoi(fn_sym2.substr(1));
54  }
55  do_not_generate_subgroup = checkParam("--no_group");
56  wrap = !checkParam("--dont_wrap");
57  sum = checkParam("--sum");
58  heightFraction = getDoubleParam("--heightFraction");
59  splineOrder = getIntParam("--spline");
60 }
61 
62 /* Usage ------------------------------------------------------------------- */
64 {
65  addUsageLine("Symmetrize volumes and images ");
68  addParamsLine(" --sym <symmetry> : For 2D images: a number");
69  addParamsLine(" : For 3D volumes: a symmetry file or point-group description");
70  addParamsLine(" : Valid point-group descriptions are:");
71  addParamsLine(" : C1, Ci, Cs, Cn (from here on n must be an integer number with no more than 2 digits)");
72  addParamsLine(" : Cnv, Cnh, Sn, Dn, Dnv, Dnh, T, Td, Th, O, Oh");
73  addParamsLine(" : I, I1, I2, I3, I4, I5, Ih, helical, dihedral, helicalDihedral");
74  addParamsLine(" :+ For a full description of symmetries look at");
75  addParamsLine(" :+ http://xmipp.cnb.csic.es/twiki/bin/view/Xmipp/Symmetry");
76  addParamsLine(" [--sym2 <sym2=C1>] : Only for helical, or helicalDihedral");
77  addParamsLine(" : You may use any other Cn symmetry");
78  addParamsLine(" [--helixParams <z> <rot> <rotPhase=0>]: Helical parameters z(Angstroms), rot(degrees), rotPhase(degrees)");
79  addParamsLine(" :+ V(r,theta,z)=V(r,theta+rotHelix+rotPhase,z+zHelix)");
80  addParamsLine(" [--heightFraction <f=0.95>]: Height fraction used for symmetrizing a helix");
81  addParamsLine(" [--sampling <T=1>] : Sampling rate (A/pixel). Used only for helical parameters");
82  addParamsLine(" [--no_group] : For 3D volumes: do not generate symmetry subgroup");
83  addParamsLine(" [--dont_wrap] : by default, the image/volume is wrapped");
84  addParamsLine(" [--sum] : compute the sum of the images/volumes instead of the average. This is useful for symmetrizing pieces");
85  addParamsLine(" [--mask_in <fileName>]: symmetrize only in the masked area");
86  addParamsLine(" [--spline <order=3>] : Spline order for the interpolation (valid values are 1 and 3)");
87  addExampleLine("Symmetrize a list of images with 6 fold symmetry",false);
88  addExampleLine(" xmipp_transform_symmetrize -i input.sel --sym 6");
89  addExampleLine("Symmetrize with i3 symmetry and the volume is not wrapped",false);
90  addExampleLine(" xmipp_transform_symmetrize -i input.vol --sym i3 --dont_wrap");
91 }
92 
93 /* Show ------------------------------------------------------------------- */
95 {
96  if (verbose==0)
97  return;
99  std::cout
100  << "Symmetry: " << fn_sym << std::endl
101  << "No group: " << do_not_generate_subgroup << std::endl
102  << "Wrap: " << wrap << std::endl
103  << "Sum: " << sum << std::endl
104  << "Spline: " << splineOrder << std::endl;
105  if (doMask)
106  std::cout << "mask_in " << fn_Maskin << std::endl;
107  if (helical)
108  std::cout << "RotHelical: " << RAD2DEG(rotHelical) << std::endl
109  << "RotPhaseHelical: " << RAD2DEG(rotPhaseHelical) << std::endl
110  << "ZHelical: " << zHelical*Ts
111  << "Height fraction: " << heightFraction << std::endl;
112  if (helical || helicalDihedral)
113  std::cout << "Symmetry2: " << fn_sym2 << std::endl;
114 }
115 
116 /* Symmetrize ------------------------------------------------------- */
118  MultidimArray<double> &V_out, int spline,
119  bool wrap, bool do_outside_avg, bool sum, bool helical, bool dihedral, bool helicalDihedral,
120  double rotHelical, double rotPhaseHelical, double zHelical, double heightFraction,
121  const MultidimArray<double> * mask, int Cn)
122 {
123  Matrix2D<double> L(4, 4), R(4, 4); // A matrix from the list
124  MultidimArray<double> V_aux;
125  Matrix1D<double> sh(3);
126  double avg = 0.;
127 
128  if (do_outside_avg)
129  {
130  MultidimArray<int> mask1;
131  mask1.resizeNoCopy(V_in);
132  mask1.setXmippOrigin();
133  size_t rad = XMIPP_MIN(XSIZE(V_in), YSIZE(V_in));
134  rad = XMIPP_MIN(rad, ZSIZE(V_in));
135  BinaryCircularMask(mask1, rad / 2, OUTSIDE_MASK);
136  double dum;
137  computeStats_within_binary_mask(mask1, V_in, dum, dum, avg, dum);
138  }
139  V_out = V_in;
140 
141  if (!helical && !dihedral && !helicalDihedral)
142  {
143  MultidimArray<double> Bcoeffs;
144  MultidimArray<double> *BcoeffsPtr=nullptr;
145  if (spline==3)
146  {
148  BcoeffsPtr=&Bcoeffs;
149  }
150  for (int i = 0; i < SL.symsNo(); i++)
151  {
152  SL.getMatrices(i, L, R);
153  /*FIXME: I do not think this make sense since V_aux is empty. ROB
154  SL.getShift(i, sh);
155  R(3, 0) = sh(0) * XSIZE(V_aux);
156  R(3, 1) = sh(1) * YSIZE(V_aux);
157  R(3, 2) = sh(2) * ZSIZE(V_aux);
158  */
159  applyGeometry(spline, V_aux, V_in, R.transpose(), xmipp_transformation::IS_NOT_INV, wrap, avg, BcoeffsPtr);
160 
161  if ( mask==nullptr)
162  arrayByArray(V_out, V_aux, V_out, '+');
163  else // op1, op2 , result
164  selfArrayByArrayMask(V_in, V_aux, V_out, '+', mask);
165  }
166 
167  if (!sum)
168  arrayByScalar(V_out, 1.0/(SL.symsNo() + 1.0f), V_out, '*');
169  }
170  else if (helical)
171  symmetry_Helical(V_out,V_in,zHelical,rotHelical,rotPhaseHelical,nullptr,false,heightFraction,Cn);
172  else if (helicalDihedral)
173  {
174  symmetry_Helical(V_out,V_in,zHelical,rotHelical,rotPhaseHelical,nullptr,true,heightFraction,Cn);
175  MultidimArray<double> Vrotated;
176  rotate(spline,Vrotated,V_out,180.0,'X',xmipp_transformation::WRAP);
177  V_out+=Vrotated;
178  V_out*=0.5;
179  }
180  else if (dihedral)
181  {
182  auto zmax=(int)(0.1*ZSIZE(V_in));
183  symmetry_Dihedral(V_out,V_in,1,-zmax,zmax,0.5);
184  }
185 }
186 
188  MultidimArray<double> &I_out, int spline,
189  bool wrap, bool do_outside_avg, bool sum,
190  const MultidimArray<double> * mask)
191 {
192  double avg = 0.;
193  if (do_outside_avg)
194  {
195  MultidimArray<int> mask1;
196  mask1.resizeNoCopy(I_in);
197  mask1.setXmippOrigin();
198  int rad = XMIPP_MIN(XSIZE(I_in), YSIZE(I_in));
199  BinaryCircularMask(mask1, rad / 2, OUTSIDE_MASK);
200  double dum;
201  computeStats_within_binary_mask(mask1, I_in, dum, dum, avg, dum);
202  }
203  I_out = I_in;
204  MultidimArray<double> rotatedImg;
205  if (mask!=nullptr)
206  REPORT_ERROR(ERR_NOT_IMPLEMENTED,"mask symmetrization not implemented for images");
207  for (int i = 1; i < symorder; i++)
208  {
209  rotate(spline, rotatedImg, I_in, 360.0 / symorder * i,'Z',wrap,avg);
210  I_out += rotatedImg;
211  }
212  if (!sum)
213  I_out *= 1.0/symorder;
214 }
215 
216 /* Preprocess ------------------------------------------------------------- */
218 {
219  if (!helical && !dihedral & !helicalDihedral)
220  {
221  if (!fn_sym.exists() && isdigit(fn_sym[0]))
223  else
224  {
225  double accuracy = do_not_generate_subgroup ? -1 : 1e-6;
226  SL.readSymmetryFile(fn_sym, accuracy);
227  symorder=-1;
228  }
229  }
230 }
231 
232 /* Process image ------------------------------------------------------------- */
233 void ProgSymmetrize::processImage(const FileName &fnImg, const FileName &fnImgOut, const MDRow &rowIn, MDRow &rowOut)
234 {
235  Image<double> Iin;
236  Image<double> Iout;
237  Image<double> mask;
238  MultidimArray<double> *mmask=nullptr;
239 
240  Iin.readApplyGeo(fnImg, rowIn);
241  Iin().setXmippOrigin();
242  Iout().resize(Iin());
243 
244  if (doMask)
245  {
246  mask.read(fn_Maskin);
247  mmask=&(mask());
248  }
249 
250  if (ZSIZE(Iin())==1)
251  {
252  if (helical)
253  REPORT_ERROR(ERR_ARG_INCORRECT,"Helical symmetrization is not meant for images");
254  if (symorder!=-1)
255  symmetrizeImage(symorder,Iin(),Iout(),splineOrder,wrap,!wrap,sum,mmask);
256  else
257  REPORT_ERROR(ERR_ARG_MISSING,"The symmetry order is not valid for images");
258  }
259  else
260  {
261  if (SL.symsNo()>0 || helical || dihedral || helicalDihedral)
262  {
263  symmetrizeVolume(SL,Iin(),Iout(),splineOrder,wrap,!wrap,
265  }
266  else
267  REPORT_ERROR(ERR_ARG_MISSING,"The symmetry description is not valid for volumes");
268  }
269  Iout.write(fnImgOut);
270 }
SymList SL
Definition: symmetrize.h:87
Argument missing.
Definition: xmipp_error.h:114
#define YSIZE(v)
Case or algorithm not implemented yet.
Definition: xmipp_error.h:177
double getDoubleParam(const char *param, int arg=0)
void getMatrices(int i, Matrix2D< double > &L, Matrix2D< double > &R, bool homogeneous=true) const
Definition: symmetries.cpp:348
bool wrap
wrap or don&#39;t wrap input file during symmetrisation
Definition: symmetrize.h:63
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
double Ts
Sampling rate (used for helical)
Definition: symmetrize.h:59
#define DEG2RAD(d)
Definition: xmipp_macros.h:312
void resizeNoCopy(const MultidimArray< T1 > &v)
void symmetrizeVolume(const SymList &SL, const MultidimArray< double > &V_in, MultidimArray< double > &V_out, int spline, bool wrap, bool do_outside_avg, bool sum, bool helical, bool dihedral, bool helicalDihedral, double rotHelical, double rotPhaseHelical, double zHelical, double heightFraction, const MultidimArray< double > *mask, int Cn)
Definition: symmetrize.cpp:117
double zHelical
Helical shift.
Definition: symmetrize.h:55
double rotHelical
Helical rotation.
Definition: symmetrize.h:51
void BinaryCircularMask(MultidimArray< int > &mask, double radius, int mode, double x0, double y0, double z0)
Definition: mask.cpp:193
int splineOrder
Spline order.
Definition: symmetrize.h:67
int readSymmetryFile(FileName fn_sym, double accuracy=SYM_ACCURACY)
Definition: symmetries.cpp:33
void applyGeometry(int SplineDegree, MultidimArray< std::complex< double > > &V2, const MultidimArray< std::complex< double > > &V1, const Matrix2D< double > &A, bool inv, bool wrap, std::complex< double > outside, MultidimArray< double > *BcoeffsPtr)
double rotPhaseHelical
Helical phase.
Definition: symmetrize.h:53
void write(const FileName &name="", size_t select_img=ALL_IMAGES, bool isStack=false, int mode=WRITE_OVERWRITE, CastWriteMode castMode=CW_CAST, int _swapWrite=0)
void symmetry_Dihedral(MultidimArray< double > &Vout, const MultidimArray< double > &Vin, double rotStep, double zmin, double zmax, double zStep, MultidimArray< int > *mask)
Matrix2D< T > transpose() const
Definition: matrix2d.cpp:1314
int symsNo() const
Definition: symmetries.h:268
int readApplyGeo(const FileName &name, const MDRow &row, const ApplyGeoParams &params=DefaultApplyGeoParams)
#define i
#define rotate(a, i, j, k, l)
void computeStats_within_binary_mask(const MultidimArray< T1 > &mask, const MultidimArray< T > &m, double &min_val, double &max_val, double &avg, double &stddev)
Definition: mask.h:799
bool helicalDihedral
Definition: symmetrize.h:95
FileName fn_sym2
Definition: symmetrize.h:43
void symmetrizeImage(int symorder, const MultidimArray< double > &I_in, MultidimArray< double > &I_out, int spline, bool wrap, bool do_outside_avg, bool sum, const MultidimArray< double > *mask)
Definition: symmetrize.cpp:187
const char * getParam(const char *param, int arg=0)
Incorrect argument received.
Definition: xmipp_error.h:113
void produceSplineCoefficients(int SplineDegree, MultidimArray< double > &coeffs, const MultidimArray< T > &V1)
#define XSIZE(v)
void symmetry_Helical(MultidimArray< double > &Vout, const MultidimArray< double > &Vin, double zHelical, double rotHelical, double rot0, MultidimArray< int > *mask, bool dihedral, double heightFraction, int Cn)
bool sum
Sum or average the result.
Definition: symmetrize.h:65
double heightFraction
Helical height fraction.
Definition: symmetrize.h:57
#define ZSIZE(v)
void addExampleLine(const char *example, bool verbatim=true)
int verbose
Verbosity level.
FileName fn_sym
symmetry file
Definition: symmetrize.h:43
bool exists() const
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
void processImage(const FileName &fnImg, const FileName &fnImgOut, const MDRow &rowIn, MDRow &rowOut)
Process image or volume.
Definition: symmetrize.cpp:233
void defineParams()
Definition: symmetrize.cpp:63
void show() const override
int Cn
Cn for helical or helicalDihedral.
Definition: symmetrize.h:69
#define RAD2DEG(r)
Definition: xmipp_macros.h:320
int textToInteger(const char *str)
bool checkParam(const char *param)
constexpr int OUTSIDE_MASK
Definition: mask.h:48
bool do_not_generate_subgroup
Do not generate subgroup.
Definition: symmetrize.h:61
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
bool each_image_produces_an_output
Indicate that an output is produced for each image in the input.
void addUsageLine(const char *line, bool verbatim=false)
FileName fn_Maskin
mask file (mask what is inside)
Definition: symmetrize.h:45
int getIntParam(const char *param, int arg=0)
bool doMask
set to true is we should mask
Definition: symmetrize.h:49
void readParams()
Definition: symmetrize.cpp:32
void addParamsLine(const String &line)