Xmipp  v3.23.11-Nereus
normalize.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 <algorithm>
27 #include "normalize.h"
28 #include "core/transformations.h"
30 #include "filters.h"
31 
32 /* Normalizations ---------------------------------------------------------- */
34 {
35  double mean;
36  double std;
37  I.computeAvgStdev(mean,std);
38  double istd=1.0/std;
40  DIRECT_MULTIDIM_ELEM(I,n)=(DIRECT_MULTIDIM_ELEM(I,n)-mean)*istd;
41 }
42 
44 {
45  double avg=0.;
46  double stddev;
47  double min;
48  double max;
49  double avgbg;
50  double stddevbg;
51  double minbg;
52  double maxbg;
53  I.computeStats(avg, stddev, min, max);
54  computeStats_within_binary_mask(bg_mask, I, minbg, maxbg, avgbg,
55  stddevbg);
56  I -= avg;
57  I /= stddevbg;
58 }
59 
61  const MultidimArray<double> *mask)
62 {
63  double avgbg;
64  double stddevbg;
65  double minbg;
66  double maxbg;
67  computeStats_within_binary_mask(bg_mask, I, minbg, maxbg, avgbg,
68  stddevbg);
69  I -= avgbg;
70  I /= stddevbg;
71  if (mask != nullptr)
72  I *= *mask;
74 }
75 
76 //#define DEBUG
77 void normalize_tomography(MultidimArray<double> &I, double tilt, double &mui,
78  double &sigmai, bool tiltMask, bool tomography0,
79  double mu0, double sigma0)
80 {
81  // Tilt series are always 2D
82  I.checkDimension(2);
83 
84  const int L=2;
85 
86  // Build a mask using the tilt angle
87  I.setXmippOrigin();
88  MultidimArray<int> mask;
89  mask.initZeros(I);
90  int Xdimtilt=(int)XMIPP_MIN(FLOOR(0.5*(XSIZE(I)*cos(DEG2RAD(tilt)))),
91  0.5*(XSIZE(I)-(2*L+1)));
92  int N=0;
93  for (int i=STARTINGY(I); i<=FINISHINGY(I); i++)
94  for (int j=-Xdimtilt; j<=Xdimtilt;j++)
95  {
96  A2D_ELEM(mask,i,j)=1;
97  N++;
98  }
99 
100  // Estimate the local variance
101  MultidimArray<double> localVariance;
102  localVariance.initZeros(I);
103  double meanVariance=0;
105  {
106  // Center a mask of size 5x5 and estimate the variance within the mask
107  double meanPiece=0;
108  double variancePiece=0;
109  double Npiece=0;
110  for (int ii=i-L; ii<=i+L; ii++)
111  {
112  if (INSIDEY(I,ii))
113  for (int jj=j-L; jj<=j+L; jj++)
114  {
115  if (INSIDEX(I,jj))
116  {
117  double pixval=A2D_ELEM(I,ii,jj);
118  meanPiece+=pixval;
119  variancePiece+=pixval*pixval;
120  ++Npiece;
121  }
122  }
123  }
124  meanPiece/=Npiece;
125  variancePiece=variancePiece/(Npiece-1)-
126  Npiece/(Npiece-1)*meanPiece*meanPiece;
127  A2D_ELEM(localVariance,i,j)=variancePiece;
128  meanVariance+=variancePiece;
129  }
130  if (0 == N) {
131  REPORT_ERROR(ERR_NUMERICAL, "N is zero (0), which would lead to division by zero");
132  }
133  meanVariance*=1.0/N;
134 
135  // Test the hypothesis that the variance in this piece is
136  // the same as the variance in the whole image
137  double iFu=1/icdf_FSnedecor(4*L*L+4*L,N-1,0.975);
138  double iFl=1/icdf_FSnedecor(4*L*L+4*L,N-1,0.025);
139  double iMeanVariance=1.0/meanVariance;
140  FOR_ALL_ELEMENTS_IN_ARRAY2D(localVariance)
141  {
142  if (A2D_ELEM(localVariance,i,j)==0)
143  A2D_ELEM(mask,i,j)=-2;
144  if (A2D_ELEM(mask,i,j)==1)
145  {
146  double ratio=A2D_ELEM(localVariance,i,j)*iMeanVariance;
147  double thl=ratio*iFu;
148  double thu=ratio*iFl;
149  if (thl>1 || thu<1)
150  A2D_ELEM(mask,i,j)=-1;
151  }
152  }
153 #ifdef DEBUG
154  Image<double> save;
155  save()=I;
156  save.write("PPP.xmp");
157  save()=localVariance;
158  save.write("PPPLocalVariance.xmp");
159  Image<int> savemask;
160  savemask()=mask;
161  savemask.write("PPPmask.xmp");
162 #endif
163 
164  // Compute the statistics again in the reduced mask
165  double avg;
166  double stddev;
167  double min;
168  double max;
169  computeStats_within_binary_mask(mask, I, min, max, avg, stddev);
170  double cosTilt=cos(DEG2RAD(tilt));
171  double iCosTilt=1.0/cosTilt;
172  if (tomography0)
173  {
174  double iadjustedStddev=1.0/(sigma0*cosTilt);
176  switch (A2D_ELEM(mask,i,j))
177  {
178  case -2:
179  A2D_ELEM(I,i,j)=0;
180  break;
181  case 0:
182  if (tiltMask)
183  A2D_ELEM(I,i,j)=0;
184  else
185  A2D_ELEM(I,i,j)=(A2D_ELEM(I,i,j)*iCosTilt-mu0)*iadjustedStddev;
186  break;
187  case -1:
188  case 1:
189  A2D_ELEM(I,i,j)=(A2D_ELEM(I,i,j)*iCosTilt-mu0)*iadjustedStddev;
190  break;
191  }
192  }
193  else
194  {
195  double adjustedStddev=stddev*cosTilt;
196  double iAdjustedStddev=1.0/adjustedStddev;
198  switch (A2D_ELEM(mask,i,j))
199  {
200  case -2:
201  A2D_ELEM(I,i,j)=0;
202  break;
203  case 0:
204  if (tiltMask)
205  A2D_ELEM(I,i,j)=0;
206  else
207  A2D_ELEM(I,i,j)=(A2D_ELEM(I,i,j)-avg)*iAdjustedStddev;
208  break;
209  case -1:
210  case 1:
211  A2D_ELEM(I,i,j)=(A2D_ELEM(I,i,j)-avg)*iAdjustedStddev;
212  break;
213  }
214  }
215 
216  // Prepare values for returning
217  mui=avg;
218  sigmai=sqrt(meanVariance);
219 #ifdef DEBUG
220 
221  save()=I;
222  save.write("PPPafter.xmp");
223  std::cout << "Press any key\n";
224  char c;
225  std::cin >> c;
226 #endif
227 }
228 #undef DEBUG
229 
231 {
232  double avg;
233  double stddev;
234  double min=0.;
235  double max;
236  double avgbg;
237  double stddevbg;
238  double minbg;
239  double maxbg;
240  I.computeStats(avg, stddev, min, max);
241  computeStats_within_binary_mask(bg_mask, I, minbg, maxbg, avgbg,
242  stddevbg);
243  if (avgbg > 0)
244  {
245  I -= avgbg;
246  I /= avgbg;
247  }
248  else
249  { // To avoid the contrast inversion
250  I -= (avgbg - min);
251  I /= (avgbg - min);
252  }
253 }
254 
256 {
257  double avgbg;
258  double stddevbg;
259  I.computeAvgStdev_within_binary_mask(bg_mask, avgbg, stddevbg);
260  double istddevbg=1.0/stddevbg;
262  DIRECT_MULTIDIM_ELEM(I,n)=(DIRECT_MULTIDIM_ELEM(I,n)-avgbg)*istddevbg;
263 }
264 
265 void normalize_Robust(MultidimArray<double> &I, const MultidimArray<int> &bg_mask, bool clip)
266 {
267  std::vector<double> voxel_vector;
269 
270  if (bg_mask.computeMax() == 0)
271  {
272  Image<double> mask;
273  mask() = I;
274  static_cast<void>(EntropySegmentation(mask()));
276  {
277  if (DIRECT_MULTIDIM_ELEM(mask(), n) == 0)
278  DIRECT_MULTIDIM_ELEM(bg_mask,n) = 1;
279  }
280  }
281 
283  {
284  if (DIRECT_MULTIDIM_ELEM(bg_mask, n) == 0)
285  voxel_vector.push_back(DIRECT_MULTIDIM_ELEM(I,n));
286  }
287 
288  std::sort(voxel_vector.begin(), voxel_vector.end());
289 
290  double medianBg;
291  double p99;
292  double ip99;
293  int idx;
294  I.computeMedian_within_binary_mask(bg_mask, medianBg);
295  idx = (int)(voxel_vector.size() * 0.99);
296  p99 = voxel_vector[idx];
297  ip99 = 1 / p99;
299  DIRECT_MULTIDIM_ELEM(I,n)=(DIRECT_MULTIDIM_ELEM(I,n) - medianBg) * ip99;
300 
301  if (clip)
302  {
304  if (DIRECT_MULTIDIM_ELEM(I,n) > 1.3284)
305  {
306  DIRECT_MULTIDIM_ELEM(I,n) = 1.3284;
307  }
308  else if (DIRECT_MULTIDIM_ELEM(I,n) < -1.3284)
309  {
310  DIRECT_MULTIDIM_ELEM(I,n) = -1.3284;
311  }
312  }
313 }
314 
316 {
317  double avg=0;
318  double stddev;
319  double min;
320  double max;
321  double avgbg=0;
322  double stddevbg;
323  double minbg;
324  double maxbg;
325  I.computeStats(avg, stddev, min, max);
326  computeStats_within_binary_mask(bg_mask, I, minbg, maxbg, avgbg,
327  stddevbg);
328  double K=1.0/fabs(avg - avgbg);
331 }
332 
334 {
335  int Npoints=0; // # points in mask.
336  double pA;
337  double pB;
338  double pC; // Least squares coefficients.
339 
340  // Only 2D ramps implemented
341  I.checkDimension(2);
342 
343  // Check if mask is NULL.
344  if (bg_mask == nullptr)
345  {
346  Npoints = I.xdim*I.ydim;
347  }
348  // Check if mask is not full of 0's.
349  else
350  {
351  Npoints=(int)bg_mask->sum();
352  }
353 
354  // Fit a least squares plane through the background pixels
355  I.setXmippOrigin();
356  if (bg_mask == nullptr)
357  {
358  least_squares_plane_fit_All_Points(I, pA, pB, pC);
359  }
360  else
361  {
362  int idx=0;
363  bg_mask->setXmippOrigin();
364  auto *allpoints=new FitPoint[Npoints];
365 
367  {
368  if (A2D_ELEM( *bg_mask, i, j))
369  {
370  FitPoint &p=allpoints[idx++];
371  p.x = j;
372  p.y = i;
373  p.z = A2D_ELEM(I, i, j);
374  p.w = 1.;
375  }
376  }
377 
378  least_squares_plane_fit(allpoints, Npoints, pA, pB, pC);
379  delete [] allpoints;
380  }
381 
382  // Subtract the plane from the image and compute stddev within mask
383  double sum1 = 0;
384  double sum2 = 0;
385  if (bg_mask == nullptr)
386  {
387  double *ref;
388  for (int i=STARTINGY(I); i<=FINISHINGY(I); i++)
389  {
390  double aux=pB * i + pC;
391  ref = &A2D_ELEM(I, i, STARTINGX(I));
392  for (int j=STARTINGX(I); j<=FINISHINGX(I); j++)
393  {
394  (*ref) -= pA * j + aux;
395  sum1 += (*ref);
396  sum2 += (*ref)*(*ref);
397  ref++;
398  }
399  }
400  }
401  else
402  {
403  for (int i=STARTINGY(I); i<=FINISHINGY(I); i++)
404  {
405  double aux=pB * i + pC;
406  for (int j=STARTINGX(I); j<=FINISHINGX(I); j++)
407  {
408  A2D_ELEM(I, i, j) -= pA * j + aux;
409  if (A2D_ELEM( *bg_mask, i, j))
410  {
411  double aux=A2D_ELEM(I,i,j);
412  sum1 += aux;
413  sum2 += aux*aux;
414  }
415  }
416  }
417  }
418 
419  double avgbg = sum1 / Npoints;
420  double stddevbg = sqrt(fabs(sum2 / Npoints - avgbg * avgbg) * Npoints / (Npoints - 1));
421  if (stddevbg>1e-6)
422  {
423  I *= 1.0/stddevbg;
424  }
425 }
426 
428  const MultidimArray<int> &bg_mask,
429  const double &threshold)
430 {
431  double pA;
432  double pB;
433  double pC;
434  double avgbg;
435  double stddevbg;
436  double minbg;
437  double maxbg;
438  double aux;
439  double newstddev;
440  double sum1 = 0.;
441  double sum2 = 0;
442  int N = 0;
443 
444  // Only implemented for 2D arrays
445  I.checkDimension(2);
446 
447  // Fit a least squares plane through the background pixels
448  auto Npoints=(int)bg_mask.sum();
449  auto *allpoints=new FitPoint[Npoints];
450  I.setXmippOrigin();
451 
452  // Get initial statistics
453  computeStats_within_binary_mask(bg_mask, I, minbg, maxbg, avgbg,stddevbg);
454 
455  // Fit plane through those pixels within +/- threshold*sigma
456  int idx=0;
458  {
459  if (A2D_ELEM(bg_mask, i, j))
460  {
461  if ( fabs(avgbg - A2D_ELEM(I, i, j)) < threshold * stddevbg)
462  {
463  FitPoint &p=allpoints[idx++];
464  p.x = j;
465  p.y = i;
466  p.z = A2D_ELEM(I, i, j);
467  p.w = 1.;
468  }
469  }
470  }
471  least_squares_plane_fit(allpoints, Npoints, pA, pB, pC);
472  delete []allpoints;
473 
474  // Subtract the plane from the image
476  {
477  A2D_ELEM(I, i, j) -= pA * j + pB * i + pC;
478  }
479 
480  // Get std.dev. of the background pixels within +/- threshold*sigma
482  {
483  if (A2D_ELEM(bg_mask, i, j))
484  {
485  if ( ABS(A2D_ELEM(I, i, j)) < threshold * stddevbg)
486  {
487  N++;
488  sum1 += (double) A2D_ELEM(I, i, j);
489  sum2 += ((double) A2D_ELEM(I, i, j)) *
490  ((double) A2D_ELEM(I, i, j));
491  }
492  }
493  }
494  // average and standard deviation
495  if (0 == N) {
496  REPORT_ERROR(ERR_NUMERICAL, "N is zero (0), which would lead to division by zero");
497  }
498  aux = sum1 / (double) N;
499  newstddev = sqrt(fabs(sum2 / N - aux*aux) * N / (N - 1));
500 
501  // Replace pixels outside +/- threshold*sigma by samples from
502  // a gaussian with avg-plane and newstddev
504  {
505  if (A2D_ELEM(bg_mask, i, j))
506  {
507  if ( fabs(A2D_ELEM(I, i, j)) > threshold * stddevbg)
508  {
509  // get local average
510  aux = pA * j + pB * i + pC;
511  A2D_ELEM(I, i, j)=rnd_gaus(aux, newstddev );
512  }
513  }
514  }
515 
516  // Divide the entire image by the new background
517  I /= newstddev;
518 }
519 
521 {
523  allow_apply_geo = true;
524  save_metadata_stack = true;
525  keep_input_columns = true;
526  addUsageLine("Change the range of intensity values of pixels.");
527  addUsageLine("In general, most of the methods requires a background to separate "
528  "particles from noise");
529  addKeywords("mask,normalization,normalize");
531  addParamsLine(" [--method <mth=NewXmipp>] : Normalizing method.");
532  addParamsLine(" where <mth>");
533  addParamsLine(" OldXmipp : I=(I-m(I))/stddev(I)");
534  addParamsLine(" : Avg(I)=0, Stddev(I)=1, does not need background");
535  addParamsLine(" Near_OldXmipp : I=(I-m(I))/stddev(bg)");
536  addParamsLine(" NewXmipp : I=(I-m(bg))/stddev(bg)");
537  addParamsLine(" : Avg(bg)=0, Stddev(I)=1");
538  addParamsLine(" : Positivity constraints can be added in reconstruction");
539  addParamsLine(" Tomography : I=(I-mean(I))/(stddev(I)*cos(tilt))");
540  addParamsLine(" : does not need background, it assumes the tilt series is vertically aligned");
541  addParamsLine(" : Similar to OldXmipp but with an extra division by the cos(tilt)");
542  addParamsLine(" Tomography0 : I=(I-mean(I(0 degrees)))/(stddev(I)*cos(tilt))");
543  addParamsLine(" : does not need background");
544  addParamsLine(" : Similar to Tomography but the average at 0 degrees is used for all images");
545  addParamsLine(" NewXmipp2 : I=(I-m(bg))/(m(I)-m(bg))");
546  addParamsLine(" Robust : I=(I-m(bg))/P95(I)");
547  addParamsLine(" Michael : I=(I-m(bg))/stddev(bg)");
548  addParamsLine(" None : Used for removing only dust");
549  addParamsLine(" Random : I=aI+b");
550  addParamsLine(" Ramp : Subtract ramp and then NewXmipp");
551  addParamsLine(" Neighbour : Replace pixels in the background with random noise");
552  addParamsLine(" [--invert] : Invert contrast.");
553  addParamsLine(" [--thr_black_dust <sblack=-3.5>] : Remove black dust particles with sigma threshold sblack.");
554  addParamsLine(" [--thr_white_dust <swhite=3.5>] : Remove white dust particles with sigma threshold swhite.");
555  addParamsLine(" [--thr_neigh <value=1.2>] : Sigma threshold for neighbour removal.");
556  addParamsLine(" [--prm <a0> <aF> <b0> <bF>] : Requires --method Random. I=aI+b.");
557  addParamsLine(" [--clip] : Requires --method Robust. Constrain maximum values in normalize volume.");
558  // addParamsLine(" requires -method Random;");
559  addParamsLine(" [--tiltMask] : Apply a mask depending on the tilt");
560  addParamsLine(" : requires --method Tomography or Tomography0");
561  addParamsLine(" [--background <mode>] ");
562  addParamsLine(" where <mode>");
563  addParamsLine(" frame <r> : Rectangular background of r pixels.");
564  addParamsLine(" circle <r> : Circular background outside radius r.");
565  mask_prm.defineParams(this,INT_MASK, "or", "Use an alternative type of background mask.");
566  addExampleLine("Normalize using OldXmipp method",false);
567  addExampleLine("xmipp_transform_normalize -i images.sel --method OldXmipp",true);
568  addExampleLine("Normalize 64x64 images using NewXmipp method",false);
569  addExampleLine("xmipp_transform_normalize -i images.sel --method NewXmipp --background circle 29",true);
570  addExampleLine("Normalize 64x64 images using NewXmipp method and a crown mask",false);
571  addExampleLine("xmipp_transform_normalize -i images.sel --method NewXmipp --mask crown 29 32",true);
572  addExampleLine("Normalize a volume to have zero mean and unit variance",false);
573  addExampleLine("xmipp_transform_normalize -i volume.vol --method OldXmipp",true);
574  addExampleLine("Normalize a volume so that the noise outside a sphere of radius 29 has zero mean and unit variance",false);
575  addExampleLine("xmipp_transform_normalize -i volume.vol --background circle 29",true);
576 }
577 
579 {
581 
582  // Get normalizing method
583  std::string aux;
584  aux = getParam("--method");
585 
586  if (aux == "OldXmipp")
587  method = OLDXMIPP;
588  else if (aux == "Near_OldXmipp")
590  else if (aux == "NewXmipp")
591  method = NEWXMIPP;
592  else if (aux == "NewXmipp2")
593  method = NEWXMIPP2;
594  else if (aux == "Robust")
595  method = ROBUST;
596  else if (aux == "Michael")
597  method = MICHAEL;
598  else if (aux == "Random")
599  method = RANDOM;
600  else if (aux == "None")
601  method = NONE;
602  else if (aux == "Ramp")
603  method = RAMP;
604  else if (aux == "Neighbour")
605  method = NEIGHBOUR;
606  else if (aux == "Tomography")
607  method = TOMOGRAPHY;
608  else if (aux == "Tomography0")
610  else
611  REPORT_ERROR(ERR_VALUE_INCORRECT, "Normalize: Unknown normalizing method");
612 
613  // Invert contrast?
614  invert_contrast = checkParam("--invert");
615 
616  // Constrain values?
617  clip = checkParam("--clip");
618 
619  // Apply a mask depending on the tilt
620  tiltMask = checkParam("--tiltMask");
621 
622  // Remove dust particles?
623  remove_black_dust = checkParam("--thr_black_dust");
624  remove_white_dust = checkParam("--thr_white_dust");
625  thresh_black_dust = getDoubleParam("--thr_black_dust");
626  thresh_white_dust = getDoubleParam("--thr_white_dust");
627  thresh_neigh = getDoubleParam("--thr_neigh");
628 
629  // Get background mask
631  if (method == NEWXMIPP || method == NEWXMIPP2 || method == MICHAEL ||
633  {
634  enable_mask = checkParam("--mask");
635  if (enable_mask)
636  {
638  mask_prm.readParams(this);
639  }
640  else
641  {
642  if (!checkParam("--background"))
644  "Normalize: --background or --mask parameter required.");
645 
646  aux = getParam("--background",0);
647  r = getIntParam("--background",1);
648 
649  if (aux == "frame")
651  else if (aux == "circle")
653  else
654  REPORT_ERROR(ERR_VALUE_INCORRECT, "Normalize: Unknown background mode");
655  }
656  }
657 
658  if (method == ROBUST)
659  {
660  enable_mask = checkParam("--mask");
661  if (enable_mask)
662  {
664  mask_prm.readParams(this);
665  }
666  }
667 
668  if (method == RANDOM)
669  {
670  if (!checkParam("--prm"))
672  "Normalize_parameters: -prm parameter required.");
673 
674  a0 = getDoubleParam("--prm", 0);
675  aF = getDoubleParam("--prm", 1);
676  b0 = getDoubleParam("--prm", 2);
677  bF = getDoubleParam("--prm", 3);
678  }
679 }
680 
682 {
684 
685  std::cout << "Normalizing method: ";
686  switch (method)
687  {
688  case OLDXMIPP:
689  std::cout << "OldXmipp\n";
690  break;
691  case NEAR_OLDXMIPP:
692  std::cout << "Near_OldXmipp\n";
693  break;
694  case NEWXMIPP:
695  std::cout << "NewXmipp\n";
696  break;
697  case NEWXMIPP2:
698  std::cout << "NewXmipp2\n";
699  break;
700  case ROBUST:
701  std::cout << "Robust\n";
702  break;
703  case MICHAEL:
704  std::cout << "Michael\n";
705  break;
706  case NONE:
707  std::cout << "None\n";
708  break;
709  case RAMP:
710  std::cout << "Ramp\n";
711  break;
712  case NEIGHBOUR:
713  std::cout << "Neighbour\n";
714  break;
715  case TOMOGRAPHY:
716  std::cout << "Tomography\n";
717  break;
718  case TOMOGRAPHY0:
719  std::cout << "Tomography0\n";
720  break;
721  case RANDOM:
722  std::cout << "Random a=[" << a0 << "," << aF << "], " << "b=[" <<
723  b0 << "," << bF << "]\n";
724  break;
725  }
726 
727  if (method == NEWXMIPP || method == NEWXMIPP2 ||
728  method == NEAR_OLDXMIPP || method == MICHAEL ||
729  method == RAMP || method == NEIGHBOUR || method == ROBUST)
730  {
731  std::cout << "Background mode: ";
732  switch (background_mode)
733  {
734  case NOBACKGROUND :
735  std::cout << "None\n";
736  break;
737  case FRAME:
738  std::cout << "Frame, width=" << r << std::endl;
739  std::cout << "Apply transformation to mask: " << apply_geo <<
740  std::endl;
741  break;
742  case CIRCLE:
743  std::cout << "Circle, radius=" << r << std::endl;
744  std::cout << "Apply transformation to mask: " << apply_geo <<
745  std::endl;
746  break;
747  }
748  }
749 
750  if (invert_contrast)
751  std::cout << "Invert contrast "<< std::endl;
752 
753  if (tiltMask)
754  std::cout << "Applying a mask depending on tilt "<< std::endl;
755 
756  if (remove_black_dust)
757  std::cout << "Remove black dust particles, using threshold " <<
758  floatToString(thresh_black_dust) << std::endl;
759 
760  if (remove_white_dust)
761  std::cout << "Remove white dust particles, using threshold " <<
762  floatToString(thresh_white_dust) << std::endl;
763 
764  if (method == NEWXMIPP && enable_mask)
765  mask_prm.show();
766 }
767 
768 
770 {
771  if (!enable_mask)
772  {
775 
776  switch (background_mode)
777  {
778  case FRAME:
779  BinaryFrameMask(bg_mask, xdimOut - 2 * r, ydimOut - 2 * r, zdimOut - 2 * r,
780  OUTSIDE_MASK);
781  break;
782  case CIRCLE:
783  if (r>(int)(xdimOut/2))
784  REPORT_ERROR(ERR_ARG_INCORRECT,"Given radius is larger than half the output size");
786  break;
787  case NOBACKGROUND:
788  break;
789  }
790  }
791  else
792  {
795  }
796  // backup a copy of the mask for apply_geo mode
798 
799  //#define DEBUG
800 #ifdef DEBUG
801 
802  Image<int> tt;
803  tt()=bg_mask;
804  tt.write("PPPmask.xmp");
805  std::cerr<<"DEBUG info: written PPPmask.xmp"<<std::endl;
806 #endif
807 
808  // Get the parameters from the 0 degrees
809  if (method==TOMOGRAPHY0)
810  {
811  // Look for the image at 0 degrees
812  double bestTilt=1000;
813  double tiltTemp;
814  FileName bestImage;
815  FileName fn_img;
816  ImageGeneric Ig;
817  MetaData * md = getInputMd();
818  for (size_t objId: md->ids())
819  {
820  md->getValue(image_label, fn_img, objId);
821 
822  if (fn_img.empty())
823  break;
824 
825  if (!md->getValue(MDL_ANGLE_TILT,tiltTemp, objId))
826  {
827  Ig.readMapped(fn_img);
828  tiltTemp = ABS(Ig.tilt());
829  }
830  if (tiltTemp < bestTilt)
831  {
832  bestTilt = tiltTemp;
833  bestImage = fn_img;
834  }
835  }
836  if (bestImage=="")
837  REPORT_ERROR(ERR_VALUE_EMPTY,"Cannot find the image at 0 degrees");
838 
839  // Compute the mu0 and sigma0 for this image
840  Image<double> I;
841  I.read(bestImage);
843  }
844 }
845 
846 void ProgNormalize::processImage(const FileName &fnImg, const FileName &fnImgOut, const MDRow &rowIn, MDRow &rowOut)
847 {
848  Image<double> I;
849  if (apply_geo)
850  I.readApplyGeo(fnImg, rowIn);
851  else
852  I.read(fnImg);
853 
854  I().setXmippOrigin();
855 
856  MultidimArray<double> &img=I();
857 
858  if (apply_geo)
859  {
861  // Applygeo only valid for 2D images for now...
862  img.checkDimension(2);
863 
865  // get copy of the mask
867  typeCast(bg_mask_bck, tmp);
868 
869  double outside = DIRECT_A2D_ELEM(tmp, 0, 0);
870 
871  // Instead of IS_INV for images use IS_NOT_INV for masks!
873  selfApplyGeometry(xmipp_transformation::BSPLINE3, tmp, A, xmipp_transformation::IS_NOT_INV, xmipp_transformation::DONT_WRAP, outside);
874 
876  dAi(bg_mask,n)=(int)round(dAi(tmp,n));
877  }
878 
879  double a;
880  double b;
881  if (invert_contrast)
882  img *= -1.;
883 
885  {
886  double avg=0.;
887  double stddev=0.;
888  double min=0.;
889  double max=0.;
890  double zz;
891  img.computeStats(avg, stddev, min, max);
892 
893  if ((min - avg) / stddev < thresh_black_dust && remove_black_dust)
894  {
896  {
897  zz = (A3D_ELEM(img, k, i, j) - avg) / stddev;
898  if (zz < thresh_black_dust)
899  A3D_ELEM(img, k, i, j) = rnd_gaus(avg,stddev);
900  }
901  }
902 
903  if ((max - avg) / stddev > thresh_white_dust && remove_white_dust)
904  {
906  {
907  zz = (A3D_ELEM(img, k, i, j) - avg) / stddev;
908  if (zz > thresh_white_dust)
909  A3D_ELEM(img, k, i, j) = rnd_gaus(avg,stddev);
910  }
911  }
912  }
913 
914  double mui;
915  double sigmai;
916  switch (method)
917  {
918  case OLDXMIPP:
919  normalize_OldXmipp(img);
920  break;
921  case NEAR_OLDXMIPP:
923  break;
924  case NEWXMIPP:
926  break;
927  case NEWXMIPP2:
929  break;
930  case ROBUST:
932  break;
933  case RAMP:
934  normalize_ramp(img, &bg_mask);
935  break;
936  case NEIGHBOUR:
938  break;
939  case TOMOGRAPHY:
940  normalize_tomography(img, I.tilt(), mui, sigmai, tiltMask);
941  break;
942  case TOMOGRAPHY0:
943  normalize_tomography(img, I.tilt(), mui, sigmai, tiltMask,
944  true, mu0, sigma0);
945  break;
946  case MICHAEL:
948  break;
949  case RANDOM:
950  a = rnd_unif(a0, aF);
951  b = rnd_unif(b0, bF);
953  A3D_ELEM(img, k, i, j) = a * A3D_ELEM(img, k, i, j) + b;
954  break;
955  case NONE:
956  break;
957  }
958  I.write(fnImgOut);
959 }
Argument missing.
Definition: xmipp_error.h:114
void selfApplyGeometry(int Splinedegree, MultidimArray< std::complex< double > > &V1, const Matrix2D< double > &A, bool inv, bool wrap, std::complex< double > outside)
#define dAi(v, i)
Empty value.
Definition: xmipp_error.h:194
#define INSIDEX(v, x)
void processImage(const FileName &fnImg, const FileName &fnImgOut, const MDRow &rowIn, MDRow &rowOut)
Definition: normalize.cpp:846
void min(Image< double > &op1, const Image< double > &op2)
#define A2D_ELEM(v, i, j)
void normalize_NewXmipp(MultidimArray< double > &I, const MultidimArray< int > &bg_mask)
Definition: normalize.cpp:255
double getDoubleParam(const char *param, int arg=0)
void normalize_Michael(MultidimArray< double > &I, const MultidimArray< int > &bg_mask)
Definition: normalize.cpp:230
void least_squares_plane_fit(FitPoint *IN_points, int Npoints, double &plane_a, double &plane_b, double &plane_c)
Definition: geometry.cpp:101
#define FINISHINGX(v)
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
double mu0
Definition: normalize.h:298
doublereal * c
#define DEG2RAD(d)
Definition: xmipp_macros.h:312
void resizeNoCopy(const MultidimArray< T1 > &v)
double z
z coordinate, assumed to be a function of x and y
Definition: geometry.h:190
double sigma0
Definition: normalize.h:299
void sqrt(Image< double > &op)
void BinaryCircularMask(MultidimArray< int > &mask, double radius, int mode, double x0, double y0, double z0)
Definition: mask.cpp:193
void normalize_tomography(MultidimArray< double > &I, double tilt, double &mui, double &sigmai, bool tiltMask, bool tomography0, double mu0, double sigma0)
Definition: normalize.cpp:77
void computeStats(double &avg, double &stddev, T &minval, T &maxval) const
Tilting angle of an image (double,degrees)
void normalize_Near_OldXmipp(MultidimArray< double > &I, const MultidimArray< int > &bg_mask)
Definition: normalize.cpp:43
double x
x coordinate
Definition: geometry.h:186
#define DIRECT_A2D_ELEM(v, i, j)
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)
int allowed_data_types
Definition: mask.h:495
void computeAvgStdev(U &avg, U &stddev) const
void normalize_OldXmipp_decomposition(MultidimArray< double > &I, const MultidimArray< int > &bg_mask, const MultidimArray< double > *mask)
Definition: normalize.cpp:60
void readParams()
Definition: normalize.cpp:578
double w
Weight of the point in the Least-Squares problem.
Definition: geometry.h:192
virtual IdIteratorProxy< false > ids()
String floatToString(float F, int _width, int _prec)
#define STARTINGX(v)
void computeAvgStdev_within_binary_mask(const MultidimArray< int > &mask, double &avg, double &stddev) const
virtual bool getValue(MDObject &mdValueOut, size_t id) const =0
int readApplyGeo(const FileName &name, const MDRow &row, const ApplyGeoParams &params=DefaultApplyGeoParams)
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
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
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
static void defineParams(XmippProgram *program, int allowed_data_types=ALL_KINDS, const char *prefix=nullptr, const char *comment=nullptr, bool moreOptions=false)
Definition: mask.cpp:1203
double tilt(const size_t n=0) const
#define STARTINGY(v)
void addKeywords(const char *keywords)
void threshold(double *phi, unsigned long nvox, double limit)
Definition: lib_vwk.cpp:524
double rnd_unif()
#define A3D_ELEM(V, k, i, j)
#define FOR_ALL_ELEMENTS_IN_ARRAY3D(V)
doublereal * b
NormalizationMode method
Definition: normalize.h:224
#define FLOOR(x)
Definition: xmipp_macros.h:240
void computeMedian_within_binary_mask(const MultidimArray< int > &mask, double &median) const
const char * getParam(const char *param, int arg=0)
#define INSIDEY(v, y)
void normalize_ramp(MultidimArray< double > &I, MultidimArray< int > *bg_mask)
Definition: normalize.cpp:333
Incorrect argument received.
Definition: xmipp_error.h:113
void normalize_remove_neighbours(MultidimArray< double > &I, const MultidimArray< int > &bg_mask, const double &threshold)
Definition: normalize.cpp:427
double thresh_white_dust
Definition: normalize.h:282
bool enable_mask
Definition: normalize.h:290
#define XSIZE(v)
void normalize_Robust(MultidimArray< double > &I, const MultidimArray< int > &bg_mask, bool clip)
Definition: normalize.cpp:265
void max(Image< double > &op1, const Image< double > &op2)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
Error related to numerical calculation.
Definition: xmipp_error.h:179
double icdf_FSnedecor(int d1, int d2, double p)
#define ABS(x)
Definition: xmipp_macros.h:142
#define DIRECT_MULTIDIM_ELEM(v, n)
void addExampleLine(const char *example, bool verbatim=true)
void readParams(XmippProgram *program)
Definition: mask.cpp:1284
MDLabel image_label
MDLabel to be used to read/write images, usually will be MDL_IMAGE.
BackgroundMode background_mode
Definition: normalize.h:240
MultidimArray< int > bg_mask
Definition: normalize.h:288
void sort(struct DCEL_T *dcel)
Definition: sorting.cpp:18
#define SPEED_UP_temps
Definition: xmipp_macros.h:419
void defineParams()
Definition: normalize.cpp:520
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
bool invert_contrast
Definition: normalize.h:264
double y
y coordinate
Definition: geometry.h:188
#define j
bool remove_black_dust
Definition: normalize.h:276
void show() const override
#define FINISHINGY(v)
void generate_mask(bool apply_geo=false)
Definition: mask.cpp:1577
int round(double x)
Definition: ap.cpp:7245
MultidimArray< int > bg_mask_bck
Definition: normalize.h:289
bool save_metadata_stack
Save the associated output metadata when output file is a stack.
void typeCast(const Matrix1D< T1 > &v1, Matrix1D< T2 > &v2)
Definition: matrix1d.h:1227
void normalize_NewXmipp2(MultidimArray< double > &I, const MultidimArray< int > &bg_mask)
Definition: normalize.cpp:315
double rnd_gaus()
#define INT_MASK
Definition: mask.h:385
double thresh_black_dust
Definition: normalize.h:281
bool keep_input_columns
Keep input metadata columns.
bool checkParam(const char *param)
constexpr int OUTSIDE_MASK
Definition: mask.h:48
void getTransformationMatrix(Matrix2D< double > &A, bool only_apply_shifts=false, const size_t n=0)
int read(const FileName &name, DataMode datamode=DATA, size_t select_img=ALL_IMAGES, bool mapData=false, int mode=WRITE_READONLY)
MultidimArray< int > imask
Definition: mask.h:499
constexpr int K
void normalize_OldXmipp(MultidimArray< double > &I)
Definition: normalize.cpp:33
double EntropySegmentation(MultidimArray< double > &V)
Definition: filters.cpp:1078
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)
void initZeros(const MultidimArray< T1 > &op)
int getIntParam(const char *param, int arg=0)
Incorrect value received.
Definition: xmipp_error.h:195
void preProcess()
Definition: normalize.cpp:769
int readMapped(const FileName &name, size_t select_img=ALL_IMAGES, int mode=WRITE_READONLY)
int * n
doublereal * a
double sum() const
void show() const
Definition: mask.cpp:1021
void addParamsLine(const String &line)
bool remove_white_dust
Definition: normalize.h:277
void BinaryFrameMask(MultidimArray< int > &mask, int Xrect, int Yrect, int Zrect, int mode, double x0, double y0, double z0)
Definition: mask.cpp:309
void least_squares_plane_fit_All_Points(const MultidimArray< double > &Image, double &plane_a, double &plane_b, double &plane_c)
Definition: geometry.cpp:154
T computeMax() const
double thresh_neigh
Definition: normalize.h:286
double tilt(const size_t n=0) const