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 "telescope/oskar_telescope.h"
7 #include "utility/oskar_dir.h"
8 #include "math/oskar_cmath.h"
9
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13
14 static void oskar_telescope_save_private(const oskar_Telescope* telescope,
15 const char* dir_path, const oskar_Station* station, int depth,
16 int* status);
17
oskar_telescope_save(const oskar_Telescope * telescope,const char * dir_path,int * status)18 void oskar_telescope_save(const oskar_Telescope* telescope,
19 const char* dir_path, int* status)
20 {
21 oskar_telescope_save_private(telescope, dir_path, NULL, 0, status);
22 }
23
oskar_telescope_save_private(const oskar_Telescope * telescope,const char * dir_path,const oskar_Station * station,int depth,int * status)24 static void oskar_telescope_save_private(const oskar_Telescope* telescope,
25 const char* dir_path, const oskar_Station* station, int depth,
26 int* status)
27 {
28 char* path = 0;
29 int i = 0, num_stations = 0;
30
31 if (depth == 0)
32 {
33 /* Check if directory already exists, and remove it if so. */
34 if (oskar_dir_exists(dir_path))
35 {
36 if (!oskar_dir_remove(dir_path))
37 {
38 *status = OSKAR_ERR_FILE_IO;
39 return;
40 }
41 }
42 }
43
44 /* Create the directory if it doesn't exist. */
45 if (!oskar_dir_exists(dir_path))
46 {
47 oskar_dir_mkpath(dir_path);
48 }
49
50 if (depth == 0)
51 {
52 /* Write the reference position. */
53 FILE* file = 0;
54 path = oskar_dir_get_path(dir_path, "position.txt");
55 file = fopen(path, "w");
56 free(path);
57 if (!file)
58 {
59 *status = OSKAR_ERR_FILE_IO;
60 return;
61 }
62 fprintf(file, "%.12f, %.12f, %.12f\n",
63 oskar_telescope_lon_rad(telescope) * 180.0 / M_PI,
64 oskar_telescope_lat_rad(telescope) * 180.0 / M_PI,
65 oskar_telescope_alt_metres(telescope));
66 fclose(file);
67
68 /* Write the station coordinates. */
69 path = oskar_dir_get_path(dir_path, "layout.txt");
70 oskar_telescope_save_layout(telescope, path, status);
71 free(path);
72
73 /* Write the station type mapping. */
74 path = oskar_dir_get_path(dir_path, "station_type_map.txt");
75 file = fopen(path, "w");
76 free(path);
77 oskar_mem_save_ascii(file, 1, 0,
78 oskar_telescope_num_stations(telescope), status,
79 oskar_telescope_station_type_map_const(telescope));
80 fclose(file);
81
82 /* Get the number of stations. */
83 num_stations = oskar_telescope_num_station_models(telescope);
84 }
85 else
86 {
87 int num_feeds = 2, name_offset = 1;
88
89 /* Write the station configuration data. */
90 path = oskar_dir_get_path(dir_path, "mount_types.txt");
91 oskar_station_save_mount_types(station, path, status);
92 free(path);
93 if (!oskar_station_has_child(station))
94 {
95 path = oskar_dir_get_path(dir_path, "feed_angle_x.txt");
96 oskar_station_save_feed_angle(station, 0, path, status);
97 free(path);
98 path = oskar_dir_get_path(dir_path, "feed_angle_y.txt");
99 oskar_station_save_feed_angle(station, 1, path, status);
100 free(path);
101 }
102 if (oskar_station_num_element_types(station) > 1)
103 {
104 path = oskar_dir_get_path(dir_path, "element_types.txt");
105 oskar_station_save_element_types(station, path, status);
106 free(path);
107 }
108 if (oskar_station_num_permitted_beams(station) > 0)
109 {
110 path = oskar_dir_get_path(dir_path, "permitted_beams.txt");
111 oskar_station_save_permitted_beams(station, path, status);
112 free(path);
113 }
114 if (oskar_station_common_pol_beams(station))
115 {
116 num_feeds = 1;
117 name_offset = 0;
118 }
119 const char* layout_name[] = {
120 "layout.txt",
121 "layout_x.txt",
122 "layout_y.txt"};
123 const char* cable_name[] = {
124 "cable_length_error.txt",
125 "cable_length_error_x.txt",
126 "cable_length_error_y.txt"};
127 const char* gain_phase_name[] = {
128 "gain_phase.txt",
129 "gain_phase_x.txt",
130 "gain_phase_y.txt"};
131 const char* apodisation_name[] = {
132 "apodisation.txt",
133 "apodisation_x.txt",
134 "apodisation_y.txt"};
135 for (i = 0; i < num_feeds; ++i)
136 {
137 const int i_name = i + name_offset;
138 path = oskar_dir_get_path(dir_path, layout_name[i_name]);
139 oskar_station_save_layout(station, i, path, status);
140 free(path);
141 path = oskar_dir_get_path(dir_path, cable_name[i_name]);
142 oskar_station_save_cable_length_error(station, i, path, status);
143 free(path);
144 if (oskar_station_apply_element_errors(station))
145 {
146 path = oskar_dir_get_path(dir_path, gain_phase_name[i_name]);
147 oskar_station_save_gain_phase(station, i, path, status);
148 free(path);
149 }
150 if (oskar_station_apply_element_weight(station))
151 {
152 path = oskar_dir_get_path(dir_path, apodisation_name[i_name]);
153 oskar_station_save_apodisation(station, i, path, status);
154 free(path);
155 }
156 }
157
158 /* Get the number of stations. */
159 if (oskar_station_has_child(station))
160 {
161 num_stations = oskar_station_num_elements(station);
162 }
163 }
164
165 /* Recursive call to write stations. */
166 for (i = 0; i < num_stations; ++i)
167 {
168 /* Get station name, and a pointer to the station to save. */
169 const oskar_Station* s = 0;
170 char station_name[128], *path = 0;
171 sprintf(station_name, "level%1d_%03d", depth, i);
172 s = (depth == 0) ? oskar_telescope_station_const(telescope, i) :
173 oskar_station_child_const(station, i);
174
175 /* Save this station. */
176 if (!s) continue;
177 path = oskar_dir_get_path(dir_path, station_name);
178 oskar_telescope_save_private(telescope, path, s, depth + 1, status);
179 free(path);
180 }
181 }
182
183 #ifdef __cplusplus
184 }
185 #endif
186