CosmoBolognaLib
Free Software C++/Python libraries for cosmological calculations
Kernel.cpp
Go to the documentation of this file.
1 /*******************************************************************
2  * Copyright (C) 2010 by Federico Marulli *
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 "Kernel.h"
35 
36 using namespace std;
37 
38 using namespace cbl;
39 using namespace glob;
40 
41 
42 // ============================================================================================
43 
44 
45 short cbl::ShortSwap (const short s)
46 {
47  unsigned char b1, b2;
48  b1 = s & 255;
49  b2 = (s>>8) & 255;
50  return (b1<<8) + b2;
51 }
52 
53 
54 // ============================================================================================
55 
56 
57 int cbl::IntSwap (const int i)
58 {
59  unsigned char b1, b2, b3, b4;
60  b1 = i & 255;
61  b2 = (i>>8) & 255;
62  b3 = (i>>16) & 255;
63  b4 = (i>>24) & 255;
64  return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
65 }
66 
67 
68 // ============================================================================================
69 
70 
71 long long cbl::LongSwap (const long long i)
72 {
73  unsigned char b1, b2, b3, b4, b5, b6, b7, b8;
74  b1 = i & 255;
75  b2 = (i>>8) & 255;
76  b3 = (i>>16) & 255;
77  b4 = (i>>24) & 255;
78  b5 = (i>>32) & 255;
79  b6 = (i>>40) & 255;
80  b7 = (i>>48) & 255;
81  b8 = (i>>56) & 255;
82  return ((long long)b1<<56) + ((long long)b2<<48) + ((long long)b3<<40) + ((long long)b4<<32) + ((long long)b5<<24) + ((long long)b6<<16) + ((long long)b7<<8) + b8;
83 }
84 
85 
86 // ============================================================================================
87 
88 
89 float cbl::FloatSwap (const float f)
90 {
91  union {
92  float f;
93  unsigned char b[4];
94  } dat1, dat2;
95 
96  dat1.f = f;
97  dat2.b[0] = dat1.b[3];
98  dat2.b[1] = dat1.b[2];
99  dat2.b[2] = dat1.b[1];
100  dat2.b[3] = dat1.b[0];
101 
102  return dat2.f;
103 }
104 
105 
106 // ============================================================================================
107 
108 
109 double cbl::DoubleSwap (const double d)
110 {
111  union {
112  double d;
113  unsigned char b[8];
114  } dat1, dat2;
115 
116  dat1.d = d;
117  dat2.b[0] = dat1.b[7];
118  dat2.b[1] = dat1.b[6];
119  dat2.b[2] = dat1.b[5];
120  dat2.b[3] = dat1.b[4];
121  dat2.b[4] = dat1.b[3];
122  dat2.b[5] = dat1.b[2];
123  dat2.b[6] = dat1.b[1];
124  dat2.b[7] = dat1.b[0];
125 
126  return dat2.d;
127 }
128 
129 
130 // ============================================================================================
131 
132 
133 double cbl::round_to_digits (const double num, const int ndigits)
134 {
135  int exp_base10 = round(log10(num));
136  double man_base10 = num*pow(10., -exp_base10);
137  double factor = pow(10., -ndigits+1);
138  double truncated_man_base10 = man_base10-fmod(man_base10, factor);
139  double rounded_remainder = fmod(man_base10, factor)/factor;
140 
141  rounded_remainder = rounded_remainder > 0.5 ? 1.0*factor : 0.0;
142 
143  return (truncated_man_base10+rounded_remainder)*pow(10.0, exp_base10);
144 }
145 
146 
147 // ============================================================================================
148 
149 
150 double cbl::round_to_precision (const double num, const int ndigits)
151 {
152  const double tenth = pow(10., ndigits);
153  return floor(num*tenth)/tenth;
154 }
155 
156 
157 // ============================================================================
158 
159 
160 void cbl::checkIO (const std::ifstream &fin, const std::string file)
161 {
162  if (fin.fail()) {
163  string Err = "Error in opening the input file";
164  if (file!="NULL") Err += ": " + file;
165  ErrorCBL(Err, "checkIO", "Kernel.cpp", ExitCode::_IO_);
166  }
167 }
168 
169 
170 // ============================================================================
171 
172 
173 void cbl::checkIO (const std::ofstream &fout, const std::string file)
174 {
175  if (fout.fail()) {
176  string Err = "Error in opening the output file";
177  if (file!="NULL") Err += ": " + file;
178  ErrorCBL(Err, "checkIO", "Kernel.cpp", ExitCode::_IO_);
179  }
180 }
181 
182 
183 // ============================================================================================
184 
185 
186 void cbl::set_EnvVar (std::vector<std::string> Var)
187 {
188  for (size_t vv=0; vv<Var.size(); vv++)
189  putenv(&Var[0][0]);
190 }
191 
192 
193 // ============================================================================================
194 
195 
196 void cbl::check_EnvVar (const std::string Var)
197 {
198  string COM = "if [ $"+Var+" ]; then touch tmp; fi";
199  if (system (COM.c_str())) {};
200  ifstream fin_check("tmp");
201  if (!fin_check)
202  WarningMsgCBL("the variable " + Var + " has not been defined!", "check_EnvVar", "Kenrel.cpp");
203  fin_check.clear(); fin_check.close();
204  if (system("rm -f tmp")) {};
205 }
206 
207 
208 // ============================================================================================
209 
210 
211 int cbl::used_memory (const int type)
212 {
213 #ifdef LINUX
214  int memory = -1;
215 
216  string mem;
217  if (type==1) mem = "VmRSS:";
218  else if (type==2) mem = "VmSize:";
219  else ErrorCBL("the input value of type is not allowed!", "used_memory", "Kernel.cpp");
220 
221  string file = "/proc/self/status";
222  ifstream fin(file.c_str()); checkIO(fin, file);
223 
224  string line, aa;
225  while (getline(fin, line)) {
226  stringstream ss(line);
227  vector<string> val;
228  while (ss>>aa) val.push_back(aa);
229  if (val.size()==3 && val[0]==mem) {
230  memory = atoi(val[1].c_str());
231  break;
232  }
233  }
234 
235  fin.clear(); fin.close();
236 
237  return memory;
238 
239 #else
240  (void)type;
241  //WarningMsgCBL("this function works only on Linux systems", "used_memory", "Kernel.cpp");
242  return 1;
243 
244 #endif
245 
246 }
247 
248 
249 // ============================================================================
250 
251 
252 int cbl::check_memory (const double frac, const bool exit, const std::string func, const int type)
253 {
254 #ifdef LINUX
255  struct sysinfo memInfo;
256  sysinfo (&memInfo);
257 
258  long long freePhysMem = memInfo.freeram;
259  freePhysMem *= memInfo.mem_unit;
260  int used = used_memory(type);
261 
262  if (used > freePhysMem*0.001*frac) { // 0.001 is to convert kbytes in bytes
263  string Err = "possible memory problem";
264  Err += (func.empty()) ? "!\n" : " in "+func+" !\n";
265  Err += "freePhysMem = "+conv((double)freePhysMem*1.e-9, par::fDP3)+" GB\n";
266  Err += "memory used by the process: = "+conv((double)used*1.e-6, par::fDP3)+" GB\n";
267  if (exit) ErrorCBL(Err, "check_memory", "Kernel.cpp");
268  else { WarningMsgCBL(Err, "check_memory", "Kernel.cpp"); return 0; }
269  }
270  return 1;
271 
272 #else
273  (void)frac; (void)exit; (void)func; (void)type;
274  //WarningMsgCBL("this function works only on Linux systems", "checked_memory", "Kernel.cpp");
275  return 1;
276 
277 #endif
278 }
279 
280 
281 // ============================================================================
282 
283 
284 void cbl::unique_unsorted (std::vector<int> &vv) // erase all equal elements
285 {
286  sort(vv.begin(),vv.end());
287  vector<int>::iterator it;
288  it = unique(vv.begin(),vv.end());
289  vv.resize(it-vv.begin());
290 }
291 
292 
293 // ============================================================================
294 
295 
296 void cbl::unique_unsorted (std::vector<double> &vv) // erase all equal elements
297 {
298  sort(vv.begin(),vv.end());
299  vector<double>::iterator it;
300  it = unique(vv.begin(),vv.end());
301  vv.resize(it-vv.begin());
302 }
303 
304 
305 // ============================================================================
306 
307 
308 void cbl::unique_unsorted (std::vector<std::string> &vv) // erase all equal elements
309 {
310  sort(vv.begin(),vv.end());
311  vector<string>::iterator it;
312  it = unique(vv.begin(),vv.end());
313  vv.resize(it-vv.begin());
314 }
315 
316 
317 // ============================================================================
318 
320 bool cbl::glob::operator<(const cbl::glob::CL &c1, const cbl::glob::CL &c2) {return c1.VV[0] < c2.VV[0];}
322 
323 void cbl::sort_2vectors (std::vector<double>::iterator p1, std::vector<double>::iterator p2, const int dim)
324 {
325  int temp = 0;
326  vector<cbl::glob::CL> ccc;
327  for (int i=0; i<dim; i++) {
328  vector<double> vect = {*p1, *p2};
329  cbl::glob::CL cl(vect);
330  ccc.push_back(cl);
331  if (i+1<dim) {*p1 ++; *p2 ++; temp ++;}
332  }
333  sort (ccc.begin(),ccc.end());
334  p1 -= temp; p2 -= temp;
335  for (int i=0; i<dim; i++) {
336  *p1 = ccc[i].VV[0]; *p2 = ccc[i].VV[1];
337  if (i+1<dim) {*p1 ++; *p2 ++;}
338  }
339 }
340 
341 void cbl::sort_3vectors (std::vector<double>::iterator p1, std::vector<double>::iterator p2, std::vector<double>::iterator p3, const int dim)
342 {
343  int temp = 0;
344  vector<cbl::glob::CL> ccc;
345  for (int i=0; i<dim; i++) {
346  vector<double> vect = {*p1, *p2, *p3};
347  cbl::glob::CL cl(vect);
348  ccc.push_back(cl);
349  if (i+1<dim) {*p1 ++; *p2 ++; *p3 ++; temp ++;}
350  }
351  sort (ccc.begin(),ccc.end());
352  p1 -= temp; p2 -= temp; p3 -= temp;
353  for (int i=0; i<dim; i++) {
354  *p1 = ccc[i].VV[0]; *p2 = ccc[i].VV[1]; *p3 = ccc[i].VV[2];
355  if (i+1<dim) {*p1 ++; *p2 ++; *p3 ++;}
356  }
357 }
358 
359 void cbl::sort_4vectors (std::vector<double>::iterator p1, std::vector<double>::iterator p2, std::vector<double>::iterator p3, std::vector<double>::iterator p4, const int dim)
360 {
361  int temp = 0;
362  vector<cbl::glob::CL> ccc;
363  for (int i=0; i<dim; i++) {
364  vector<double> vect = {*p1, *p2, *p3, *p4};
365  cbl::glob::CL cl(vect);
366  ccc.push_back(cl);
367  if (i+1<dim) {*p1 ++; *p2 ++; *p3 ++; *p4 ++; temp ++;}
368  }
369  sort (ccc.begin(),ccc.end());
370  p1 -= temp; p2 -= temp; p3 -= temp; p4 -= temp;
371  for (int i=0; i<dim; i++) {
372  *p1 = ccc[i].VV[0]; *p2 = ccc[i].VV[1]; *p3 = ccc[i].VV[2]; *p4 = ccc[i].VV[3];
373  if (i+1<dim) {*p1 ++; *p2 ++; *p3 ++; *p4 ++;}
374  }
375 }
376 
377 
378 // ============================================================================
379 
380 
381 int cbl::makeDir (std::string path, const std::string rootPath, const mode_t mode, const bool verbose)
382 {
383  struct stat st;
384 
385  for (string::iterator iter=path.begin(); iter!=path.end();) {
386  string::iterator newIter = find(iter, path.end(), '/');
387  string newPath = rootPath+"/"+string(path.begin(), newIter);
388 
389  if (stat(newPath.c_str(), &st)!=0) {
390  if (mkdir(newPath.c_str(), mode)!=0 && errno!=EEXIST)
391  return ErrorCBL("cannot create the directory "+newPath+strerror(errno), "makeDir", "Kernel.cpp");
392  }
393  else
394  if (!S_ISDIR(st.st_mode)) {
395  errno = ENOTDIR;
396  return ErrorCBL(newPath+" is not a directory", "makeDir", "Kernel.cpp");
397  }
398  else if (verbose)
399  WarningMsgCBL(newPath+" already exists", "makeDir", "Kernel.cpp");
400 
401  iter = newIter;
402  if (newIter!=path.end()) ++iter;
403  }
404 
405  return 0;
406 }
407 
408 // ============================================================================
409 
410 std::vector<std::vector<double>> cbl::read_file (const std::string file_name, const std::string path_name, const std::vector<int> column_data, const int skip_nlines)
411 {
412  const string input_file (path_name+file_name);
413  const int cl_max = column_data.size();
414 
415  ifstream fin(input_file.c_str()); checkIO(fin, input_file);
416  string line;
417 
418  // get the number of lines to read
419  unsigned int n_lines = 0;
420  while(getline(fin, line)) n_lines++;
421  n_lines-=skip_nlines;
422 
423  fin.clear(); fin.close();
424 
425  // vector of vectors to return
426  vector<vector<double>> final_data(cl_max, vector<double>(n_lines, 0));
427 
428 #pragma omp parallel num_threads(cl_max>omp_get_max_threads() ? omp_get_max_threads() : cl_max)
429  {
430  // loop on the columns to read
431 #pragma omp for schedule(dynamic)
432  for (int cl=0; cl<cl_max; ++cl) {
433 
434  // share ifstream between the CPUs
435  ifstream Fin (input_file);
436  string Line;
437 
438  if (skip_nlines>0)
439  for (int i=0; i<skip_nlines; ++i)
440  getline(Fin, Line);
441 
442 
443  // read the file lines
444  for (unsigned int nn=0; nn<n_lines; ++nn) {
445 
446  getline(Fin, Line);
447  stringstream ss(Line);
448  vector<double> num; double NUM;
449  while (ss>>NUM) num.emplace_back(NUM);
450 
451  // store the data
452  final_data[cl][nn] = num[column_data[cl]-1];
453  }
454 
455  Fin.clear(); Fin.close();
456  }
457  }
458 
459  return final_data;
460 }
461 
462 // ============================================================================
463 
464 std::vector<std::vector<double>> cbl::read_file (const std::string file_name, const std::string path_name, const std::vector<int> column_data, const std::string delimiter, const char comment)
465 {
466  std::ifstream file_input(path_name+file_name.c_str(),std::ios::in); checkIO(file_input, path_name+file_name);
467  std::string line;
468  int line_count = 0;
469  while (!file_input.eof())
470  {
471  std::getline(file_input,line);
472  line_count++;
473  }
474  line_count --; // it counts one more
475  file_input.clear(); file_input.seekg(0, std::ios::beg);
476 
477  std::vector<std::vector<double>> read_data(column_data.size(), std::vector<double>());
478  std::vector<std::string> temp(1000); // The max number (now it's 1000) must be generalised according to file columns
479  for (int i=0; i<line_count; i++){
480  getline(file_input,line);
481  if (line.at(0) != comment){
482  int line_pos = 0;
483  int vector_ind = 0;
484  while (line.find(delimiter) != std::string::npos){
485  line_pos = line.find(delimiter);
486  temp[vector_ind] = line.substr(0, line_pos);
487  line.erase(0, line_pos + delimiter.length());
488  vector_ind++;
489  }
490  // I save also the last part of string
491  temp[vector_ind] = line.substr(0, line_pos);
492  line.erase(0, line_pos + delimiter.length());
493 
494  for (size_t i=0; i<read_data.size(); i++){
495  read_data[i].emplace_back(std::stod(temp[column_data[i]]));
496  }
497  }
498  }
499 
500  return read_data;
501 }
Useful generic functions.
static const char fDP3[]
conversion symbol for: double -> std::string
Definition: Constants.h:136
Var
the catalogue variables
Definition: Catalogue.h:70
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
std::vector< std::vector< double > > read_file(const std::string file_name, const std::string path_name, const std::vector< int > column_data, const int skip_nlines=0)
read a data from a file ASCII
Definition: Kernel.cpp:410
void checkIO(const std::ifstream &fin, const std::string file="NULL")
check if an input file can be opened
Definition: Kernel.cpp:160
void sort_4vectors(std::vector< double >::iterator p1, std::vector< double >::iterator p2, std::vector< double >::iterator p3, std::vector< double >::iterator p4, const int dim)
sort the elements of a std::vectors, and the elements of three other std::vectors according to the fi...
Definition: Kernel.cpp:359
int used_memory(const int type)
get the memory used by current process in kB
Definition: Kernel.cpp:211
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 set_EnvVar(const std::vector< std::string > Var)
set evironment variables
Definition: Kernel.cpp:186
short ShortSwap(const short s)
endian conversion of a short variable
Definition: Kernel.cpp:45
double round_to_digits(const double num, const int ndigits)
reduce the digit figures of an input double
Definition: Kernel.cpp:133
double DoubleSwap(const double d)
endian conversion of a double variable
Definition: Kernel.cpp:109
void sort_2vectors(std::vector< double >::iterator p1, std::vector< double >::iterator p2, const int dim)
sort the elements of a std::vectors, and the elements of a second std::vector according to the first ...
Definition: Kernel.cpp:323
void WarningMsgCBL(const std::string msg, const std::string functionCBL, const std::string fileCBL)
internal CBL warning message
Definition: Kernel.h:747
long long LongSwap(const long long i)
endian conversion of a long integer variable
Definition: Kernel.cpp:71
int check_memory(const double frac, const bool exit=true, const std::string func="", const int type=1)
check if the memory used by current process is larger than a given fraction of the available memory
Definition: Kernel.cpp:252
void check_EnvVar(const std::string Var)
check if an environment variable exists
Definition: Kernel.cpp:196
float FloatSwap(const float f)
endian conversion of a float variable
Definition: Kernel.cpp:89
double round_to_precision(const double num, const int ndigits)
reduce the precision of an input double
Definition: Kernel.cpp:150
int makeDir(std::string path, const std::string rootPath=".", const mode_t mode=0777, const bool verbose=false)
function to create multiple directories
Definition: Kernel.cpp:381
void sort_3vectors(std::vector< double >::iterator p1, std::vector< double >::iterator p2, std::vector< double >::iterator p3, const int dim)
sort the elements of a std::vectors, and the elements of two other std::vectors according to the firs...
Definition: Kernel.cpp:341
int IntSwap(const int i)
endian conversion of an integer variable
Definition: Kernel.cpp:57