Loading [MathJax]/extensions/tex2jax.js
PeTar
N-body code for collisional gravitational systems
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
io.hpp
Go to the documentation of this file.
1 #pragma once
2 #include <iostream>
3 #include <cstdio>
4 #include <cstring>
5 #include <iomanip>
6 #include <fstream>
7 #include <string>
8 #include <map>
9 
10 #define PRINT_WIDTH 15
11 #define PRINT_PRECISION 7
12 
13 // print format parameters
17  int width_key;
18 
19  IOParamsPrintHelp(const int _offset_short_key, const int _offset_long_key, const int _width_key):
20  offset_short_key(_offset_short_key), offset_long_key(_offset_long_key), width_key(_width_key) {}
21 
22  static void printTypeShortNameDescription(std::ostream& os) {
23  os<<"I: 64bit integer; F: 64bit floating; S: string\n";
24  }
25 
26  static char getValueTypeShortName(const long long int& value) {
27  return 'I';
28  }
29 
30  static char getValueTypeShortName(const double& value) {
31  return 'F';
32  }
33 
34  static char getValueTypeShortName(const std::string& value) {
35  return 'S';
36  }
37 };
38 
39 
40 // IO Params
41 template <class Type>
42 struct IOParams{
43  Type value;
44  const char* key;
45  const char* name;
46  const char* defaulted;
48 
49  template <class TContainer>
50  IOParams(TContainer& _ioc, const Type& _value, const char* _key, const char* _name, const char* _defaulted=NULL, const bool _print_help_flag=true): value(_value), key(_key), name(_name), defaulted(_defaulted), print_help_flag(_print_help_flag) {
51  _ioc.store(_key, this);
52  }
53 
54  void print(std::ostream& os) const{
55  os<<name<<": "<<value<<std::endl;
56  }
57 
58  void printHelp(std::ostream& os, const IOParamsPrintHelp& _align) const {
59  if (print_help_flag) {
60  //key
61  if (strlen(key)==1) {
62  os<<std::setw(_align.offset_short_key)<<"-"<<key<<" ";
63  }
64  else {
65  os<<std::setw(_align.offset_long_key)<<"--"
66  <<std::left<<std::setw(_align.width_key)<<key<<std::right;
67  }
68  os<<"["<<IOParamsPrintHelp::getValueTypeShortName(value)<<"] " // type
69  <<*this<<std::endl; // description
70  }
71  }
72 };
73 
74 template <class Type>
75 std::ostream& operator <<(std::ostream& os, const IOParams<Type>& par) {
76  if (par.defaulted!=NULL) os<<par.name<<": "<<par.defaulted;
77  else os<<par.name<<": "<<par.value;
78  return os;
79 }
80 
83  struct char_cmp {
84  bool operator () (const char *a,const char *b) const {
85  return strcmp(a,b)<0;
86  }
87  };
88  std::map<const char*, IOParams<double>*, char_cmp> d_f64;
89  std::map<const char*, IOParams<long long int>*, char_cmp> d_i64;
90  std::map<const char*, IOParams<std::string>*, char_cmp> d_str;
91 
92 public:
93 
94  void store(const char* _name, IOParams<double>* _item) {
95  d_f64[_name] = _item;
96  }
97 
98  void store(const char* _name, IOParams<long long int>* _item) {
99  d_i64[_name] = _item;
100  }
101 
102  void store(const char* _name, IOParams<std::string>* _item) {
103  d_str[_name] = _item;
104  }
105 
106  void writeAscii(FILE *_fout) {
107  for(auto iter = d_f64.begin(); iter!=d_f64.end(); iter++) fprintf(_fout, "%c %s %26.15e\n", IOParamsPrintHelp::getValueTypeShortName(iter->second->value), iter->first, iter->second->value);
108  for(auto iter = d_i64.begin(); iter!=d_i64.end(); iter++) fprintf(_fout, "%c %s %lld\n", IOParamsPrintHelp::getValueTypeShortName(iter->second->value), iter->first, iter->second->value);
109  for(auto iter = d_str.begin(); iter!=d_str.end(); iter++) fprintf(_fout, "%c %s %s\n", IOParamsPrintHelp::getValueTypeShortName(iter->second->value), iter->first, iter->second->value.c_str());
110  }
111 
112  void readAscii(FILE *_fin) {
113 
114  char key_name[1024];
115  while (!feof(_fin)) {
116  size_t rcount=0;
117  char type_id;
118  rcount=fscanf(_fin, "%c ", &type_id);
119  if (rcount<1) {
120  std::cerr<<"Error: Data reading fails! requiring data number is 1, only obtain "<<rcount<<".\n";
121  abort();
122  }
123 
124  switch (type_id) {
125  case 'F':
126  {
127  double dtmp;
128  rcount=fscanf(_fin, "%s %lf\n", key_name, &dtmp);
129  if (rcount<2) {
130  std::cerr<<"Error: Data reading fails! requiring data number is 2, only obtain "<<rcount<<".\n";
131  abort();
132  }
133  auto search = d_f64.find(key_name);
134  if (search == d_f64.end())
135  std::cerr<<"Warning: parameter name key "<<key_name<<" is not found!\n";
136  else
137  search->second->value = dtmp;
138  break;
139  }
140  case 'I':
141  {
142  long long int dtmp;
143  rcount=fscanf(_fin, "%s %lld\n", key_name, &dtmp);
144  if (rcount<2) {
145  std::cerr<<"Error: Data reading fails! requiring data number is 2, only obtain "<<rcount<<".\n";
146  abort();
147  }
148  auto search = d_i64.find(key_name);
149  if (search == d_i64.end())
150  std::cerr<<"Warning: parameter name key "<<key_name<<" is not found!\n";
151  else
152  search->second->value = dtmp;
153  break;
154  }
155  case 'S':
156  {
157  char dtmp[1024];
158  rcount=fscanf(_fin, "%s %s\n", key_name, dtmp);
159  if (rcount<2) {
160  std::cerr<<"Error: Data reading fails! requiring data number is 2, only obtain "<<rcount<<".\n";
161  abort();
162  }
163  auto search = d_str.find(key_name);
164  if (search == d_str.end())
165  std::cerr<<"Warning: parameter name key "<<key_name<<" is not found!\n";
166  else
167  search->second->value = dtmp;
168  break;
169  }
170  default:
171  std::cerr<<"Warning: parameter type not found, given "<<type_id<<", should be one of F, L, I, S\n";
172  break;
173  }
174  }
175  }
176 
177 #ifdef PARTICLE_SIMULATOR_MPI_PARALLEL
178  void mpi_broadcast() {
179  for(auto iter=d_f64.begin(); iter!=d_f64.end(); iter++) PS::Comm::broadcast(&(iter->second->value), 1, 0);
180  for(auto iter=d_i64.begin(); iter!=d_i64.end(); iter++) PS::Comm::broadcast(&(iter->second->value), 1, 0);
181  for(auto iter=d_str.begin(); iter!=d_str.end(); iter++) {
182  size_t str_size=iter->second->value.size();
183  PS::Comm::broadcast(&str_size, 1, 0);
184  char stmp[str_size+1];
185  std::strcpy(stmp, iter->second->value.c_str());
186  PS::Comm::broadcast(stmp, str_size, 0);
187  iter->second->value = std::string(stmp);
188  }
189  }
190 #endif
191 
192  void print(std::ostream& os) const{
193  for(auto iter=d_f64.begin(); iter!=d_f64.end(); iter++) os<<iter->first<<": "<<iter->second->value<<std::endl;
194  for(auto iter=d_i64.begin(); iter!=d_i64.end(); iter++) os<<iter->first<<": "<<iter->second->value<<std::endl;
195  for(auto iter=d_str.begin(); iter!=d_str.end(); iter++) os<<iter->first<<": "<<iter->second->value<<std::endl;
196  }
197 
198  void printHelp(std::ostream& os, const int _offset_short_key=2, const int _offset_long_key=1, const int _width_key=23) const{
199  IOParamsPrintHelp print_help(_offset_short_key, _offset_long_key, _width_key);
200  std::cout<<" default values are shown after ':'\n"
201  <<" the char in [] indicates argument type: ";
202  print_help.printTypeShortNameDescription(std::cout);
203  for(auto iter=d_f64.begin(); iter!=d_f64.end(); iter++) iter->second->printHelp(os, print_help);
204  for(auto iter=d_i64.begin(); iter!=d_i64.end(); iter++) iter->second->printHelp(os, print_help);
205  for(auto iter=d_str.begin(); iter!=d_str.end(); iter++) iter->second->printHelp(os, print_help);
206  }
207 };
208 
209 
211 public:
212  long long int nfile; // file id
213  long long int n_body;
214  double time;
215 #ifdef RECORD_CM_IN_HEADER
216  PS::F64vec pos_offset;
217  PS::F64vec vel_offset;
218 #endif
220  n_body = 0;
221  time = 0.0;
222 #ifdef RECORD_CM_IN_HEADER
223  pos_offset = PS::F64vec(0.0);
224  vel_offset = PS::F64vec(0.0);
225 #endif
226  }
227 #ifdef RECORD_CM_IN_HEADER
228  FileHeader(const long long int ni, const long long int n, const double t, const PS::F64vec& pos, const PS::F64vec& vel){
229  nfile = ni;
230  n_body = n;
231  time = t;
232  pos_offset = pos;
233  vel_offset = vel;
234  }
235  int readAscii(FILE * fp){
236  int rcount=fscanf(fp, "%lld %lld %lf %lf %lf %lf %lf %lf %lf\n", &nfile, &n_body, &time, &pos_offset.x,&pos_offset.y, &pos_offset.z, &vel_offset.x, &vel_offset.y, &vel_offset.z);
237  if (rcount<9) {
238  std::cerr<<"Error: cannot read header, please check your data file header!\n";
239  abort();
240  }
241  //std::cout<<"Number of particles ="<<n_body<<"; Time="<<time<<std::endl;
242  return n_body;
243  }
244 
245  void writeAscii(FILE* fp) const{
246  fprintf(fp, "%lld %lld %26.17e %26.17e %26.17e %26.17e %26.17e %26.17e %26.17e\n", nfile, n_body, time, pos_offset.x, pos_offset.y, pos_offset.z, vel_offset.x, vel_offset.y, vel_offset.z);
247  }
248 #else
249  FileHeader(const long long int ni, const long long int n, const double t) {
250  nfile = ni;
251  n_body = n;
252  time = t;
253  }
254 
255  int readAscii(FILE * fp){
256  int rcount=fscanf(fp, "%lld %lld %lf\n", &nfile, &n_body, &time);
257  if (rcount<3) {
258  std::cerr<<"Error: cannot read header, please check your data file header!\n";
259  abort();
260  }
261  //std::cout<<"Number of particles ="<<n_body<<"; Time="<<time<<std::endl;
262  return n_body;
263  }
264 
265  void writeAscii(FILE* fp) const{
266  fprintf(fp, "%lld %lld %26.17e\n", nfile, n_body, time);
267  }
268 #endif
269  int readBinary(FILE* fp){
270  size_t rcount=fread(this, sizeof(FileHeader), 1, fp);
271  if(rcount<1) {
272  std::cerr<<"Error: Data reading fails! requiring data number is "<<1<<" bytes, only obtain "<<rcount<<" bytes.\n";
273  abort();
274  }
275  //std::cout<<"Number of particles ="<<n_body<<"; Time="<<time<<std::endl;
276  return n_body;
277  }
278 
279  void writeBinary(FILE* fp) const{
280  fwrite(this, sizeof(FileHeader), 1, fp);
281  }
282 };
FileHeader::n_body
long long int n_body
Definition: io.hpp:213
IOParamsPrintHelp::printTypeShortNameDescription
static void printTypeShortNameDescription(std::ostream &os)
Definition: io.hpp:22
IOParams::value
Type value
Definition: io.hpp:43
IOParams::printHelp
void printHelp(std::ostream &os, const IOParamsPrintHelp &_align) const
Definition: io.hpp:58
IOParamsPrintHelp::getValueTypeShortName
static char getValueTypeShortName(const std::string &value)
Definition: io.hpp:34
IOParamsContainer::print
void print(std::ostream &os) const
Definition: io.hpp:192
IOParamsContainer::store
void store(const char *_name, IOParams< std::string > *_item)
Definition: io.hpp:102
galpy_pot_movie.fp
fp
Definition: galpy_pot_movie.py:131
FileHeader::time
double time
Definition: io.hpp:214
PIKG::F64vec
Vector3< F64 > F64vec
Definition: pikg_vector.hpp:167
IOParamsContainer::readAscii
void readAscii(FILE *_fin)
Definition: io.hpp:112
IOParamsContainer::printHelp
void printHelp(std::ostream &os, const int _offset_short_key=2, const int _offset_long_key=1, const int _width_key=23) const
Definition: io.hpp:198
FileHeader::FileHeader
FileHeader(const long long int ni, const long long int n, const double t)
Definition: io.hpp:249
IOParamsPrintHelp::width_key
int width_key
Definition: io.hpp:17
operator<<
std::ostream & operator<<(std::ostream &os, const IOParams< Type > &par)
Definition: io.hpp:75
IOParamsPrintHelp
Definition: io.hpp:14
IOParams::name
const char * name
Definition: io.hpp:45
IOParams::print
void print(std::ostream &os) const
Definition: io.hpp:54
FileHeader::readBinary
int readBinary(FILE *fp)
Definition: io.hpp:269
IOParamsPrintHelp::offset_long_key
int offset_long_key
Definition: io.hpp:16
IOParams::key
const char * key
Definition: io.hpp:44
FileHeader::writeAscii
void writeAscii(FILE *fp) const
Definition: io.hpp:265
IOParamsContainer::store
void store(const char *_name, IOParams< double > *_item)
Definition: io.hpp:94
IOParamsPrintHelp::getValueTypeShortName
static char getValueTypeShortName(const double &value)
Definition: io.hpp:30
IOParams::defaulted
const char * defaulted
Definition: io.hpp:46
IOParamsContainer::writeAscii
void writeAscii(FILE *_fout)
Definition: io.hpp:106
IOParams::print_help_flag
bool print_help_flag
Definition: io.hpp:47
IOParams
Definition: io.hpp:42
FileHeader::FileHeader
FileHeader()
Definition: io.hpp:219
IOParamsPrintHelp::getValueTypeShortName
static char getValueTypeShortName(const long long int &value)
Definition: io.hpp:26
IOParamsContainer::store
void store(const char *_name, IOParams< long long int > *_item)
Definition: io.hpp:98
IOParams::IOParams
IOParams(TContainer &_ioc, const Type &_value, const char *_key, const char *_name, const char *_defaulted=NULL, const bool _print_help_flag=true)
Definition: io.hpp:50
FileHeader::nfile
long long int nfile
Definition: io.hpp:212
IOParamsPrintHelp::IOParamsPrintHelp
IOParamsPrintHelp(const int _offset_short_key, const int _offset_long_key, const int _width_key)
Definition: io.hpp:19
FileHeader::readAscii
int readAscii(FILE *fp)
Definition: io.hpp:255
FileHeader::writeBinary
void writeBinary(FILE *fp) const
Definition: io.hpp:279
FileHeader
Definition: io.hpp:210
IOParamsContainer
IO Params container.
Definition: io.hpp:82
IOParamsPrintHelp::offset_short_key
int offset_short_key
Definition: io.hpp:15