1 /*
2 * Copyright (c) 2012-2021, The OSKAR Developers.
3 * See the LICENSE file at the top-level directory of this distribution.
4 */
5
6 #include "sky/oskar_sky.h"
7 #include "math/oskar_cmath.h"
8 #include <stdio.h>
9
10 #define RAD2DEG 180.0/M_PI
11 #define RAD2ARCSEC RAD2DEG * 3600.0
12
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16
oskar_sky_save(const oskar_Sky * sky,const char * filename,int * status)17 void oskar_sky_save(const oskar_Sky* sky, const char* filename, int* status)
18 {
19 int i = 0;
20 FILE* file = 0;
21 if (*status) return;
22
23 /* Check sky model is in CPU memory. */
24 if (oskar_sky_mem_location(sky) != OSKAR_CPU)
25 {
26 *status = OSKAR_ERR_BAD_LOCATION;
27 return;
28 }
29
30 /* Open the output file. */
31 file = fopen(filename, "w");
32 if (!file)
33 {
34 *status = OSKAR_ERR_FILE_IO;
35 return;
36 }
37
38 /* Get the data type and number of sources. */
39 const int type = oskar_sky_precision(sky);
40 const int num_sources = oskar_sky_num_sources(sky);
41
42 /* Print a helpful header. */
43 fprintf(file, "# Number of sources: %i\n", num_sources);
44 fprintf(file, "# RA (deg), Dec (deg), I (Jy), Q (Jy), U (Jy), V (Jy), "
45 "Ref. freq. (Hz), Spectral index, Rotation measure (rad/m^2), "
46 "FWHM major (arcsec), FWHM minor (arcsec), Position angle (deg)\n");
47
48 /* Print out sky model in ASCII format. */
49 if (type == OSKAR_DOUBLE)
50 {
51 const double *ra_ = 0, *dec_ = 0, *I_ = 0, *Q_ = 0, *U_ = 0, *V_ = 0;
52 const double *ref_ = 0, *sp_ = 0, *rm_ = 0;
53 const double *maj_ = 0, *min_ = 0, *pa_ = 0;
54 ra_ = oskar_mem_double_const(oskar_sky_ra_rad_const(sky), status);
55 dec_ = oskar_mem_double_const(oskar_sky_dec_rad_const(sky), status);
56 I_ = oskar_mem_double_const(oskar_sky_I_const(sky), status);
57 Q_ = oskar_mem_double_const(oskar_sky_Q_const(sky), status);
58 U_ = oskar_mem_double_const(oskar_sky_U_const(sky), status);
59 V_ = oskar_mem_double_const(oskar_sky_V_const(sky), status);
60 ref_ = oskar_mem_double_const(oskar_sky_reference_freq_hz_const(sky), status);
61 sp_ = oskar_mem_double_const(oskar_sky_spectral_index_const(sky), status);
62 rm_ = oskar_mem_double_const(oskar_sky_rotation_measure_rad_const(sky), status);
63 maj_ = oskar_mem_double_const(oskar_sky_fwhm_major_rad_const(sky), status);
64 min_ = oskar_mem_double_const(oskar_sky_fwhm_minor_rad_const(sky), status);
65 pa_ = oskar_mem_double_const(oskar_sky_position_angle_rad_const(sky), status);
66
67 for (i = 0; i < num_sources; ++i)
68 {
69 fprintf(file, "% 11.6f,% 11.6f,% 12.6e,% 12.6e,% 12.6e,% 12.6e,"
70 "% 12.6e,% 12.6e,% 12.6e,% 12.6e,% 12.6e,% 11.6f\n",
71 ra_[i] * RAD2DEG, dec_[i] * RAD2DEG,
72 I_[i], Q_[i], U_[i], V_[i], ref_[i], sp_[i], rm_[i],
73 maj_[i] * RAD2ARCSEC, min_[i] * RAD2ARCSEC,
74 pa_[i] * RAD2DEG);
75 }
76 }
77 else if (type == OSKAR_SINGLE)
78 {
79 const float *ra_ = 0, *dec_ = 0, *I_ = 0, *Q_ = 0, *U_ = 0, *V_ = 0;
80 const float *ref_ = 0, *sp_ = 0, *rm_ = 0;
81 const float *maj_ = 0, *min_ = 0, *pa_ = 0;
82 ra_ = oskar_mem_float_const(oskar_sky_ra_rad_const(sky), status);
83 dec_ = oskar_mem_float_const(oskar_sky_dec_rad_const(sky), status);
84 I_ = oskar_mem_float_const(oskar_sky_I_const(sky), status);
85 Q_ = oskar_mem_float_const(oskar_sky_Q_const(sky), status);
86 U_ = oskar_mem_float_const(oskar_sky_U_const(sky), status);
87 V_ = oskar_mem_float_const(oskar_sky_V_const(sky), status);
88 ref_ = oskar_mem_float_const(oskar_sky_reference_freq_hz_const(sky), status);
89 sp_ = oskar_mem_float_const(oskar_sky_spectral_index_const(sky), status);
90 rm_ = oskar_mem_float_const(oskar_sky_rotation_measure_rad_const(sky), status);
91 maj_ = oskar_mem_float_const(oskar_sky_fwhm_major_rad_const(sky), status);
92 min_ = oskar_mem_float_const(oskar_sky_fwhm_minor_rad_const(sky), status);
93 pa_ = oskar_mem_float_const(oskar_sky_position_angle_rad_const(sky), status);
94
95 for (i = 0; i < num_sources; ++i)
96 {
97 fprintf(file, "% 11.6f,% 11.6f,% 12.6e,% 12.6e,% 12.6e,% 12.6e,"
98 "% 12.6e,% 12.6e,% 12.6e,% 12.6e,% 12.6e,% 11.6f\n",
99 ra_[i] * RAD2DEG, dec_[i] * RAD2DEG,
100 I_[i], Q_[i], U_[i], V_[i], ref_[i], sp_[i], rm_[i],
101 maj_[i] * RAD2ARCSEC, min_[i] * RAD2ARCSEC,
102 pa_[i] * RAD2DEG);
103 }
104 }
105 else
106 {
107 *status = OSKAR_ERR_BAD_DATA_TYPE;
108 }
109
110 fclose(file);
111 }
112
113 #ifdef __cplusplus
114 }
115 #endif
116