1 /*
2 * Copyright (c) 2013-2021, The OSKAR Developers.
3 * See the LICENSE file at the top-level directory of this distribution.
4 */
5
6 #include "telescope/private_telescope.h"
7 #include "telescope/oskar_telescope.h"
8
9 #include "math/oskar_cmath.h"
10
11 #include <ctype.h>
12 #include <string.h>
13
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17
18 /* Properties and metadata. */
19
oskar_telescope_precision(const oskar_Telescope * model)20 int oskar_telescope_precision(const oskar_Telescope* model)
21 {
22 return model->precision;
23 }
24
oskar_telescope_mem_location(const oskar_Telescope * model)25 int oskar_telescope_mem_location(const oskar_Telescope* model)
26 {
27 return model->mem_location;
28 }
29
oskar_telescope_lon_rad(const oskar_Telescope * model)30 double oskar_telescope_lon_rad(const oskar_Telescope* model)
31 {
32 return model->lon_rad;
33 }
34
oskar_telescope_lat_rad(const oskar_Telescope * model)35 double oskar_telescope_lat_rad(const oskar_Telescope* model)
36 {
37 return model->lat_rad;
38 }
39
oskar_telescope_alt_metres(const oskar_Telescope * model)40 double oskar_telescope_alt_metres(const oskar_Telescope* model)
41 {
42 return model->alt_metres;
43 }
44
oskar_telescope_polar_motion_x_rad(const oskar_Telescope * model)45 double oskar_telescope_polar_motion_x_rad(const oskar_Telescope* model)
46 {
47 return model->pm_x_rad;
48 }
49
oskar_telescope_polar_motion_y_rad(const oskar_Telescope * model)50 double oskar_telescope_polar_motion_y_rad(const oskar_Telescope* model)
51 {
52 return model->pm_y_rad;
53 }
54
oskar_telescope_phase_centre_coord_type(const oskar_Telescope * model)55 int oskar_telescope_phase_centre_coord_type(const oskar_Telescope* model)
56 {
57 return model->phase_centre_coord_type;
58 }
59
oskar_telescope_phase_centre_longitude_rad(const oskar_Telescope * model)60 double oskar_telescope_phase_centre_longitude_rad(const oskar_Telescope* model)
61 {
62 return model->phase_centre_rad[0];
63 }
64
oskar_telescope_phase_centre_latitude_rad(const oskar_Telescope * model)65 double oskar_telescope_phase_centre_latitude_rad(const oskar_Telescope* model)
66 {
67 return model->phase_centre_rad[1];
68 }
69
oskar_telescope_channel_bandwidth_hz(const oskar_Telescope * model)70 double oskar_telescope_channel_bandwidth_hz(const oskar_Telescope* model)
71 {
72 return model->channel_bandwidth_hz;
73 }
74
oskar_telescope_tec_screen_height_km(const oskar_Telescope * model)75 double oskar_telescope_tec_screen_height_km(const oskar_Telescope* model)
76 {
77 return model->tec_screen_height_km;
78 }
79
oskar_telescope_tec_screen_pixel_size_m(const oskar_Telescope * model)80 double oskar_telescope_tec_screen_pixel_size_m(const oskar_Telescope* model)
81 {
82 return model->tec_screen_pixel_size_m;
83 }
84
oskar_telescope_tec_screen_time_interval_sec(const oskar_Telescope * model)85 double oskar_telescope_tec_screen_time_interval_sec(
86 const oskar_Telescope* model)
87 {
88 return model->tec_screen_time_interval_sec;
89 }
90
oskar_telescope_isoplanatic_screen(const oskar_Telescope * model)91 int oskar_telescope_isoplanatic_screen(const oskar_Telescope* model)
92 {
93 return model->isoplanatic_screen;
94 }
95
oskar_telescope_time_average_sec(const oskar_Telescope * model)96 double oskar_telescope_time_average_sec(const oskar_Telescope* model)
97 {
98 return model->time_average_sec;
99 }
100
oskar_telescope_uv_filter_min(const oskar_Telescope * model)101 double oskar_telescope_uv_filter_min(const oskar_Telescope* model)
102 {
103 return model->uv_filter_min;
104 }
105
oskar_telescope_uv_filter_max(const oskar_Telescope * model)106 double oskar_telescope_uv_filter_max(const oskar_Telescope* model)
107 {
108 return model->uv_filter_max;
109 }
110
oskar_telescope_uv_filter_units(const oskar_Telescope * model)111 int oskar_telescope_uv_filter_units(const oskar_Telescope* model)
112 {
113 return model->uv_filter_units;
114 }
115
oskar_telescope_pol_mode(const oskar_Telescope * model)116 int oskar_telescope_pol_mode(const oskar_Telescope* model)
117 {
118 return model->pol_mode;
119 }
120
oskar_telescope_num_baselines(const oskar_Telescope * model)121 int oskar_telescope_num_baselines(const oskar_Telescope* model)
122 {
123 return ((model->num_stations * (model->num_stations - 1)) / 2);
124 }
125
oskar_telescope_num_stations(const oskar_Telescope * model)126 int oskar_telescope_num_stations(const oskar_Telescope* model)
127 {
128 return model->num_stations;
129 }
130
oskar_telescope_num_station_models(const oskar_Telescope * model)131 int oskar_telescope_num_station_models(const oskar_Telescope* model)
132 {
133 return model->num_station_models;
134 }
135
oskar_telescope_allow_station_beam_duplication(const oskar_Telescope * model)136 int oskar_telescope_allow_station_beam_duplication(
137 const oskar_Telescope* model)
138 {
139 return model->allow_station_beam_duplication;
140 }
141
oskar_telescope_ionosphere_screen_type(const oskar_Telescope * model)142 char oskar_telescope_ionosphere_screen_type(const oskar_Telescope* model)
143 {
144 return (char) (model->ionosphere_screen_type);
145 }
146
oskar_telescope_enable_numerical_patterns(const oskar_Telescope * model)147 int oskar_telescope_enable_numerical_patterns(const oskar_Telescope* model)
148 {
149 return model->enable_numerical_patterns;
150 }
151
oskar_telescope_max_station_size(const oskar_Telescope * model)152 int oskar_telescope_max_station_size(const oskar_Telescope* model)
153 {
154 return model->max_station_size;
155 }
156
oskar_telescope_max_station_depth(const oskar_Telescope * model)157 int oskar_telescope_max_station_depth(const oskar_Telescope* model)
158 {
159 return model->max_station_depth;
160 }
161
162
163 /* Station models. */
164
oskar_telescope_station(oskar_Telescope * model,int i)165 oskar_Station* oskar_telescope_station(oskar_Telescope* model, int i)
166 {
167 if (i >= model->num_station_models) return 0;
168 return model->station[i];
169 }
170
oskar_telescope_station_const(const oskar_Telescope * model,int i)171 const oskar_Station* oskar_telescope_station_const(
172 const oskar_Telescope* model, int i)
173 {
174 if (i >= model->num_station_models) return 0;
175 return model->station[i];
176 }
177
178
179 /* Arrays. */
180
oskar_telescope_station_type_map(oskar_Telescope * model)181 oskar_Mem* oskar_telescope_station_type_map(oskar_Telescope* model)
182 {
183 return model->station_type_map;
184 }
185
oskar_telescope_station_type_map_const(const oskar_Telescope * model)186 const oskar_Mem* oskar_telescope_station_type_map_const(
187 const oskar_Telescope* model)
188 {
189 return model->station_type_map;
190 }
191
oskar_telescope_station_measured_offset_ecef_metres(oskar_Telescope * model,int dim)192 oskar_Mem* oskar_telescope_station_measured_offset_ecef_metres(
193 oskar_Telescope* model, int dim)
194 {
195 return model->station_measured_offset_ecef_metres[dim];
196 }
197
oskar_telescope_station_measured_offset_ecef_metres_const(const oskar_Telescope * model,int dim)198 const oskar_Mem* oskar_telescope_station_measured_offset_ecef_metres_const(
199 const oskar_Telescope* model, int dim)
200 {
201 return model->station_measured_offset_ecef_metres[dim];
202 }
203
oskar_telescope_station_measured_enu_metres(oskar_Telescope * model,int dim)204 oskar_Mem* oskar_telescope_station_measured_enu_metres(
205 oskar_Telescope* model, int dim)
206 {
207 return model->station_measured_enu_metres[dim];
208 }
209
oskar_telescope_station_measured_enu_metres_const(const oskar_Telescope * model,int dim)210 const oskar_Mem* oskar_telescope_station_measured_enu_metres_const(
211 const oskar_Telescope* model, int dim)
212 {
213 return model->station_measured_enu_metres[dim];
214 }
215
oskar_telescope_station_true_offset_ecef_metres(oskar_Telescope * model,int dim)216 oskar_Mem* oskar_telescope_station_true_offset_ecef_metres(
217 oskar_Telescope* model, int dim)
218 {
219 return model->station_true_offset_ecef_metres[dim];
220 }
221
oskar_telescope_station_true_offset_ecef_metres_const(const oskar_Telescope * model,int dim)222 const oskar_Mem* oskar_telescope_station_true_offset_ecef_metres_const(
223 const oskar_Telescope* model, int dim)
224 {
225 return model->station_true_offset_ecef_metres[dim];
226 }
227
oskar_telescope_station_true_enu_metres(oskar_Telescope * model,int dim)228 oskar_Mem* oskar_telescope_station_true_enu_metres(
229 oskar_Telescope* model, int dim)
230 {
231 return model->station_true_enu_metres[dim];
232 }
233
oskar_telescope_station_true_enu_metres_const(const oskar_Telescope * model,int dim)234 const oskar_Mem* oskar_telescope_station_true_enu_metres_const(
235 const oskar_Telescope* model, int dim)
236 {
237 return model->station_true_enu_metres[dim];
238 }
239
oskar_telescope_noise_enabled(const oskar_Telescope * model)240 int oskar_telescope_noise_enabled(const oskar_Telescope* model)
241 {
242 return model->noise_enabled;
243 }
244
oskar_telescope_noise_seed(const oskar_Telescope * model)245 unsigned int oskar_telescope_noise_seed(const oskar_Telescope* model)
246 {
247 return model->noise_seed;
248 }
249
oskar_telescope_tec_screen_path(const oskar_Telescope * model)250 const char* oskar_telescope_tec_screen_path(const oskar_Telescope* model)
251 {
252 return oskar_mem_char_const(model->tec_screen_path);
253 }
254
oskar_telescope_gains(oskar_Telescope * model)255 oskar_Gains* oskar_telescope_gains(oskar_Telescope* model)
256 {
257 return model->gains;
258 }
259
oskar_telescope_gains_const(const oskar_Telescope * model)260 const oskar_Gains* oskar_telescope_gains_const(const oskar_Telescope* model)
261 {
262 return model->gains;
263 }
264
265
266 /* Setters. */
267
oskar_telescope_set_allow_station_beam_duplication(oskar_Telescope * model,int value)268 void oskar_telescope_set_allow_station_beam_duplication(oskar_Telescope* model,
269 int value)
270 {
271 model->allow_station_beam_duplication = value;
272 }
273
oskar_telescope_set_ionosphere_screen_type(oskar_Telescope * model,const char * type)274 void oskar_telescope_set_ionosphere_screen_type(oskar_Telescope* model,
275 const char* type)
276 {
277 model->ionosphere_screen_type = toupper(type[0]);
278 }
279
oskar_telescope_set_isoplanatic_screen(oskar_Telescope * model,int flag)280 void oskar_telescope_set_isoplanatic_screen(oskar_Telescope* model, int flag)
281 {
282 model->isoplanatic_screen = flag;
283 }
284
oskar_telescope_set_enable_noise(oskar_Telescope * model,int value,unsigned int seed)285 void oskar_telescope_set_enable_noise(oskar_Telescope* model,
286 int value, unsigned int seed)
287 {
288 model->noise_enabled = value;
289 model->noise_seed = seed;
290 }
291
oskar_telescope_set_enable_numerical_patterns(oskar_Telescope * model,int value)292 void oskar_telescope_set_enable_numerical_patterns(oskar_Telescope* model,
293 int value)
294 {
295 model->enable_numerical_patterns = value;
296 }
297
oskar_telescope_set_gaussian_station_beam_p(oskar_Station * station,double fwhm_rad,double ref_freq_hz)298 static void oskar_telescope_set_gaussian_station_beam_p(oskar_Station* station,
299 double fwhm_rad, double ref_freq_hz)
300 {
301 oskar_station_set_gaussian_beam_values(station, fwhm_rad, ref_freq_hz);
302 if (oskar_station_has_child(station))
303 {
304 int i = 0;
305 const int num_elements = oskar_station_num_elements(station);
306 for (i = 0; i < num_elements; ++i)
307 {
308 oskar_telescope_set_gaussian_station_beam_p(
309 oskar_station_child(station, i), fwhm_rad, ref_freq_hz);
310 }
311 }
312 }
313
oskar_telescope_set_gaussian_station_beam_width(oskar_Telescope * model,double fwhm_deg,double ref_freq_hz)314 void oskar_telescope_set_gaussian_station_beam_width(oskar_Telescope* model,
315 double fwhm_deg, double ref_freq_hz)
316 {
317 int i = 0;
318 for (i = 0; i < model->num_station_models; ++i)
319 {
320 oskar_telescope_set_gaussian_station_beam_p(model->station[i],
321 fwhm_deg * M_PI / 180.0, ref_freq_hz);
322 }
323 }
324
oskar_telescope_set_noise_freq_file(oskar_Telescope * model,const char * filename,int * status)325 void oskar_telescope_set_noise_freq_file(oskar_Telescope* model,
326 const char* filename, int* status)
327 {
328 int i = 0;
329 if (*status) return;
330 for (i = 0; i < model->num_station_models; ++i)
331 {
332 if (!model->station[i]) continue;
333 oskar_mem_load_ascii(filename, 1, status,
334 oskar_station_noise_freq_hz(model->station[i]), "");
335 }
336 }
337
oskar_telescope_set_noise_freq(oskar_Telescope * model,double start_hz,double inc_hz,int num_channels,int * status)338 void oskar_telescope_set_noise_freq(oskar_Telescope* model,
339 double start_hz, double inc_hz, int num_channels, int* status)
340 {
341 int i = 0;
342 oskar_Mem* noise_freq_hz = 0;
343 noise_freq_hz = oskar_mem_create(model->precision, OSKAR_CPU,
344 num_channels, status);
345 if (*status) return;
346 if (model->precision == OSKAR_DOUBLE)
347 {
348 double* f = oskar_mem_double(noise_freq_hz, status);
349 for (i = 0; i < num_channels; ++i) f[i] = start_hz + i * inc_hz;
350 }
351 else
352 {
353 float* f = oskar_mem_float(noise_freq_hz, status);
354 for (i = 0; i < num_channels; ++i) f[i] = start_hz + i * inc_hz;
355 }
356
357 /* Set noise frequency for all top-level stations. */
358 for (i = 0; i < model->num_station_models; ++i)
359 {
360 oskar_Mem* t = 0;
361 if (!model->station[i]) continue;
362 t = oskar_station_noise_freq_hz(model->station[i]);
363 oskar_mem_realloc(t, num_channels, status);
364 oskar_mem_copy(t, noise_freq_hz, status);
365 }
366 oskar_mem_free(noise_freq_hz, status);
367 }
368
oskar_telescope_set_noise_rms_file(oskar_Telescope * model,const char * filename,int * status)369 void oskar_telescope_set_noise_rms_file(oskar_Telescope* model,
370 const char* filename, int* status)
371 {
372 int i = 0;
373 if (*status) return;
374 for (i = 0; i < model->num_station_models; ++i)
375 {
376 if (!model->station[i]) continue;
377 oskar_mem_load_ascii(filename, 1, status,
378 oskar_station_noise_rms_jy(model->station[i]), "");
379 }
380 }
381
oskar_telescope_set_noise_rms(oskar_Telescope * model,double start,double end,int * status)382 void oskar_telescope_set_noise_rms(oskar_Telescope* model,
383 double start, double end, int* status)
384 {
385 int i = 0, j = 0, num_channels = 0;
386 double inc = 0.0;
387 oskar_Station* s = 0;
388 oskar_Mem *noise_rms_jy = 0, *h = 0;
389
390 /* Set noise RMS for all top-level stations. */
391 if (*status) return;
392 for (i = 0; i < model->num_station_models; ++i)
393 {
394 s = model->station[i];
395 if (!s) continue;
396 h = oskar_station_noise_rms_jy(s);
397 num_channels = (int)oskar_mem_length(oskar_station_noise_freq_hz(s));
398 if (num_channels == 0)
399 {
400 *status = OSKAR_ERR_OUT_OF_RANGE;
401 return;
402 }
403 oskar_mem_realloc(h, num_channels, status);
404 noise_rms_jy = oskar_mem_create(model->precision, OSKAR_CPU,
405 num_channels, status);
406 inc = (end - start) / (double)num_channels;
407 if (model->precision == OSKAR_DOUBLE)
408 {
409 double* r = oskar_mem_double(noise_rms_jy, status);
410 for (j = 0; j < num_channels; ++j) r[j] = start + j * inc;
411 }
412 else
413 {
414 float* r = oskar_mem_float(noise_rms_jy, status);
415 for (j = 0; j < num_channels; ++j) r[j] = start + j * inc;
416 }
417 oskar_mem_copy(h, noise_rms_jy, status);
418 oskar_mem_free(noise_rms_jy, status);
419 }
420 }
421
oskar_telescope_set_position(oskar_Telescope * model,double longitude_rad,double latitude_rad,double altitude_metres)422 void oskar_telescope_set_position(oskar_Telescope* model,
423 double longitude_rad, double latitude_rad, double altitude_metres)
424 {
425 model->lon_rad = longitude_rad;
426 model->lat_rad = latitude_rad;
427 model->alt_metres = altitude_metres;
428 }
429
oskar_telescope_set_polar_motion(oskar_Telescope * model,double pm_x_rad,double pm_y_rad)430 void oskar_telescope_set_polar_motion(oskar_Telescope* model,
431 double pm_x_rad, double pm_y_rad)
432 {
433 int i = 0;
434 model->pm_x_rad = pm_x_rad;
435 model->pm_y_rad = pm_y_rad;
436
437 /* Set for all stations, too. */
438 for (i = 0; i < model->num_station_models; ++i)
439 {
440 oskar_station_set_polar_motion(model->station[i], pm_x_rad, pm_y_rad);
441 }
442 }
443
oskar_telescope_set_station_phase_centre(oskar_Station * station,int coord_type,double longitude_rad,double latitude_rad)444 static void oskar_telescope_set_station_phase_centre(oskar_Station* station,
445 int coord_type, double longitude_rad, double latitude_rad)
446 {
447 oskar_station_set_phase_centre(station, coord_type, longitude_rad,
448 latitude_rad);
449 if (oskar_station_has_child(station))
450 {
451 int i = 0, num_elements = 0;
452 num_elements = oskar_station_num_elements(station);
453 for (i = 0; i < num_elements; ++i)
454 {
455 oskar_telescope_set_station_phase_centre(
456 oskar_station_child(station, i),
457 coord_type, longitude_rad, latitude_rad);
458 }
459 }
460 }
461
oskar_telescope_set_phase_centre(oskar_Telescope * model,int coord_type,double longitude_rad,double latitude_rad)462 void oskar_telescope_set_phase_centre(oskar_Telescope* model,
463 int coord_type, double longitude_rad, double latitude_rad)
464 {
465 int i = 0;
466 model->phase_centre_coord_type = coord_type;
467 model->phase_centre_rad[0] = longitude_rad;
468 model->phase_centre_rad[1] = latitude_rad;
469 for (i = 0; i < model->num_station_models; ++i)
470 {
471 oskar_telescope_set_station_phase_centre(model->station[i],
472 coord_type, longitude_rad, latitude_rad);
473 }
474 }
475
oskar_telescope_set_tec_screen_height(oskar_Telescope * model,double height_km)476 void oskar_telescope_set_tec_screen_height(oskar_Telescope* model,
477 double height_km)
478 {
479 model->tec_screen_height_km = height_km;
480 }
481
oskar_telescope_set_tec_screen_pixel_size(oskar_Telescope * model,double pixel_size_m)482 void oskar_telescope_set_tec_screen_pixel_size(oskar_Telescope* model,
483 double pixel_size_m)
484 {
485 model->tec_screen_pixel_size_m = pixel_size_m;
486 }
487
oskar_telescope_set_tec_screen_time_interval(oskar_Telescope * model,double time_interval_sec)488 void oskar_telescope_set_tec_screen_time_interval(oskar_Telescope* model,
489 double time_interval_sec)
490 {
491 model->tec_screen_time_interval_sec = time_interval_sec;
492 }
493
oskar_telescope_set_tec_screen_path(oskar_Telescope * model,const char * path)494 void oskar_telescope_set_tec_screen_path(oskar_Telescope* model,
495 const char* path)
496 {
497 int status = 0;
498 const size_t len = 1 + strlen(path);
499 oskar_mem_realloc(model->tec_screen_path, len, &status);
500 memcpy(oskar_mem_void(model->tec_screen_path), path, len);
501 }
502
oskar_telescope_set_channel_bandwidth(oskar_Telescope * model,double bandwidth_hz)503 void oskar_telescope_set_channel_bandwidth(oskar_Telescope* model,
504 double bandwidth_hz)
505 {
506 model->channel_bandwidth_hz = bandwidth_hz;
507 }
508
oskar_telescope_set_time_average(oskar_Telescope * model,double time_average_sec)509 void oskar_telescope_set_time_average(oskar_Telescope* model,
510 double time_average_sec)
511 {
512 model->time_average_sec = time_average_sec;
513 }
514
oskar_telescope_set_station_type_p(oskar_Station * station,int type)515 static void oskar_telescope_set_station_type_p(oskar_Station* station, int type)
516 {
517 oskar_station_set_station_type(station, type);
518 if (oskar_station_has_child(station))
519 {
520 int i = 0, num_elements = 0;
521 num_elements = oskar_station_num_elements(station);
522 for (i = 0; i < num_elements; ++i)
523 {
524 oskar_telescope_set_station_type_p(
525 oskar_station_child(station, i), type);
526 }
527 }
528 }
529
oskar_telescope_set_station_type(oskar_Telescope * model,const char * type,int * status)530 void oskar_telescope_set_station_type(oskar_Telescope* model, const char* type,
531 int* status)
532 {
533 int i = 0, t = 0;
534 if (*status) return;
535 if (!strncmp(type, "A", 1) || !strncmp(type, "a", 1))
536 {
537 t = OSKAR_STATION_TYPE_AA;
538 }
539 else if (!strncmp(type, "G", 1) || !strncmp(type, "g", 1))
540 {
541 t = OSKAR_STATION_TYPE_GAUSSIAN_BEAM;
542 }
543 else if (!strncmp(type, "I", 1) || !strncmp(type, "i", 1))
544 {
545 t = OSKAR_STATION_TYPE_ISOTROPIC;
546 }
547 else if (!strncmp(type, "V", 1) || !strncmp(type, "v", 1))
548 {
549 t = OSKAR_STATION_TYPE_VLA_PBCOR;
550 }
551 else
552 {
553 *status = OSKAR_ERR_INVALID_ARGUMENT;
554 return;
555 }
556 for (i = 0; i < model->num_station_models; ++i)
557 {
558 oskar_telescope_set_station_type_p(model->station[i], t);
559 }
560 }
561
oskar_telescope_set_unique_stations(oskar_Telescope * model,int value,int * status)562 void oskar_telescope_set_unique_stations(oskar_Telescope* model,
563 int value, int* status)
564 {
565 if (value)
566 {
567 int i = 0;
568 int* type_map = oskar_mem_int(model->station_type_map, status);
569 for (i = 0; i < model->num_stations; ++i) type_map[i] = i;
570 }
571 else
572 {
573 oskar_mem_clear_contents(model->station_type_map, status);
574 }
575 }
576
oskar_telescope_set_uv_filter(oskar_Telescope * model,double uv_filter_min,double uv_filter_max,const char * units,int * status)577 void oskar_telescope_set_uv_filter(oskar_Telescope* model,
578 double uv_filter_min, double uv_filter_max, const char* units,
579 int* status)
580 {
581 if (!strncmp(units, "M", 1) || !strncmp(units, "m", 1))
582 {
583 model->uv_filter_units = OSKAR_METRES;
584 }
585 else if (!strncmp(units, "W", 1) || !strncmp(units, "w", 1))
586 {
587 model->uv_filter_units = OSKAR_WAVELENGTHS;
588 }
589 else
590 {
591 *status = OSKAR_ERR_INVALID_ARGUMENT;
592 return;
593 }
594 model->uv_filter_min = uv_filter_min;
595 model->uv_filter_max = uv_filter_max;
596 }
597
oskar_telescope_set_pol_mode(oskar_Telescope * model,const char * mode,int * status)598 void oskar_telescope_set_pol_mode(oskar_Telescope* model, const char* mode,
599 int* status)
600 {
601 if (*status) return;
602 if (!strncmp(mode, "S", 1) || !strncmp(mode, "s", 1))
603 {
604 model->pol_mode = OSKAR_POL_MODE_SCALAR;
605 }
606 else if (!strncmp(mode, "F", 1) || !strncmp(mode, "f", 1))
607 {
608 model->pol_mode = OSKAR_POL_MODE_FULL;
609 }
610 else
611 {
612 *status = OSKAR_ERR_INVALID_ARGUMENT;
613 }
614 }
615
616 #ifdef __cplusplus
617 }
618 #endif
619