Xmipp  v3.23.11-Nereus
metadata_histogram.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar coss@cnb.csic.es (1999)
4  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19  * 02111-1307 USA
20  *
21  * All comments concerning this program package may be sent to the
22  * e-mail address 'xmipp@cnb.csic.es'
23  ***************************************************************************/
24 
25 #include "core/histogram.h"
26 #include "core/metadata_vec.h"
27 #include "core/xmipp_image.h"
28 #include "core/xmipp_program.h"
29 
31 {
32 public:
35  MDLabel col, col2; // Columns for histogram
36  double m, M, m2, M2; // range for histogram
41  double percentil;
42 
43  void defineParams()
44  {
45  addUsageLine("Calculate histogram from a metadata column(1D) or from a couple of columns(2D)");
46  addParamsLine(" -i <input_metadata> : input metadata");
47  addParamsLine(" [-o <text_file=\"/dev/stdout\">] : output text file with histogram, by default standard output");
48  addParamsLine(" --col <label> : column to create the histogram");
49  addParamsLine(" [--range <m> <M>] : range for the histogram, automatic calculated if not provided");
50  addParamsLine(" [--steps <N=100>] : number of subdivisions");
51  addParamsLine(" [--col2 <label=\"\"> ] : if specified, a 2D histogram is calculated");
52  addParamsLine(" [--range2 <m> <M>] : range for second column in 2D histogram");
53  addParamsLine(" requires --col2;");
54  addParamsLine(" [--steps2 <N=100>] : number of subdivisions in second column");
55  addParamsLine(" requires --col2;");
56  addParamsLine(" [--percentil <p=50.>] : Only for 1D histograms");
57  addParamsLine(" [--write_as_image <image_file>] : Only for 2D histograms");
58  addParamsLine(" requires --col2;");
59 
60  addExampleLine("Calculate the histogram of the column 'angleRot' from a metadata:", false);
61  addExampleLine("xmipp_metadata_histogram -i images.xmd --col angleRot -o hist.txt");
62 
63  addSeeAlsoLine("image_histogram");
64 
65  }
66 
67  void readColumn(MDLabel &column, bool &automatic, double &m, double &M, int &steps, bool second=false)
68  {
69  const char* colStr = second ? "--col2" : "--col";
70  const char* rangeStr = second ? "--range2" : "--range";
71  const char* stepStr = second ? "--steps2" : "--steps";
72 
73  column = MDL::str2Label(getParam(colStr));
74  steps = getIntParam(stepStr);
75  automatic = true;
76  if (checkParam(rangeStr))
77  {
78  m = getDoubleParam(rangeStr, 0);
79  M = getDoubleParam(rangeStr, 1);
80  automatic = false;
81  }
82 
83  // Check if valid columns where provided
84  if (column == MDL_UNDEFINED)
85  REPORT_ERROR(ERR_MD_UNDEFINED, "Metadata Histogram: Column for histogram not valid");
86  else if (!MDL::isDouble(column))
87  REPORT_ERROR(ERR_MD_BADTYPE, "Metadata Histogram: Column type for histogram should be double");
88  }
89 
90  void getColumnValues(const MDLabel column, MultidimArray<double> &values, const bool automatic, double &m, double &M)
91  {
92  std::vector<double> columnValues;
93  mdIn.getColumnValues(column, columnValues);
94  values = columnValues;
95  if (automatic)
96  values.computeDoubleMinMax(m, M);
97  }
98 
99  void readParams()
100  {
101  fn_in = getParam("-i");
102  mdIn.read(fn_in);
103  fn_out = getParam("-o");
104  percentil = getDoubleParam("--percentil");
105  readColumn(col, automatic_range, m, M, StepsNo);
106 
107  if ((do_hist2d = checkParam("--col2")))
108  readColumn(col2, automatic_range2, m2, M2, StepsNo2, true);
109 
110  if ((write_img = checkParam("--write_as_image")))
111  fn_img = getParam("--write_as_image");
112  }
113 
114  void run()
115  {
116  double avg=0., stddev=0., dummy;
118  getColumnValues(col, C, automatic_range, m, M);
119 
120  if (!do_hist2d)
121  {
122  compute_hist(C, hist, m, M, StepsNo);
123  std::cout << formatString("min: %f max: %f steps: %d", m, M, StepsNo) << std::endl;
124  C.computeStats(avg, stddev, dummy, dummy);
125  std::cout << formatString("mean: %f stddev: %f", avg, stddev) << std::endl;
126  std::cout << formatString("percentil (%f)", hist.percentil(percentil)) << std::endl;
127  hist.write(fn_out);
128  }
129  else
130  {
132  getColumnValues(col2, C2, automatic_range2, m2, M2);
133  compute_hist(C, C2, hist2, m, M, m2, M2, StepsNo, StepsNo2);
134  //stats for column 1
135  std::cout << formatString("min1: %f max1: %f steps1: %d", m, M, StepsNo) << std::endl;
136  C.computeStats(avg, stddev, dummy, dummy);
137  std::cout << formatString("mean: %f stddev: %f", avg, stddev) << std::endl;
138  //stats for column 2
139  std::cout << formatString("min2: %f max2: %f steps2: %d", m2, M2, StepsNo2) << std::endl;
140  C2.computeStats(avg, stddev, dummy, dummy);
141  std::cout << formatString("mean: %f stddev: %f", avg, stddev) << std::endl;
142  hist2.write(fn_out);
143 
144  if (write_img)
145  {
146  Image<double> img;
147  img() = hist2;
148  img.write(fn_img);
149  }
150  }
151  }
152 
153 }
154 ;//end of class ProgHistogram
double getDoubleParam(const char *param, int arg=0)
static MDLabel str2Label(const String &labelName)
void read(const FileName &inFile, const std::vector< MDLabel > *desiredLabels=nullptr, bool decomposeStack=true) override
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void computeStats(double &avg, double &stddev, T &minval, T &maxval) const
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)
double percentil(double percent_mass)
Definition: histogram.cpp:160
void addSeeAlsoLine(const char *seeAlso)
Undefined label.
Definition: xmipp_error.h:162
const char * getParam(const char *param, int arg=0)
void compute_hist(const MultidimArrayGeneric &array, Histogram1D &hist, int no_steps)
Definition: histogram.cpp:572
void readColumn(MDLabel &column, bool &automatic, double &m, double &M, int &steps, bool second=false)
void computeDoubleMinMax(double &minval, double &maxval) const
void addExampleLine(const char *example, bool verbatim=true)
void write(const FileName &fn)
Definition: histogram.cpp:561
double dummy
double steps
void getColumnValues(const MDLabel label, std::vector< MDObject > &valuesOut) const override
Bad label type.
Definition: xmipp_error.h:161
void write(const FileName &fn, MDLabel=MDL_X, MDLabel=MDL_COUNT)
Definition: histogram.cpp:129
static bool isDouble(const MDLabel label)
String formatString(const char *format,...)
bool checkParam(const char *param)
void addUsageLine(const char *line, bool verbatim=false)
int getIntParam(const char *param, int arg=0)
void getColumnValues(const MDLabel column, MultidimArray< double > &values, const bool automatic, double &m, double &M)
MDLabel
void addParamsLine(const String &line)