Gateau User Manual
Atmospheric simulation of astronomical signals
fio.h
Go to the documentation of this file.
1 /*! \file fio.h
2  * \brief File input/output operations.
3  **/
4 
5 #include <iostream>
6 #include <iomanip>
7 #include <cmath>
8 #include <fstream>
9 #include <string>
10 #include <sstream>
11 #include <filesystem>
12 
13 #include "hdf5.h"
14 
15 #include "structs.h"
16 
17 #ifndef __FILEIO_H
18 #define __FILEIO_H
19 
20 namespace fs = std::filesystem;
21 
22 #define NPWVATM 55
23 #define NFREQ 8301
24 #define NATMGRID 3
25 #define COLBUFF 16
26 #define FMTBUFF 4
27 
28 #define OBSATTRS_NAME "OBSATTRS"
29 #define SPAX_NAME "SPAXEL"
30 #define NSPAX_NAME "num_spax"
31 #define FREQS_NAME "frequencies"
32 #define ETA_AP_NAME "eta_ap"
33 #define TIME_NAME "times"
34 #define AZ_NAME "az"
35 #define EL_NAME "el"
36 #define PWV_NAME "pwv"
37 
38 #define AZ_SPAX_NAME "az_spax"
39 #define EL_SPAX_NAME "el_spax"
40 #define OUT_NAME "data"
41 
42 #define CHBUFF 100
43 #define RANK1D 1
44 #define RANK2D 2
45 
46 void readAtmMeta(int **meta, std::string path);
47 
48 template <typename T, typename U>
49 void readEtaATM(
50  T **eta_array,
51  U *pwv_atm,
52  U *freq_atm
53  );
54 
55 template <typename T, typename U>
56 void readAtmScreen(
57  T **PWV_screen,
58  U *x_spec,
59  U *y_spec,
60  std::string path,
61  std::string datp
62  );
63 
64 class OutputFile
65 {
66  private:
67  const char *filename;
68 
69  // Handles for hdf5 file and groups
70  hid_t file_id;
71  hid_t obsattrs_id;
72  hid_t spax_id;
73 
74  // Handles for hdf5 dataspace/set creation
75  // Special one for PWV because its easier
76  hid_t dspace_id, dspace_pwv_id, dspace_slab_id, dspace_pwv_slab_id, dset_id, dset_pwv_id;
77 
78  // Output dimensions
79  hsize_t dims_1D[RANK1D],
80  dims_2D[RANK2D],
81  dims_2D_chunk[RANK2D],
82  dims_2D_stride[RANK2D];
83 
84  hsize_t dims_2D_null[2] = {0,0};
85 
86  // Hyperslab dimensions
87  hsize_t start[2], count[2], start_pink[2], count_pink[2], start_pwv[1], count_pwv[1];
88 
89  int ntimes, nfreqs;
90  int offset_times = 0;
91  int offset_freqs = 0;
92  int offset_times_pwv = 0;
93 
94  void check_API_call_status(
95  herr_t status,
96  int loc
97  )
98  {
99  if(status < 0) {printf("HDF5 API error occured on line %d\n", loc);}
100  }
101 
102  public:
103  OutputFile(
104  const char *filename,
105  int nspax,
106  int ntimes,
107  int nfreqs,
108  float *freqs,
109  float *times,
110  float *eta_ap,
111  float *az,
112  float *el
113  )
114  {
115  this->filename = filename;
116  this->ntimes = ntimes;
117  this->nfreqs = nfreqs;
118 
119  dims_2D[0] = nfreqs;
120  dims_2D[1] = ntimes;
121 
122  start[0] = 0;
123  count[0] = nfreqs;
124 
125  start_pink[1] = 0;
126  count_pink[1] = ntimes;
127 
128  // Make file and obsattrs group
129  file_id = H5Fcreate(
130  filename,
131  H5F_ACC_TRUNC,
132  H5P_DEFAULT,
133  H5P_DEFAULT
134  );
135 
136  obsattrs_id = H5Gcreate(
137  file_id,
138  OBSATTRS_NAME,
139  H5P_DEFAULT,
140  H5P_DEFAULT,
141  H5P_DEFAULT
142  );
143 
144  // Write dataspace with number of spaxels
145  dspace_id = H5Screate(H5S_SCALAR);
146 
147  dset_id = H5Dcreate(
148  obsattrs_id,
149  NSPAX_NAME,
150  H5T_NATIVE_INT,
151  dspace_id,
152  H5P_DEFAULT,
153  H5P_DEFAULT,
154  H5P_DEFAULT
155  );
156 
157  check_API_call_status(
158  H5Dwrite(
159  dset_id,
160  H5T_NATIVE_INT,
161  H5S_ALL,
162  H5S_ALL,
163  H5P_DEFAULT,
164  &nspax
165  ),
166  __LINE__
167  );
168 
169  check_API_call_status(H5Dclose(dset_id), __LINE__);
170 
171  // Write dataspace for frequencies
172  dims_1D[0] = nfreqs;
173 
174  dspace_id = H5Screate_simple(
175  RANK1D,
176  dims_1D,
177  NULL
178  );
179 
180  dset_id = H5Dcreate(
181  obsattrs_id,
182  FREQS_NAME,
183  H5T_IEEE_F32LE,
184  dspace_id,
185  H5P_DEFAULT,
186  H5P_DEFAULT,
187  H5P_DEFAULT
188  );
189 
190  check_API_call_status(
191  H5Dwrite(
192  dset_id,
193  H5T_IEEE_F32LE,
194  H5S_ALL,
195  H5S_ALL,
196  H5P_DEFAULT,
197  freqs
198  ),
199  __LINE__
200  );
201  check_API_call_status(H5Dclose(dset_id), __LINE__);
202 
203  // Write eta_ap
204  dset_id = H5Dcreate(
205  obsattrs_id,
206  ETA_AP_NAME,
207  H5T_IEEE_F32LE,
208  dspace_id,
209  H5P_DEFAULT,
210  H5P_DEFAULT,
211  H5P_DEFAULT
212  );
213 
214  check_API_call_status(
215  H5Dwrite(
216  dset_id,
217  H5T_IEEE_F32LE,
218  H5S_ALL,
219  H5S_ALL,
220  H5P_DEFAULT,
221  eta_ap
222  ),
223  __LINE__
224  );
225  check_API_call_status(H5Dclose(dset_id), __LINE__);
226  check_API_call_status(H5Sclose(dspace_id), __LINE__);
227 
228  // Write time and az-el arrays
229  dims_1D[0] = ntimes;
230 
231  dspace_id = H5Screate_simple(
232  RANK1D,
233  dims_1D,
234  NULL
235  );
236 
237  dset_id = H5Dcreate(
238  obsattrs_id,
239  TIME_NAME,
240  H5T_IEEE_F32LE,
241  dspace_id,
242  H5P_DEFAULT,
243  H5P_DEFAULT,
244  H5P_DEFAULT
245  );
246 
247  check_API_call_status(
248  H5Dwrite(
249  dset_id,
250  H5T_IEEE_F32LE,
251  H5S_ALL,
252  H5S_ALL,
253  H5P_DEFAULT,
254  times
255  ),
256  __LINE__
257  );
258  check_API_call_status(H5Dclose(dset_id), __LINE__);
259 
260  dset_id = H5Dcreate(
261  obsattrs_id,
262  AZ_NAME,
263  H5T_IEEE_F32LE,
264  dspace_id,
265  H5P_DEFAULT,
266  H5P_DEFAULT,
267  H5P_DEFAULT
268  );
269 
270  check_API_call_status(
271  H5Dwrite(
272  dset_id,
273  H5T_IEEE_F32LE,
274  H5S_ALL,
275  H5S_ALL,
276  H5P_DEFAULT,
277  az
278  ),
279  __LINE__
280  );
281  check_API_call_status(H5Dclose(dset_id), __LINE__);
282 
283  dset_id = H5Dcreate(
284  obsattrs_id,
285  EL_NAME,
286  H5T_IEEE_F32LE,
287  dspace_id,
288  H5P_DEFAULT,
289  H5P_DEFAULT,
290  H5P_DEFAULT
291  );
292 
293  check_API_call_status(
294  H5Dwrite(
295  dset_id,
296  H5T_IEEE_F32LE,
297  H5S_ALL,
298  H5S_ALL,
299  H5P_DEFAULT,
300  el
301  ),
302  __LINE__
303  );
304  check_API_call_status(H5Dclose(dset_id), __LINE__);
305  check_API_call_status(H5Sclose(dspace_id), __LINE__);
306 
307  // Allocate output array for zenith PWV
308  dspace_pwv_id = H5Screate_simple(
309  RANK1D,
310  dims_1D,
311  NULL
312  );
313 
314  dset_pwv_id = H5Dcreate(
315  obsattrs_id,
316  PWV_NAME,
317  H5T_IEEE_F32LE,
318  dspace_pwv_id,
319  H5P_DEFAULT,
320  H5P_DEFAULT,
321  H5P_DEFAULT
322  );
323  }
324  void write_chunk_to_pwv(
325  int ntimes_chunk,
326  float *data
327  )
328  {
329  start_pwv[0] = offset_times_pwv;
330  count_pwv[0] = ntimes_chunk;
331 
332  dims_1D[0] = ntimes_chunk;
333 
334  check_API_call_status(
335  H5Sselect_hyperslab(
336  dspace_pwv_id,
337  H5S_SELECT_SET,
338  start_pwv,
339  NULL,
340  count_pwv,
341  NULL
342  ),
343  __LINE__
344  );
345 
346  dspace_pwv_slab_id = H5Screate_simple(
347  RANK1D,
348  dims_1D,
349  NULL
350  );
351 
352  check_API_call_status(
353  H5Dwrite(
354  dset_pwv_id,
355  H5T_IEEE_F32LE,
356  dspace_pwv_slab_id,
357  dspace_pwv_id,
358  H5P_DEFAULT,
359  data
360  ),
361  __LINE__
362  );
363 
364  offset_times_pwv += ntimes_chunk;
365  check_API_call_status(H5Sclose(dspace_pwv_slab_id), __LINE__);
366  }
367  void close_obsattrs() {
368  check_API_call_status(H5Dclose(dset_pwv_id), __LINE__);
369  check_API_call_status(H5Sclose(dspace_pwv_id), __LINE__);
370  check_API_call_status(H5Gclose(obsattrs_id), __LINE__);
371  }
372 
373  void open_spaxel(
374  int spax_index,
375  float az_spax,
376  float el_spax
377  )
378  {
379  offset_times = 0;
380  offset_freqs = 0;
381 
382  char spax_name[CHBUFF] = SPAX_NAME;
383  char buffer[CHBUFF];
384 
385  sprintf(buffer, "%d", spax_index);
386  strcat(spax_name, buffer);
387 
388  spax_id = H5Gcreate(
389  file_id,
390  spax_name,
391  H5P_DEFAULT,
392  H5P_DEFAULT,
393  H5P_DEFAULT
394  );
395 
396  dspace_id = H5Screate(H5S_SCALAR);
397 
398  dset_id = H5Dcreate(
399  spax_id,
400  AZ_SPAX_NAME,
401  H5T_IEEE_F32LE,
402  dspace_id,
403  H5P_DEFAULT,
404  H5P_DEFAULT,
405  H5P_DEFAULT
406  );
407 
408  check_API_call_status(
409  H5Dwrite(
410  dset_id,
411  H5T_IEEE_F32LE,
412  H5S_ALL,
413  H5S_ALL,
414  H5P_DEFAULT,
415  &az_spax
416  ),
417  __LINE__
418  );
419  check_API_call_status(H5Dclose(dset_id), __LINE__);
420 
421  dset_id = H5Dcreate(
422  spax_id,
423  EL_SPAX_NAME,
424  H5T_IEEE_F32LE,
425  dspace_id,
426  H5P_DEFAULT,
427  H5P_DEFAULT,
428  H5P_DEFAULT
429  );
430 
431  check_API_call_status(
432  H5Dwrite(
433  dset_id,
434  H5T_IEEE_F32LE,
435  H5S_ALL,
436  H5S_ALL,
437  H5P_DEFAULT,
438  &el_spax
439  ),
440  __LINE__
441  );
442  check_API_call_status(H5Dclose(dset_id), __LINE__);
443  check_API_call_status(H5Sclose(dspace_id), __LINE__);
444 
445  // Allocate output array for this spaxel
446  dspace_id = H5Screate_simple(
447  RANK2D,
448  dims_2D,
449  NULL
450  );
451 
452  dset_id = H5Dcreate(
453  spax_id,
454  OUT_NAME,
455  H5T_IEEE_F32LE,
456  dspace_id,
457  H5P_DEFAULT,
458  H5P_DEFAULT,
459  H5P_DEFAULT
460  );
461  }
462 
463  void write_pink_chunk_to_spaxel(
464  int k_ch,
465  float *data
466  )
467  {
468  start_pink[0] = k_ch;
469  count_pink[0] = 1;
470 
471  dims_1D[0] = ntimes;
472 
473  check_API_call_status(
474  H5Sselect_hyperslab(
475  dspace_id,
476  H5S_SELECT_SET,
477  start_pink,
478  NULL,
479  count_pink,
480  NULL
481  ),
482  __LINE__
483  );
484 
485  dspace_slab_id = H5Screate_simple(
486  RANK1D,
487  dims_1D,
488  NULL
489  );
490 
491  check_API_call_status(
492  H5Dwrite(
493  dset_id,
494  H5T_IEEE_F32LE,
495  dspace_slab_id,
496  dspace_id,
497  H5P_DEFAULT,
498  data
499  ),
500  __LINE__
501  );
502 
503  check_API_call_status(H5Sclose(dspace_slab_id), __LINE__);
504  }
505 
506  void write_chunk_to_spaxel(
507  int ntimes_chunk,
508  float *data
509  )
510  {
511  start[1] = offset_times;
512  count[1] = ntimes_chunk;
513 
514  dims_1D[0] = ntimes_chunk * nfreqs;
515 
516  check_API_call_status(
517  H5Sselect_hyperslab(
518  dspace_id,
519  H5S_SELECT_SET,
520  start,
521  NULL,
522  count,
523  NULL
524  ),
525  __LINE__
526  );
527 
528  dspace_slab_id = H5Screate_simple(
529  RANK1D,
530  dims_1D,
531  NULL
532  );
533 
534  float *buffer = new float[dims_1D[0]];
535  check_API_call_status(
536  H5Dread(
537  dset_id,
538  H5T_IEEE_F32LE,
539  dspace_slab_id,
540  dspace_id,
541  H5P_DEFAULT,
542  buffer
543  ),
544  __LINE__
545  );
546 
547  for(int ii=0; ii < dims_1D[0]; ii++)
548  {
549  buffer[ii] += data[ii];
550  }
551 
552  check_API_call_status(
553  H5Dwrite(
554  dset_id,
555  H5T_IEEE_F32LE,
556  dspace_slab_id,
557  dspace_id,
558  H5P_DEFAULT,
559  buffer
560  ),
561  __LINE__
562  );
563 
564  delete[] buffer;
565 
566  offset_times += ntimes_chunk;
567  check_API_call_status(H5Sclose(dspace_slab_id), __LINE__);
568  }
569 
570  void close_spaxel()
571  {
572  check_API_call_status(H5Dclose(dset_id), __LINE__);
573  check_API_call_status(H5Sclose(dspace_id), __LINE__);
574  check_API_call_status(H5Gclose(spax_id), __LINE__);
575  }
576  ~OutputFile()
577  {
578  check_API_call_status(H5Fclose(file_id), __LINE__);
579  }
580 };
581 #endif
582 
583 void readAtmMeta(
584  int **meta,
585  std::string path
586  )
587 {
588  fs::path dir(path);
589  fs::path file("atm_meta.datp");
590  fs::path abs_loc = dir / file;
591 
592  *meta = new int[NATMGRID];
593 
594  std::string store;
595 
596  std::ifstream myfile(abs_loc);
597  std::string line;
598 
599  int idx = 0;
600 
601  if (!myfile)
602  {
603  std::cerr
604  << "Could not open the file at "
605  << abs_loc
606  << std::endl;
607  exit(5);
608  }
609  else
610  {
611  while(std::getline(myfile, line))
612  {
613  std::istringstream iss(line);
614  while(std::getline(iss, store, ' '))
615  {
616  if (store=="") {continue;}
617  (*meta)[idx] = std::stoi(store);
618  idx++;
619  }
620  }
621  myfile.close();
622  }
623 }
624 
625 template <typename T, typename U>
626 void readEtaATM(
627  T **eta_array,
628  U *pwv_atm,
629  U *freq_atm,
630  const char* filepath
631  )
632 {
633  // TODO read these in from file? Ask Arend
634  pwv_atm->start = 0.1;
635  pwv_atm->step = 0.1;
636  pwv_atm->num = NPWVATM;
637 
638  freq_atm->start = 70.e9;
639  freq_atm->step = 0.1e9;
640  freq_atm->num = NFREQ;
641 
642  *eta_array = new T[NPWVATM * NFREQ];
643 
644  std::string store;
645  //std::cout << abi::__cxa_demangle(typeid(store).name(), NULL, NULL, &status) << std::endl;
646 
647  std::ifstream myfile(filepath);
648  std::string line;
649 
650  int line_nr = 0;
651  int idx = 0;
652 
653  if (!myfile)
654  {
655  std::cerr
656  << "Could not open the resource file at "
657  << filepath
658  << std::endl;
659  exit(5);
660  /* TODO Standardize exit codes */
661  }
662 
663  while(std::getline(myfile, line))
664  {
665  std::istringstream iss(line);
666  if(!line_nr)
667  {
668  line_nr++;
669  continue;
670  }
671 
672  while(std::getline(iss, store, ' '))
673  {
674  if(!idx)
675  {
676  idx++;
677  continue;
678  }
679  else if (store=="")
680  {
681  continue;
682  }
683 
684  (*eta_array)[NFREQ * (idx-1) + (line_nr - 1)] = std::stof(store);
685  idx++;
686  }
687  line_nr++;
688  idx = 0;
689  }
690  myfile.close();
691 }
692 
693 template <typename T, typename U>
694 void readAtmScreen(
695  T **PWV_screen,
696  U *x_spec,
697  U *y_spec,
698  std::string path,
699  std::string datp)
700 {
701  fs::path dir(path);
702  fs::path file(datp);
703  fs::path abs_loc = dir / file;
704 
705  *PWV_screen = new T[x_spec->num * y_spec->num];
706 
707  std::string store;
708 
709  std::ifstream myfile(abs_loc);
710  std::string line;
711 
712  int line_nr = 0;
713  int idx = 0;
714 
715  if (!myfile)
716  {
717  std::cerr
718  << "Could not open the file!"
719  << std::endl;
720  }
721  else
722  {
723  while(std::getline(myfile, line))
724  {
725  std::istringstream iss(line);
726  while(std::getline(iss, store, ' '))
727  {
728  if (store=="")
729  {
730  continue;
731  }
732 
733  (*PWV_screen)[y_spec->num * line_nr + idx] = std::stof(store);
734  idx++;
735  }
736  line_nr++;
737  idx = 0;
738  }
739  myfile.close();
740  }
741 }
structs.h
Data structures for receiving data from Python interface.
OutputFile
Definition: fio.h:64