Xmipp  v3.23.11-Nereus
histogram.h
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar S. Sorzano (coss@cnb.csic.es)
4  * Arun Kulshreshth (arun_2000_iitd@yahoo.com)
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 'xmipp@cnb.csic.es'
25  ***************************************************************************/
26 
27 #ifndef CORE_HISTOGRAM_H
28 #define CORE_HISTOGRAM_H
29 
30 #include "multidim_array.h"
31 #include "multidim_array_generic.h"
32 #include "metadata_label.h"
33 
36 
37 
121 class Histogram1D: public MultidimArray< double >
122 {
123 public:
124  // Structure
125  double hmin; // minimum value of the histogram
126  double hmax; // maximum value of the histogram
127  double step_size; // size of step
128  double istep_size;
129  int no_samples; // No. of points inside the histogram
130 
141  {
142  clear();
143  }
144 
154  {
155  clear();
156  *this = H;
157  }
158 
167  void clear();
168 
170  Histogram1D& operator=(const Histogram1D& H);
171 
173  void assign(const Histogram1D& H);
174 
189  void init(double min_val, double max_val, int n_steps);
190 
202  void insert_value(double val);
203 
205 #define INSERT_VALUE(histogram,value) \
206 {\
207  if (value == histogram.hmax) { \
208  size_t iii = XSIZE(histogram) - 1; \
209  ++DIRECT_A1D_ELEM(histogram, iii); \
210  ++histogram.no_samples; \
211  } else { \
212  size_t iii = (size_t) ((value - histogram.hmin) * histogram.istep_size); \
213  if (iii >= 0 && iii < XSIZE(histogram)) \
214  { \
215  ++DIRECT_A1D_ELEM(histogram, iii); \
216  ++histogram.no_samples; \
217  } \
218  } \
219 }
220 
233  double percentil(double percent_mass);
234 
239  double mass_below(double value);
240 
245  double mass_above(double value)
246  {
247  return no_samples - mass_below(value);
248  }
249 
255  friend std::ostream& operator<<(std::ostream& o, const Histogram1D& hist);
256 
259  void write(const FileName& fn, MDLabel=MDL_X, MDLabel=MDL_COUNT);
260 
271  void val2index(double v, int& i) const
272  {
273  if (v == hmax)
274  i = XSIZE(*this) - 1;
275  else
276  {
277  double aux=(v - hmin) * istep_size;
278  i = (int) FLOOR(aux);
279  }
280 
281  if (i < 0 || i >= (int)XSIZE(*this))
282  i = -1;
283  }
284 
295  inline void index2val(double i, double& v) const
296  {
297  v = hmin + i * step_size;
298  }
299 
306  double hist_min() const
307  {
308  return hmin;
309  }
310 
317  double hist_max() const
318  {
319  return hmax;
320  }
321 
328  double step() const
329  {
330  return step_size;
331  }
332 
339  int stepNo() const
340  {
341  return XSIZE(*this);
342  }
343 
350  double sampleNo() const
351  {
352  return no_samples;
353  }
354 
360  double entropy() const;
361 };
362 
365  class CDF
366  {
367  public:
370  double minVal, maxVal;
371  public:
373  void calculateCDF(MultidimArray<double> &V, double probStep=0.005);
374 
376  double getProbability(double x);
377  };
378 
379 
387 {
388 public:
391 public:
393  void init(const Histogram1D &oldHistogram, const MultidimArray<int> &bins);
394 
396  int val2Index(double value) const;
397 
399  void selfNormalize();
400 
402  friend std::ostream & operator << (std::ostream &_out,
403  const IrregularHistogram1D &_h);
404 
406  inline double operator()(int i) const
407  {
408  return DIRECT_A1D_ELEM(__hist,i);
409  }
410 
412  const Histogram1D& getHistogram() const;
413 };
414 
429 template<typename T>
430 void compute_hist(const MultidimArray<T>& array, Histogram1D& hist,
431  int no_steps)
432 {
433  double min=0, max=0;
434  array.computeDoubleMinMax(min, max);
435  compute_hist(array, hist, min, max, no_steps);
436 }
437 
439 void compute_hist(const MultidimArrayGeneric& array, Histogram1D& hist,
440  int no_steps);
441 
444 template<typename T>
445 void compute_hist(const std::vector< T > &v,
446  Histogram1D& hist,
447  int no_steps = 100)
448 {
449  hist.clear();
450  int imax=v.size();
451  if (imax==0)
452  return;
453 
454  // Compute minimum and maximum
455  double min, max;
456  min=max=v[0];
457  for (int i=1; i<imax; i++)
458  {
459  double val=v[i];
460  min=XMIPP_MIN(min,val);
461  max=XMIPP_MAX(max,val);
462  }
463  hist.init(min, max, no_steps);
464 
465  for (int i=1; i<imax; i++)
466  {
467  double value=v[i];
468  INSERT_VALUE(hist,value);
469  }
470 }
471 
485 template<typename T>
487  double min, double max, int no_steps)
488 {
489  hist.init(min, max, no_steps);
490  T* ptr=&DIRECT_MULTIDIM_ELEM(v,0);
491  size_t nmax=(MULTIDIM_SIZE(v)/4)*4;
492 
493  double value;
494  for (size_t n=0; n<nmax; n+=4, ptr+=4)
495  {
496  value=*ptr;
497  INSERT_VALUE(hist,value);
498  value=*(ptr+1);
499  INSERT_VALUE(hist,value);
500  value=*(ptr+2);
501  INSERT_VALUE(hist,value);
502  value=*(ptr+3);
503  INSERT_VALUE(hist,value);
504  }
505  for (size_t n=nmax; n<MULTIDIM_SIZE(v); ++n, ptr+=1)
506  {
507  value=*ptr;
508  INSERT_VALUE(hist,value);
509  }
510 }
511 
514 void compute_hist(const MultidimArrayGeneric& v, Histogram1D& hist,
515  double min, double max, int no_steps);
516 
521 template<typename T>
523  & v, Histogram1D& hist,
524  const Matrix1D< int >& corner1,
525  const Matrix1D< int >& corner2,
526  int no_steps = 100)
527 {
528  double min, max;
529  v.computeDoubleMinMax(min, max, corner1, corner2);
530  hist.init(min, max, no_steps);
531 
532  Matrix1D< int > r(2);
533  FOR_ALL_ELEMENTS_IN_ARRAY2D_BETWEEN(corner1, corner2)
534  {
535  double value=v(r);
536  INSERT_VALUE(hist,value);
537  }
538 }
539 
559 double detectability_error(const Histogram1D& h1, const Histogram1D& h2);
560 
569 double KLDistance(const Histogram1D& h1, const Histogram1D& h2);
570 
589 template<typename T>
590 double effective_range(const T& v, double percentil_out = 0.25)
591 {
592  Histogram1D hist;
593  compute_hist(v, hist, 200)
594  ;
595  double min_val = hist.percentil(percentil_out / 2);
596  double max_val = hist.percentil(100 - percentil_out / 2);
597  return max_val - min_val;
598 }
599 
604 template<typename T>
605 void reject_outliers(T& v, double percentil_out = 0.25)
606 {
607  Histogram1D hist;
608  compute_hist(v, hist, 400);
609  double eff0 = hist.percentil(percentil_out / 2);
610  double effF = hist.percentil(100 - percentil_out / 2);
611  int i0, iF;
612  hist.val2index(eff0, i0);
613  hist.val2index(effF, iF);
614  if (iF == i0) {
615  hist.index2val(i0, eff0);
616  hist.index2val(i0 + 1, effF);
617  }
618 
620  if (DIRECT_MULTIDIM_ELEM(v,n) < eff0)
621  DIRECT_MULTIDIM_ELEM(v,n) = eff0;
622  else if (DIRECT_MULTIDIM_ELEM(v,n) > effF)
623  DIRECT_MULTIDIM_ELEM(v,n) = effF;
624 }
625 
632 template<typename T>
634  & v, int bins = 8)
635 {
636  const int hist_steps = 200;
637  Histogram1D hist;
638  compute_hist(v, hist, hist_steps);
639 
640  // Compute the distribution function of the pdf
641  MultidimArray<double> norm_sum(hist_steps);
642  DIRECT_A1D_ELEM(norm_sum,0) = DIRECT_A1D_ELEM(hist,0);
643 
644  for (int i = 1; i < hist_steps; i++)
645  DIRECT_A1D_ELEM(norm_sum,i) = DIRECT_A1D_ELEM(norm_sum,i - 1) + DIRECT_A1D_ELEM(hist,i);
646  norm_sum /= MULTIDIM_SIZE(v);
647 
648  // array to store the boundary pixels of bins
649  MultidimArray< double > div(bins - 1);
650  int index = 0;
651 
652  for (int current_bin = 1; current_bin < bins; current_bin++)
653  {
654  double current_value = (double) current_bin / bins;
655  while (DIRECT_A1D_ELEM(norm_sum,index) < current_value && index < FINISHINGX(norm_sum))
656  index++;
657  hist.index2val((double) index, DIRECT_A1D_ELEM(div,current_bin - 1));
658  }
659 
660  // requantize and equalize histogram
661  T* ptr=NULL;
662  unsigned long int n;
664  {
665  T vi=*ptr;
666  if (vi < DIRECT_A1D_ELEM(div,0))
667  *ptr = 0;
668  else if (vi > DIRECT_A1D_ELEM(div,bins - 2))
669  *ptr = bins - 1;
670  else
671  {
672  index = 0;
673  while (vi > DIRECT_A1D_ELEM(div,index))
674  index++;
675  *ptr = index;
676  }
677  }
678 }
680 
699 class Histogram2D : public MultidimArray< double >
700 {
701 public:
702  // Structure
703  double imin; // minimum value of the i axis
704  double imax; // maximum value of the i axis
705  double istep_size; // size of step
706  double jmin; // minimum value of the j axis
707  double jmax; // maximum value of the j axis
708  double jstep_size; // size of step
709  int no_samples; // No. of points inside the histogram
710 
721  {
722  clear();
723  }
724 
734  {
735  *this = H;
736  }
737 
746  void clear();
747 
750  Histogram2D& operator=(const Histogram2D& H);
751 
754  void assign(const Histogram2D& H);
755 
770  void init(double imin_val, double imax_val, int in_steps,
771  double jmin_val, double jmax_val, int jn_steps);
772 
787  void insert_value(double v, double u);
788 
794  friend std::ostream& operator<<(std::ostream& o, const Histogram2D& hist);
795 
798  void write(const FileName& fn);
799 
813  void val2index(double v, double u, int& i, int& j) const
814  {
815  if (v == imax)
816  i = IstepNo() - 1;
817  else
818  i = (int) FLOOR((v - imin) / istep_size);
819 
820  if (u == jmax)
821  j = JstepNo() - 1;
822 
823  j = (int) FLOOR((u - jmin) / jstep_size);
824 
825  if (i < 0 || i >= IstepNo())
826  i = -1;
827 
828  if (j < 0 || j >= JstepNo())
829  j = -1;
830  }
831 
843  void index2val(double i, double j, double& v, double& u) const
844  {
845  v = imin + i * istep_size;
846  u = jmin + j * jstep_size;
847  }
848 
855  double Ihist_min() const
856  {
857  return imin;
858  }
859 
866  double Ihist_max() const
867  {
868  return imax;
869  }
870 
877  double Istep() const
878  {
879  return istep_size;
880  }
881 
888  int IstepNo() const
889  {
890  return YSIZE(*this);
891  }
892 
899  double Jhist_min() const
900  {
901  return jmin;
902  }
903 
910  double Jhist_max() const
911  {
912  return jmax;
913  }
914 
921  double Jstep() const
922  {
923  return jstep_size;
924  }
925 
932  int JstepNo() const
933  {
934  return XSIZE(*this);
935  }
936 
943  int sampleNo() const
944  {
945  return no_samples;
946  }
947 };
948 
965 template<typename T>
966 void compute_hist(const T& v1, const T& v2,
967  Histogram2D& hist, int no_steps1, int no_steps2)
968 {
969  double min1, max1;
970  v1.computeDoubleMinMax(min1, max1)
971  ;
972 
973  double min2, max2;
974  v2.computeDoubleMinMax(min2, max2);
975 
976  compute_hist(v1, v2, hist, min1, max1, min2, max2, no_steps1, no_steps2);
977 }
978 
984 template<typename T>
986  & v1, const MultidimArray<T>& v2,
987  Histogram2D& hist,
988  double m1, double M1, double m2, double M2, int no_steps1,
989  int no_steps2)
990 {
991  if (!v1.sameShape(v2))
992  REPORT_ERROR(ERR_MULTIDIM_SIZE, "compute_hist: v1 and v2 are of different shape");
993 
994  hist.init(m1, M1, no_steps1, m2, M2, no_steps2);
995 
998  DIRECT_MULTIDIM_ELEM(v2, n));
999 }
1001 
1002 #endif
int sampleNo() const
Definition: histogram.h:943
void insert_value(double v, double u)
Definition: histogram.cpp:530
void val2index(double v, int &i) const
Definition: histogram.h:271
void clear()
Definition: histogram.cpp:40
int * nmax
#define YSIZE(v)
void min(Image< double > &op1, const Image< double > &op2)
double istep_size
Definition: histogram.h:705
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
double KLDistance(const Histogram1D &h1, const Histogram1D &h2)
Definition: histogram.cpp:377
double hist_max() const
Definition: histogram.h:317
#define FINISHINGX(v)
int IstepNo() const
Definition: histogram.h:888
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
#define INSERT_VALUE(histogram, value)
Definition: histogram.h:205
#define MULTIDIM_SIZE(v)
int JstepNo() const
Definition: histogram.h:932
double mass_below(double value)
Definition: histogram.cpp:215
MultidimArray< double > probXLessThanx
Definition: histogram.h:369
double detectability_error(const Histogram1D &h1, const Histogram1D &h2)
Definition: histogram.cpp:324
void assign(const Histogram1D &H)
Definition: histogram.cpp:66
double step() const
Definition: histogram.h:328
void init(double imin_val, double imax_val, int in_steps, double jmin_val, double jmax_val, int jn_steps)
Definition: histogram.cpp:512
Histogram1D & operator=(const Histogram1D &H)
Definition: histogram.cpp:51
double percentil(double percent_mass)
Definition: histogram.cpp:160
void index2val(double i, double j, double &v, double &u) const
Definition: histogram.h:843
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY_ptr(v, n, ptr)
Incorrect MultidimArray size.
Definition: xmipp_error.h:174
double hmin
Definition: histogram.h:125
double jmax
Definition: histogram.h:707
double hmax
Definition: histogram.h:126
double Ihist_min() const
Definition: histogram.h:855
void init(double min_val, double max_val, int n_steps)
Definition: histogram.cpp:71
#define i
void insert_value(double val)
Definition: histogram.cpp:83
double jstep_size
Definition: histogram.h:708
#define DIRECT_A1D_ELEM(v, i)
int stepNo() const
Definition: histogram.h:339
#define M2
friend std::ostream & operator<<(std::ostream &o, const Histogram1D &hist)
Definition: histogram.cpp:115
#define M1
void index2val(double i, double &v) const
Definition: histogram.h:295
double v1
#define FLOOR(x)
Definition: xmipp_macros.h:240
Number of elements of a type (int) [this is a genereic type do not use to transfer information to ano...
double imax
Definition: histogram.h:704
viol index
Histogram1D(const Histogram1D &H)
Definition: histogram.h:153
Definition: histogram.h:365
void reject_outliers(T &v, double percentil_out=0.25)
Definition: histogram.h:605
void val2index(double v, double u, int &i, int &j) const
Definition: histogram.h:813
double Jhist_min() const
Definition: histogram.h:899
bool sameShape(const MultidimArrayBase &op) const
#define XSIZE(v)
void computeDoubleMinMax(double &minval, double &maxval) const
Histogram2D(const Histogram2D &H)
Definition: histogram.h:733
void max(Image< double > &op1, const Image< double > &op2)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
void compute_hist(const MultidimArray< T > &array, Histogram1D &hist, int no_steps)
Definition: histogram.h:430
double Istep() const
Definition: histogram.h:877
MultidimArray< double > __binsRightLimits
Definition: histogram.h:390
int current_value
Definition: svm-toy.cpp:54
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
double Ihist_max() const
Definition: histogram.h:866
double Jstep() const
Definition: histogram.h:921
#define j
double hist_min() const
Definition: histogram.h:306
double effective_range(const T &v, double percentil_out=0.25)
Definition: histogram.h:590
double operator()(int i) const
Get value.
Definition: histogram.h:406
int no_samples
Definition: histogram.h:709
double mass_above(double value)
Definition: histogram.h:245
void write(const FileName &fn, MDLabel=MDL_X, MDLabel=MDL_COUNT)
Definition: histogram.cpp:129
void histogram_equalization(MultidimArray< T > &v, int bins=8)
Definition: histogram.h:633
int no_samples
Definition: histogram.h:129
X component (double)
doublereal * u
double entropy() const
Definition: histogram.cpp:238
double step_size
Definition: histogram.h:127
double sampleNo() const
Definition: histogram.h:350
double jmin
Definition: histogram.h:706
double Jhist_max() const
Definition: histogram.h:910
MultidimArray< double > x
Definition: histogram.h:368
#define FOR_ALL_ELEMENTS_IN_ARRAY2D_BETWEEN(corner1, corner2)
int * n
MDLabel
double imin
Definition: histogram.h:703
double minVal
Definition: histogram.h:370
double istep_size
Definition: histogram.h:128
Histogram1D __hist
Definition: histogram.h:389