CosmoBolognaLib
Free Software C++/Python libraries for cosmological calculations
Data2D.cpp
Go to the documentation of this file.
1 /********************************************************************
2  * Copyright (C) 2014 by Federico Marulli and Alfonso Veropalumbo *
3  * federico.marulli3@unibo.it *
4  * *
5  * This program is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU General Public License as *
7  * published by the Free Software Foundation; either version 2 of *
8  * the License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public *
16  * License along with this program; if not, write to the Free *
17  * Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ********************************************************************/
20 
34 #include "Data2D.h"
35 
36 using namespace std;
37 
38 using namespace cbl;
39 using namespace data;
40 
41 
42 // ======================================================================================
43 
44 
45 cbl::data::Data2D::Data2D (const std::vector<double> x, const std::vector<double> y, const std::vector<std::vector<double>> data, const std::vector<double> bin_edges_x, const std::vector<double> bin_edges_y) : Data(DataType::_2D_)
46 {
47  m_x = x;
48  m_y = y;
49  if (bin_edges_x.size()>0)
50  m_edges_xx = bin_edges_x;
51  if (bin_edges_y.size()>0)
52  m_edges_yy = bin_edges_y;
53 
54  m_xsize = m_x.size();
55  m_ysize = m_y.size();
56 
57  checkDim(data, m_xsize, "data");
58 
59  for (int i=0; i<m_xsize; i++) {
60  checkDim(data[i], m_ysize, "data["+conv(i,par::fINT)+"]");
61  for (int j=0; j<m_ysize; j++)
62  m_data.push_back(data[i][j]);
63  }
64 
65  m_ndata = m_data.size();
66  m_error.resize(m_ndata,0);
67 
68  m_covariance.resize(m_ndata, vector<double>(m_ndata,0));
69 }
70 
71 
72 // ======================================================================================
73 
74 
75 cbl::data::Data2D::Data2D (const std::vector<double> x, const std::vector<double> y, const std::vector<std::vector<double>> data, const std::vector<std::vector<double>> error, const std::vector<double> bin_edges_x, const std::vector<double> bin_edges_y) : Data(DataType::_2D_)
76 {
77  m_x = x;
78  m_y = y;
79  if (bin_edges_x.size()>0)
80  m_edges_xx = bin_edges_x;
81  if (bin_edges_y.size()>0)
82  m_edges_yy = bin_edges_y;
83 
84  m_xsize = m_x.size();
85  m_ysize = m_y.size();
86 
87  checkDim(data, m_xsize, "data");
88 
89  checkDim(error, m_xsize, "error");
90 
91  for (int i=0; i<m_xsize; i++) {
92  checkDim(data[i], m_ysize, "data["+conv(i, par::fINT)+"]");
93  checkDim(error[i], m_ysize, "error["+conv(i, par::fINT)+"]");
94  for (int j=0; j<m_ysize; j++) {
95  m_data.push_back(data[i][j]);
96  m_error.push_back(error[i][j]);
97  }
98  }
99 
100  m_ndata = m_data.size();
101 
102  m_covariance.resize(m_ndata, vector<double>(m_ndata, 0));
103  for (int i=0; i<m_ndata; i++)
104  m_covariance[i][i] = pow(m_error[i], 2);
105 }
106 
107 
108 // ======================================================================================
109 
110 
111 cbl::data::Data2D::Data2D (const std::vector<double> x, const std::vector<double> y, const std::vector<double> data, const std::vector<double> error, const std::vector<double> bin_edges_x, const std::vector<double> bin_edges_y) : Data(DataType::_2D_)
112 {
113  m_x = x;
114  m_y = y;
115  if (bin_edges_x.size()>0)
116  m_edges_xx = bin_edges_x;
117  if (bin_edges_y.size()>0)
118  m_edges_yy = bin_edges_y;
119 
120  m_xsize = m_x.size();
121  m_ysize = m_y.size();
122 
123  checkDim(data, m_xsize*m_ysize, "data");
124  checkDim(error, m_xsize*m_ysize, "error");
125 
126  m_data = data;
127  m_error = error;
128 
129  m_ndata = m_data.size();
130 
131  m_covariance.resize(m_ndata, vector<double>(m_ndata,0));
132  for (int i=0; i<m_ndata; i++)
133  m_covariance[i][i] = pow(m_error[i], 2);
134 }
135 
136 
137 // ======================================================================================
138 
139 
140 cbl::data::Data2D::Data2D (const std::vector<double> x, const std::vector<double> y, const std::vector<double> data, const std::vector<std::vector<double>> covariance_matrix, const std::vector<double> bin_edges_x, const std::vector<double> bin_edges_y) : Data(DataType::_2D_)
141 {
142  m_x = x;
143  m_y = y;
144  if (bin_edges_x.size()>0)
145  m_edges_xx = bin_edges_x;
146  if (bin_edges_y.size()>0)
147  m_edges_yy = bin_edges_y;
148 
149  m_xsize = m_x.size();
150  m_ysize = m_y.size();
151 
152  checkDim(data, m_xsize*m_ysize, "data");
153 
154  m_data = data;
155 
156  m_ndata = m_data.size();
157  m_error.resize(m_ndata,0);
158 
159  checkDim(covariance_matrix, m_ndata, "covariance_matrix");
160  for (int i=0;i<m_ndata;i++)
161  checkDim(covariance_matrix[i], m_ndata, "covariance_matrix["+conv(i,par::fINT)+"]");
162 
164 
165  for (int i=0;i<m_ndata;i++)
166  m_error[i] = sqrt(m_covariance[i][i]);
167 }
168 
169 
170 // ======================================================================================
171 
172 
173 void cbl::data::Data2D::get_data (std::vector<std::vector<double>> &data) const
174 {
175  data.erase(data.begin(), data.end());
176  data.resize(m_xsize, vector<double>(m_ysize,0));
177 
178  for (int i=0; i<m_xsize; i++)
179  for (int j=0; j< m_ysize; j++)
180  data[i][j] = this->data(i,j);
181 }
182 
183 
184 // ======================================================================================
185 
186 
187 void cbl::data::Data2D::get_error (std::vector<std::vector<double>> &error) const
188 {
189  error.erase(error.begin(), error.end());
190  error.resize(m_xsize, vector<double>(m_ysize,0));
191 
192  for (int i=0; i<m_xsize; i++)
193  for (int j=0; j< m_ysize; j++)
194  error[i][j] = this->error(i,j);
195 }
196 
197 
198 // ======================================================================================
199 
200 
201 void cbl::data::Data2D::read (const string input_file, const int skip_nlines, const vector<int> column, const vector<int> column_data, const vector<int> column_errors, const vector<int> column_edges)
202 {
203  if (column_data.size()!=column_errors.size()) ErrorCBL("the sizes of column_data and columt_errors must be equal!", "read", "Data2D.cpp");
204 
205  // default column of input data values in the y dimension
206  int column_data_default = column[1]+1;
207 
208  // default column of input error values
209  int column_error_default = column[1]+2;
210 
211  // default first column of input edge values
212  int column_edges_default = column[1]+3;
213 
214  ifstream fin(input_file.c_str()); checkIO(fin, input_file);
215  string line;
216 
217  // loop on the data (and, possibly, error) vectors to be read; if
218  // more than one data vectors are read, the data (and, possibly,
219  // error) vectors will be added one after the other, in order to
220  // construct a single data object
221  const int cl_max = (column_data.size()<2) ? 1 : column_data.size();
222  std::vector<double> dummy_edges_xx, dummy_edges_yy;
223  for (int cl=0; cl<cl_max; ++cl) {
224 
225  // skip the first nlines (in case of header lines)
226  if (skip_nlines>0)
227  for (int i=0; i<skip_nlines; ++i)
228  getline(fin, line);
229 
230 
231  // read the file lines
232 
233  double last_bin_edge_xx = par::defaultDouble;
234  double last_bin_edge_yy = par::defaultDouble;
235 
236  while (getline(fin, line)) {
237 
238  stringstream ss(line);
239  vector<double> num; double NUM;
240  while (ss>>NUM) num.emplace_back(NUM);
241 
242  if (num.size()<3) ErrorCBL("there are less than 3 columns in the input file!", "read", "Data2D.cpp");
243 
244  // if column[0] is larger than 0, the column of x coordinates is
245  // the one specified in input
246  size_t ind_x = max(0, column[0]-1);
247  checkDim(num, ind_x+1, "num", false);
248  m_x.emplace_back(num[ind_x]);
249 
250  // if column[1] is larger than 0, the column of y coordinates is
251  // the one specified in input
252  size_t ind_y = max(0, column[1]-1);
253  checkDim(num, ind_y+1, "num", false);
254  m_y.emplace_back(num[ind_y]);
255 
256  // if the size of the column_data vector is 0, the columns of
257  // data values are the ones specified in input
258  const size_t ind_data = (column_data.size()==0) ? column_data_default-1 : column_data[cl]-1;
259  checkDim(num, ind_data+1, "num", false);
260  m_data.emplace_back(num[ind_data]);
261 
262  // if the size of the column_errors vector is 0, the columns of
263  // error values are the ones specified in input; if the error
264  // column is not present, the errors will be set to 1, by
265  // default
266  const size_t ind_error = (column_errors.size()==0) ? column_error_default-1 : column_errors[cl]-1;
267  if (num.size()<ind_error+1 && column_errors.size()>1)
268  WarningMsgCBL("the errors cannot be retrieved from the provided input file, and will be set to 1", "read", "Data1D.cpp");
269  m_error.emplace_back((num.size()<ind_error+1) ? 1 : num[ind_error]);
270 
271  // if the size of the column_edges vector is 0, the columns of
272  // bin edges values are the ones specified in input
273  const size_t ind_edges = (column_edges.size()==0) ? column_edges_default-1 : column_edges[cl]-1;
274  if (num.size()>ind_edges+1) {
275  dummy_edges_xx.emplace_back(num[ind_edges]);
276  last_bin_edge_xx = num[ind_edges+1];
277  }
278 
279  // if the size of the column_edges vector is 0, the columns of
280  // bin edges values are the ones specified in input
281  const size_t ind_edges_yy = (column_edges.size()==0) ? column_edges_default-1+2 : column_edges[cl]-1+2;
282  if (num.size()>ind_edges_yy+1) {
283  dummy_edges_yy.emplace_back(num[ind_edges_yy]);
284  last_bin_edge_yy = num[ind_edges_yy+1];
285  }
286 
287  }
288 
289  std::sort( dummy_edges_xx.begin(), dummy_edges_xx.end() );
290  dummy_edges_xx.erase( std::unique( dummy_edges_xx.begin(), dummy_edges_xx.end() ), dummy_edges_xx.end() );
291  std::sort( dummy_edges_yy.begin(), dummy_edges_yy.end() );
292  dummy_edges_yy.erase( std::unique( dummy_edges_yy.begin(), dummy_edges_yy.end() ), dummy_edges_yy.end() );
293 
294  for (size_t i=0; i<dummy_edges_xx.size(); i++)
295  m_edges_xx.emplace_back(dummy_edges_xx[i]);
296  m_edges_xx.emplace_back(last_bin_edge_xx);
297  for (size_t i=0; i<dummy_edges_yy.size(); i++)
298  m_edges_yy.emplace_back(dummy_edges_yy[i]);
299  m_edges_yy.emplace_back(last_bin_edge_yy);
300 
301  // go back at the beginning of the file
302  fin.clear(); fin.seekg(ios::beg);
303 
304  column_data_default += 2;
305  column_error_default += 2;
306  }
307 
308  fin.clear(); fin.close();
309 
310 
311  // set the data size and diagonal covariance
312 
313  unique_unsorted(m_x);
314  unique_unsorted(m_y);
315 
316  m_xsize = m_x.size();
317  m_ysize = m_y.size();
318  m_ndata = m_data.size();
319 
320  m_covariance.resize(m_ndata, vector<double>(m_ndata, 0));
321  for (int i=0; i<m_ndata; i++)
322  m_covariance[i][i] = pow(m_error[i], 2);
323 }
324 
325 
326 // ======================================================================================
327 
328 
329 void cbl::data::Data2D::Print (const int precision) const
330 {
331  for (int i=0; i<m_xsize; ++i)
332  for (int j=0; j<m_ysize; ++j) {
333  int index = j+m_ysize*i;
334  coutCBL << setprecision(precision) << setw(8) << right << m_x[i]
335  << " " << setprecision(precision) << setw(8) << right << m_y[j]
336  << " " << setprecision(precision) << setw(8) << right << m_data[index]
337  << " " << setprecision(precision) << setw(8) << right << m_error[index] << endl;
338  }
339 }
340 
341 
342 // ======================================================================================
343 
344 
345 void cbl::data::Data2D::write (const string dir, const string file, const string header, const bool full, const int prec, const int ww, const int rank) const
346 {
347  (void)rank;
348 
349  string file_out = dir+file;
350  ofstream fout(file_out.c_str()); checkIO(fout, file_out);
351 
352  if (header!=par::defaultString)
353  fout << "### " << header << " ###" << endl;
354 
355  const int bp = cout.precision();
356 
357  for (int i=0; i<m_xsize; ++i)
358  for (int j=0; j<m_ysize; ++j) {
359  int index = j+m_ysize*i;
360  cbl::Print(m_x[i], prec, ww, "", " ", false, fout);
361  cbl::Print(m_y[j], prec, ww, "", " ", false, fout);
362  cbl::Print(m_data[index], prec, ww, "", " ", false, fout);
363  cbl::Print(m_error[index], prec, ww, "", "\n", false, fout);
364  }
365 
366 
367  if (full) { // duplicate the information in the other 3 quadrants
368 
369  for (int i=0; i<m_xsize; ++i)
370  for (int j=0; j<m_ysize; ++j) {
371  int index = j+m_ysize*i;
372  cbl::Print(m_x[i], prec, ww, "", " ", false, fout);
373  cbl::Print(-m_y[j], prec, ww, "", " ", false, fout);
374  cbl::Print(m_data[index], prec, ww, "", " ", false, fout);
375  cbl::Print(m_error[index], prec, ww, "", "\n", false, fout);
376  }
377 
378  for (int i=0; i<m_xsize; ++i)
379  for (int j=0; j<m_ysize; ++j) {
380  int index = j+m_ysize*i;
381  cbl::Print(-m_x[i], prec, ww, "", " ", false, fout);
382  cbl::Print(-m_y[j], prec, ww, "", " ", false, fout);
383  cbl::Print(m_data[index], prec, ww, "", " ", false, fout);
384  cbl::Print(m_error[index], prec, ww, "", "\n", false, fout);
385  }
386 
387  for (int i=0; i<m_xsize; ++i)
388  for (int j=0; j<m_ysize; ++j) {
389  int index = j+m_ysize*i;
390  cbl::Print(-m_x[i], prec, ww, "", " ", false, fout);
391  cbl::Print(m_y[j], prec, ww, "", " ", false, fout);
392  cbl::Print(m_data[index], prec, ww, "", " ", false, fout);
393  cbl::Print(m_error[index], prec, ww, "", "\n", false, fout);
394  }
395 
396  }
397 
398  cout.precision(bp);
399  fout.close(); cout << endl; coutCBL << "I wrote the file: " << file_out << endl << endl;
400 }
401 
402 
403 // ======================================================================================
404 
405 
406 void cbl::data::Data2D::write_covariance (const string dir, const string file, const int precision) const
407 {
408  checkDim(m_covariance, m_ndata, m_ndata, "covariance", false);
409 
410  string file_out = dir+file;
411  ofstream fout(file_out.c_str()); checkIO(fout, file_out);
412 
413  fout << "### [1] r1 # [2] r2 # [3] r1 # [4] r2 # [5] covariance # [6] correlation # [7] index1 # [8] index2 ### " << endl;
414 
415  for (int i=0; i<m_xsize; ++i) {
416  for (int j=0; j<m_ysize; ++j) {
417  for (int k=0; k<m_xsize; ++k) {
418  for (int l=0; l<m_ysize; ++l) {
419  int index1 = j+m_ysize*i;
420  int index2 = l+m_ysize*k;
421  fout << setiosflags(ios::fixed) << setprecision(precision) << setw(15) << right << m_x[i]
422  << " " << setiosflags(ios::fixed) << setprecision(precision) << setw(15) << right << m_y[j]
423  << " " << setiosflags(ios::fixed) << setprecision(precision) << setw(15) << right << m_x[k]
424  << " " << setiosflags(ios::fixed) << setprecision(precision) << setw(15) << right << m_y[l]
425  << " " << setiosflags(ios::fixed) << setprecision(precision) << setw(15) << right << m_covariance[index1][index2]
426  << " " << setiosflags(ios::fixed) << setprecision(precision) << setw(15) << right << m_covariance[index1][index2]/sqrt(m_covariance[index1][index1]*m_covariance[index2][index2])
427  << " " << setiosflags(ios::fixed) << setprecision(precision) << setw(5) << right << index1
428  << " " << setiosflags(ios::fixed) << setprecision(precision) << setw(5) << right << index2 << endl;
429  }
430  }
431  }
432  }
433 
434  fout.close(); cout << endl; coutCBL << "I wrote the file: " << file_out << endl;
435 
436 }
437 
438 
439 // ======================================================================================
440 
441 
442 shared_ptr<Data> cbl::data::Data2D::cut (const double xmin, const double xmax, const double ymin, const double ymax) const
443 {
444  vector<bool> mask(m_ndata, true);
445  vector<double> xx, yy, edges_xx, edges_yy;
446 
447  for (int i=0; i<m_xsize; i++) {
448  for (int j=0; j<m_ysize; j++) {
449  if ( ((m_x[i] < xmin) || (m_x[i]>xmax)) || ((m_y[j] < ymin) || (m_y[j]>ymax)))
450  mask[j+m_ysize*i] = false;
451  }
452  }
453 
454  int last_index = 0;
455  for (int i=0; i<m_xsize; i++){
456  if ( !((m_x[i] < xmin) || (m_x[i]>xmax))){
457  xx.push_back(m_x[i]);
458  if (m_edges_xx.size()>0)
459  edges_xx.push_back(m_edges_xx[i]);
460  last_index = i;
461  }
462  }
463  if (m_edges_xx.size()>0)
464  edges_xx.push_back(m_edges_xx[last_index+1]);
465 
466  last_index = 0;
467  for (int i=0; i<m_ysize; i++){
468  if (!((m_y[i] < ymin) || (m_y[i]>ymax))){
469  yy.push_back(m_y[i]);
470  if (m_edges_yy.size()>0)
471  edges_yy.push_back(m_edges_yy[i]);
472  last_index = i;
473  }
474  }
475  if (m_edges_yy.size()>0)
476  edges_yy.push_back(m_edges_yy[last_index+1]);
477 
478  vector<double> data, error;
479  vector<vector<double>> covariance;
480  Data::cut(mask, data, error, covariance);
481 
482  shared_ptr<Data> dd = make_shared<Data2D>(Data2D(xx, yy, data, covariance, edges_xx, edges_yy));
483 
484  return dd;
485 }
486 
487 
488 // ======================================================================================
489 
490 
491 shared_ptr<Data> cbl::data::Data2D::as_factory ()
492 {
493  shared_ptr<Data> dd = make_shared<Data2D>(Data2D(m_x, m_data, m_covariance));
494 
495  return dd;
496 }
The class Data2D.
#define coutCBL
CBL print message.
Definition: Kernel.h:734
The class Data2D.
Definition: Data2D.h:51
int m_xsize
number of points along x
Definition: Data2D.h:66
void write_covariance(const std::string dir, const std::string file, const int precision=10) const override
write the covariance
Definition: Data2D.cpp:406
std::vector< double > m_y
ordered y axis points
Definition: Data2D.h:63
void write(const std::string dir, const std::string file, const std::string header, const bool full, const int prec=4, const int ww=8, const int rank=0) const
write the data
Definition: Data2D.cpp:345
std::vector< double > m_x
ordered x axis points
Definition: Data2D.h:60
Data2D()
default constructor
Definition: Data2D.h:83
std::shared_ptr< Data > cut(const double xmin, const double xmax, const double ymin, const double ymax) const
cut the data
Definition: Data2D.cpp:442
virtual void Print(const int precision=4) const override
print the data on screen
Definition: Data2D.cpp:329
void get_error(std::vector< std::vector< double >> &error) const override
get error
Definition: Data2D.cpp:187
int m_ysize
number of points along y
Definition: Data2D.h:69
virtual void read(const std::string input_file, const int skip_nlines=0, const std::vector< int > column={1, 2}, const std::vector< int > column_data={}, const std::vector< int > column_errors={}, const std::vector< int > column_edges={}) override
read the data
Definition: Data2D.cpp:201
std::shared_ptr< Data > as_factory()
static factory used to construct objects of class Data2D
Definition: Data2D.cpp:491
void get_data(std::vector< std::vector< double >> &data) const override
get data
Definition: Data2D.cpp:173
The class Data.
Definition: Data.h:89
std::vector< std::vector< double > > m_covariance
covariance matrix
Definition: Data.h:112
int m_ndata
number of data
Definition: Data.h:97
std::vector< double > m_edges_yy
bin edges for the y variable
Definition: Data.h:109
void cut(const std::vector< bool > mask, std::vector< double > &data, std::vector< double > &error, std::vector< std::vector< double >> &covariance_matrix) const
cut the dataset using a mask
Definition: Data.cpp:222
virtual std::vector< double > data() const
get data
Definition: Data.h:376
std::vector< double > m_error
standard deviations
Definition: Data.h:103
std::vector< double > m_data
data values
Definition: Data.h:100
std::vector< double > m_edges_xx
bin edges for the x variable
Definition: Data.h:106
virtual std::vector< double > error() const
get standard deviation
Definition: Data.h:389
static const char fINT[]
conversion symbol for: int -> std::string
Definition: Constants.h:121
static const std::string defaultString
default std::string value
Definition: Constants.h:336
static const double defaultDouble
default double value
Definition: Constants.h:348
DataType
the data type
Definition: Data.h:53
The global namespace of the CosmoBolognaLib
Definition: CAMB.h:38
std::string conv(const T val, const char *fact)
convert a number to a std::string
Definition: Kernel.h:903
void Print(const T value, const int prec, const int ww, const std::string header="", const std::string end="\n", const bool use_coutCBL=true, std::ostream &stream=std::cout, const std::string colour=cbl::par::col_default)
function to print values with a proper homegenised format
Definition: Kernel.h:1142
void checkDim(const std::vector< T > vect, const int val, const std::string vector, bool equal=true)
check if the dimension of a std::vector is equal/lower than an input value
Definition: Kernel.h:1532
void checkIO(const std::ifstream &fin, const std::string file="NULL")
check if an input file can be opened
Definition: Kernel.cpp:160
int ErrorCBL(const std::string msg, const std::string functionCBL, const std::string fileCBL, const cbl::glob::ExitCode exitCode=cbl::glob::ExitCode::_error_)
throw an exception: it is used for handling exceptions inside the CosmoBolognaLib
Definition: Kernel.h:780
void unique_unsorted(std::vector< int > &vv)
erase all the equal elements of the input std::vector
Definition: Kernel.cpp:284
void covariance_matrix(const std::vector< std::vector< double >> mat, std::vector< std::vector< double >> &cov, const bool JK=false)
compute the covariance matrix from an input dataset
Definition: Func.cpp:761
void WarningMsgCBL(const std::string msg, const std::string functionCBL, const std::string fileCBL)
internal CBL warning message
Definition: Kernel.h:747