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/station/private_station.h"
7 #include "telescope/station/oskar_station_accessors.h"
8
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12
13
14 /* Data common to all station types. */
15
oskar_station_unique_id(const oskar_Station * model)16 int oskar_station_unique_id(const oskar_Station* model)
17 {
18 return model ? model->unique_id : 0;
19 }
20
oskar_station_precision(const oskar_Station * model)21 int oskar_station_precision(const oskar_Station* model)
22 {
23 return model ? model->precision : 0;
24 }
25
oskar_station_mem_location(const oskar_Station * model)26 int oskar_station_mem_location(const oskar_Station* model)
27 {
28 return model ? model->mem_location : 0;
29 }
30
oskar_station_type(const oskar_Station * model)31 int oskar_station_type(const oskar_Station* model)
32 {
33 return model ? model->station_type : 0;
34 }
35
oskar_station_normalise_final_beam(const oskar_Station * model)36 int oskar_station_normalise_final_beam(const oskar_Station* model)
37 {
38 return model ? model->normalise_final_beam : 0;
39 }
40
oskar_station_lon_rad(const oskar_Station * model)41 double oskar_station_lon_rad(const oskar_Station* model)
42 {
43 return model ? model->lon_rad : 0.0;
44 }
45
oskar_station_lat_rad(const oskar_Station * model)46 double oskar_station_lat_rad(const oskar_Station* model)
47 {
48 return model ? model->lat_rad : 0.0;
49 }
50
oskar_station_alt_metres(const oskar_Station * model)51 double oskar_station_alt_metres(const oskar_Station* model)
52 {
53 return model ? model->alt_metres : 0.0;
54 }
55
oskar_station_offset_ecef_x(const oskar_Station * model)56 double oskar_station_offset_ecef_x(const oskar_Station* model)
57 {
58 return model ? model->offset_ecef[0] : 0.0;
59 }
60
oskar_station_offset_ecef_y(const oskar_Station * model)61 double oskar_station_offset_ecef_y(const oskar_Station* model)
62 {
63 return model ? model->offset_ecef[1] : 0.0;
64 }
65
oskar_station_offset_ecef_z(const oskar_Station * model)66 double oskar_station_offset_ecef_z(const oskar_Station* model)
67 {
68 return model ? model->offset_ecef[2] : 0.0;
69 }
70
oskar_station_polar_motion_x_rad(const oskar_Station * model)71 double oskar_station_polar_motion_x_rad(const oskar_Station* model)
72 {
73 return model ? model->pm_x_rad : 0.0;
74 }
75
oskar_station_polar_motion_y_rad(const oskar_Station * model)76 double oskar_station_polar_motion_y_rad(const oskar_Station* model)
77 {
78 return model ? model->pm_y_rad : 0.0;
79 }
80
oskar_station_beam_lon_rad(const oskar_Station * model)81 double oskar_station_beam_lon_rad(const oskar_Station* model)
82 {
83 return model ? model->beam_lon_rad : 0.0;
84 }
85
oskar_station_beam_lat_rad(const oskar_Station * model)86 double oskar_station_beam_lat_rad(const oskar_Station* model)
87 {
88 return model ? model->beam_lat_rad : 0.0;
89 }
90
oskar_station_beam_coord_type(const oskar_Station * model)91 int oskar_station_beam_coord_type(const oskar_Station* model)
92 {
93 return model ? model->beam_coord_type : 0;
94 }
95
oskar_station_noise_freq_hz(oskar_Station * model)96 oskar_Mem* oskar_station_noise_freq_hz(oskar_Station* model)
97 {
98 return model ? model->noise_freq_hz : 0;
99 }
100
oskar_station_noise_freq_hz_const(const oskar_Station * model)101 const oskar_Mem* oskar_station_noise_freq_hz_const(const oskar_Station* model)
102 {
103 return model ? model->noise_freq_hz : 0;
104 }
105
oskar_station_noise_rms_jy(oskar_Station * model)106 oskar_Mem* oskar_station_noise_rms_jy(oskar_Station* model)
107 {
108 return model ? model->noise_rms_jy : 0;
109 }
110
oskar_station_noise_rms_jy_const(const oskar_Station * model)111 const oskar_Mem* oskar_station_noise_rms_jy_const(const oskar_Station* model)
112 {
113 return model ? model->noise_rms_jy : 0;
114 }
115
116 /* Data used only for Gaussian beam stations. */
117
oskar_station_gaussian_beam_fwhm_rad(const oskar_Station * model)118 double oskar_station_gaussian_beam_fwhm_rad(const oskar_Station* model)
119 {
120 return model ? model->gaussian_beam_fwhm_rad : 0.0;
121 }
122
oskar_station_gaussian_beam_reference_freq_hz(const oskar_Station * model)123 double oskar_station_gaussian_beam_reference_freq_hz(const oskar_Station* model)
124 {
125 return model ? model->gaussian_beam_reference_freq_hz : 0.0;
126 }
127
128 /* Data used only for aperture array stations. */
129
oskar_station_identical_children(const oskar_Station * model)130 int oskar_station_identical_children(const oskar_Station* model)
131 {
132 return model ? model->identical_children : 0;
133 }
134
oskar_station_num_elements(const oskar_Station * model)135 int oskar_station_num_elements(const oskar_Station* model)
136 {
137 return model ? model->num_elements : 0;
138 }
139
oskar_station_num_element_types(const oskar_Station * model)140 int oskar_station_num_element_types(const oskar_Station* model)
141 {
142 return model ? model->num_element_types : 0;
143 }
144
oskar_station_normalise_array_pattern(const oskar_Station * model)145 int oskar_station_normalise_array_pattern(const oskar_Station* model)
146 {
147 return model ? model->normalise_array_pattern : 0;
148 }
149
oskar_station_normalise_element_pattern(const oskar_Station * model)150 int oskar_station_normalise_element_pattern(const oskar_Station* model)
151 {
152 return model ? model->normalise_element_pattern : 0;
153 }
154
oskar_station_enable_array_pattern(const oskar_Station * model)155 int oskar_station_enable_array_pattern(const oskar_Station* model)
156 {
157 return model ? model->enable_array_pattern : 0;
158 }
159
oskar_station_common_element_orientation(const oskar_Station * model)160 int oskar_station_common_element_orientation(const oskar_Station* model)
161 {
162 return model ? model->common_element_orientation : 0;
163 }
164
oskar_station_common_pol_beams(const oskar_Station * model)165 int oskar_station_common_pol_beams(const oskar_Station* model)
166 {
167 return model ? model->common_pol_beams : 0;
168 }
169
oskar_station_array_is_3d(const oskar_Station * model)170 int oskar_station_array_is_3d(const oskar_Station* model)
171 {
172 return model ? model->array_is_3d : 0;
173 }
174
oskar_station_apply_element_errors(const oskar_Station * model)175 int oskar_station_apply_element_errors(const oskar_Station* model)
176 {
177 return model ? model->apply_element_errors : 0;
178 }
179
oskar_station_apply_element_weight(const oskar_Station * model)180 int oskar_station_apply_element_weight(const oskar_Station* model)
181 {
182 return model ? model->apply_element_weight : 0;
183 }
184
oskar_station_seed_time_variable_errors(const oskar_Station * model)185 unsigned int oskar_station_seed_time_variable_errors(const oskar_Station* model)
186 {
187 return model ? model->seed_time_variable_errors : 0u;
188 }
189
oskar_station_swap_xy(const oskar_Station * model)190 int oskar_station_swap_xy(const oskar_Station* model)
191 {
192 return model ? model->swap_xy : 0;
193 }
194
oskar_station_element_euler_index_rad(const oskar_Station * model,int feed,int dim,int index)195 double oskar_station_element_euler_index_rad(
196 const oskar_Station* model, int feed, int dim, int index)
197 {
198 const oskar_Mem* ptr = 0;
199 if (!model || feed > 1 || dim > 2) return 0.0;
200 ptr = model->element_euler_cpu[feed][dim];
201 if (!ptr) ptr = model->element_euler_cpu[0][dim];
202 return ptr ? ((const double*) oskar_mem_void_const(ptr))[index] : 0.0;
203 }
204
oskar_station_element_euler_rad(oskar_Station * model,int feed,int dim)205 oskar_Mem* oskar_station_element_euler_rad(
206 oskar_Station* model, int feed, int dim)
207 {
208 oskar_Mem* ptr = 0;
209 if (!model || feed > 1 || dim > 2) return 0;
210 ptr = model->element_euler_cpu[feed][dim];
211 return ptr ? ptr : model->element_euler_cpu[0][dim];
212 }
213
oskar_station_element_euler_rad_const(const oskar_Station * model,int feed,int dim)214 const oskar_Mem* oskar_station_element_euler_rad_const(
215 const oskar_Station* model, int feed, int dim)
216 {
217 const oskar_Mem* ptr = 0;
218 if (!model || feed > 1 || dim > 2) return 0;
219 ptr = model->element_euler_cpu[feed][dim];
220 return ptr ? ptr : model->element_euler_cpu[0][dim];
221 }
222
oskar_station_element_true_enu_metres(oskar_Station * model,int feed,int dim)223 oskar_Mem* oskar_station_element_true_enu_metres(
224 oskar_Station* model, int feed, int dim)
225 {
226 oskar_Mem* ptr = 0;
227 if (!model || feed > 1 || dim > 2) return 0;
228 ptr = model->element_true_enu_metres[feed][dim];
229 return ptr ? ptr : model->element_true_enu_metres[0][dim];
230 }
231
oskar_station_element_true_enu_metres_const(const oskar_Station * model,int feed,int dim)232 const oskar_Mem* oskar_station_element_true_enu_metres_const(
233 const oskar_Station* model, int feed, int dim)
234 {
235 const oskar_Mem* ptr = 0;
236 if (!model || feed > 1 || dim > 2) return 0;
237 ptr = model->element_true_enu_metres[feed][dim];
238 return ptr ? ptr : model->element_true_enu_metres[0][dim];
239 }
240
oskar_station_element_measured_enu_metres(oskar_Station * model,int feed,int dim)241 oskar_Mem* oskar_station_element_measured_enu_metres(
242 oskar_Station* model, int feed, int dim)
243 {
244 oskar_Mem* ptr = 0;
245 if (!model || feed > 1 || dim > 2) return 0;
246 ptr = model->element_measured_enu_metres[feed][dim];
247 return ptr ? ptr : model->element_measured_enu_metres[0][dim];
248 }
249
oskar_station_element_measured_enu_metres_const(const oskar_Station * model,int feed,int dim)250 const oskar_Mem* oskar_station_element_measured_enu_metres_const(
251 const oskar_Station* model, int feed, int dim)
252 {
253 const oskar_Mem* ptr = 0;
254 if (!model || feed > 1 || dim > 2) return 0;
255 ptr = model->element_measured_enu_metres[feed][dim];
256 return ptr ? ptr : model->element_measured_enu_metres[0][dim];
257 }
258
oskar_station_element_cable_length_error_metres(oskar_Station * model,int feed)259 oskar_Mem* oskar_station_element_cable_length_error_metres(
260 oskar_Station* model, int feed)
261 {
262 oskar_Mem* ptr = 0;
263 if (!model || feed > 1) return 0;
264 ptr = model->element_cable_length_error[feed];
265 return ptr ? ptr : model->element_cable_length_error[0];
266 }
267
oskar_station_element_cable_length_error_metres_const(const oskar_Station * model,int feed)268 const oskar_Mem* oskar_station_element_cable_length_error_metres_const(
269 const oskar_Station* model, int feed)
270 {
271 const oskar_Mem* ptr = 0;
272 if (!model || feed > 1) return 0;
273 ptr = model->element_cable_length_error[feed];
274 return ptr ? ptr : model->element_cable_length_error[0];
275 }
276
oskar_station_element_gain(oskar_Station * model,int feed)277 oskar_Mem* oskar_station_element_gain(oskar_Station* model, int feed)
278 {
279 oskar_Mem* ptr = 0;
280 if (!model || feed > 1) return 0;
281 ptr = model->element_gain[feed];
282 return ptr ? ptr : model->element_gain[0];
283 }
284
oskar_station_element_gain_const(const oskar_Station * model,int feed)285 const oskar_Mem* oskar_station_element_gain_const(
286 const oskar_Station* model, int feed)
287 {
288 const oskar_Mem* ptr = 0;
289 if (!model || feed > 1) return 0;
290 ptr = model->element_gain[feed];
291 return ptr ? ptr : model->element_gain[0];
292 }
293
oskar_station_element_gain_error(oskar_Station * model,int feed)294 oskar_Mem* oskar_station_element_gain_error(oskar_Station* model, int feed)
295 {
296 oskar_Mem* ptr = 0;
297 if (!model || feed > 1) return 0;
298 ptr = model->element_gain_error[feed];
299 return ptr ? ptr : model->element_gain_error[0];
300 }
301
oskar_station_element_gain_error_const(const oskar_Station * model,int feed)302 const oskar_Mem* oskar_station_element_gain_error_const(
303 const oskar_Station* model, int feed)
304 {
305 const oskar_Mem* ptr = 0;
306 if (!model || feed > 1) return 0;
307 ptr = model->element_gain_error[feed];
308 return ptr ? ptr : model->element_gain_error[0];
309 }
310
oskar_station_element_phase_offset_rad(oskar_Station * model,int feed)311 oskar_Mem* oskar_station_element_phase_offset_rad(
312 oskar_Station* model, int feed)
313 {
314 oskar_Mem* ptr = 0;
315 if (!model || feed > 1) return 0;
316 ptr = model->element_phase_offset_rad[feed];
317 return ptr ? ptr : model->element_phase_offset_rad[0];
318 }
319
oskar_station_element_phase_offset_rad_const(const oskar_Station * model,int feed)320 const oskar_Mem* oskar_station_element_phase_offset_rad_const(
321 const oskar_Station* model, int feed)
322 {
323 const oskar_Mem* ptr = 0;
324 if (!model || feed > 1) return 0;
325 ptr = model->element_phase_offset_rad[feed];
326 return ptr ? ptr : model->element_phase_offset_rad[0];
327 }
328
oskar_station_element_phase_error_rad(oskar_Station * model,int feed)329 oskar_Mem* oskar_station_element_phase_error_rad(
330 oskar_Station* model, int feed)
331 {
332 oskar_Mem* ptr = 0;
333 if (!model || feed > 1) return 0;
334 ptr = model->element_phase_error_rad[feed];
335 return ptr ? ptr : model->element_phase_error_rad[0];
336 }
337
oskar_station_element_phase_error_rad_const(const oskar_Station * model,int feed)338 const oskar_Mem* oskar_station_element_phase_error_rad_const(
339 const oskar_Station* model, int feed)
340 {
341 const oskar_Mem* ptr = 0;
342 if (!model || feed > 1) return 0;
343 ptr = model->element_phase_error_rad[feed];
344 return ptr ? ptr : model->element_phase_error_rad[0];
345 }
346
oskar_station_element_weight(oskar_Station * model,int feed)347 oskar_Mem* oskar_station_element_weight(oskar_Station* model, int feed)
348 {
349 oskar_Mem* ptr = 0;
350 if (!model || feed > 1) return 0;
351 ptr = model->element_weight[feed];
352 return ptr ? ptr : model->element_weight[0];
353 }
354
oskar_station_element_weight_const(const oskar_Station * model,int feed)355 const oskar_Mem* oskar_station_element_weight_const(
356 const oskar_Station* model, int feed)
357 {
358 const oskar_Mem* ptr = 0;
359 if (!model || feed > 1) return 0;
360 ptr = model->element_weight[feed];
361 return ptr ? ptr : model->element_weight[0];
362 }
363
oskar_station_element_types(oskar_Station * model)364 oskar_Mem* oskar_station_element_types(oskar_Station* model)
365 {
366 return model ? model->element_types : 0;
367 }
368
oskar_station_element_types_const(const oskar_Station * model)369 const oskar_Mem* oskar_station_element_types_const(const oskar_Station* model)
370 {
371 return model ? model->element_types : 0;
372 }
373
oskar_station_element_types_cpu_const(const oskar_Station * model)374 const int* oskar_station_element_types_cpu_const(const oskar_Station* model)
375 {
376 if (!model) return 0;
377 return (const int*) oskar_mem_void_const(model->element_types_cpu);
378 }
379
oskar_station_element_mount_types_const(const oskar_Station * model)380 const char* oskar_station_element_mount_types_const(const oskar_Station* model)
381 {
382 if (!model) return 0;
383 return oskar_mem_char_const(model->element_mount_types_cpu);
384 }
385
oskar_station_has_child(const oskar_Station * model)386 int oskar_station_has_child(const oskar_Station* model)
387 {
388 return model ? (model->child ? 1 : 0) : 0;
389 }
390
oskar_station_child(oskar_Station * model,int i)391 oskar_Station* oskar_station_child(oskar_Station* model, int i)
392 {
393 return model ? model->child[i] : 0;
394 }
395
oskar_station_child_const(const oskar_Station * model,int i)396 const oskar_Station* oskar_station_child_const(const oskar_Station* model,
397 int i)
398 {
399 return model ? model->child[i] : 0;
400 }
401
oskar_station_has_element(const oskar_Station * model)402 int oskar_station_has_element(const oskar_Station* model)
403 {
404 return model ? (model->element ? 1 : 0) : 0;
405 }
406
oskar_station_element(oskar_Station * model,int element_type_index)407 oskar_Element* oskar_station_element(oskar_Station* model,
408 int element_type_index)
409 {
410 return model ? model->element[element_type_index] : 0;
411 }
412
oskar_station_element_const(const oskar_Station * model,int element_type_index)413 const oskar_Element* oskar_station_element_const(const oskar_Station* model,
414 int element_type_index)
415 {
416 return model ? model->element[element_type_index] : 0;
417 }
418
oskar_station_num_permitted_beams(const oskar_Station * model)419 int oskar_station_num_permitted_beams(const oskar_Station* model)
420 {
421 return model ? model->num_permitted_beams : 0;
422 }
423
oskar_station_permitted_beam_az_rad_const(const oskar_Station * model)424 const oskar_Mem* oskar_station_permitted_beam_az_rad_const(
425 const oskar_Station* model)
426 {
427 return model ? model->permitted_beam_az_rad : 0;
428 }
429
oskar_station_permitted_beam_el_rad_const(const oskar_Station * model)430 const oskar_Mem* oskar_station_permitted_beam_el_rad_const(
431 const oskar_Station* model)
432 {
433 return model ? model->permitted_beam_el_rad : 0;
434 }
435
436
437 /* Setters. */
438
oskar_station_set_unique_ids(oskar_Station * model,int * counter)439 void oskar_station_set_unique_ids(oskar_Station* model, int* counter)
440 {
441 if (!model) return;
442 model->unique_id = (*counter)++;
443 if (model->child)
444 {
445 int i = 0;
446 for (i = 0; i < model->num_elements; ++i)
447 {
448 oskar_station_set_unique_ids(model->child[i], counter);
449 }
450 }
451 }
452
oskar_station_set_station_type(oskar_Station * model,int type)453 void oskar_station_set_station_type(oskar_Station* model, int type)
454 {
455 if (!model) return;
456 model->station_type = type;
457 }
458
oskar_station_set_normalise_final_beam(oskar_Station * model,int value)459 void oskar_station_set_normalise_final_beam(oskar_Station* model, int value)
460 {
461 if (!model) return;
462 model->normalise_final_beam = value;
463 }
464
oskar_station_set_position(oskar_Station * model,double longitude_rad,double latitude_rad,double altitude_m,double offset_ecef_x,double offset_ecef_y,double offset_ecef_z)465 void oskar_station_set_position(oskar_Station* model,
466 double longitude_rad, double latitude_rad, double altitude_m,
467 double offset_ecef_x, double offset_ecef_y, double offset_ecef_z)
468 {
469 if (!model) return;
470 model->lon_rad = longitude_rad;
471 model->lat_rad = latitude_rad;
472 model->alt_metres = altitude_m;
473 model->offset_ecef[0] = offset_ecef_x;
474 model->offset_ecef[1] = offset_ecef_y;
475 model->offset_ecef[2] = offset_ecef_z;
476 }
477
oskar_station_set_polar_motion(oskar_Station * model,double pm_x_rad,double pm_y_rad)478 void oskar_station_set_polar_motion(oskar_Station* model,
479 double pm_x_rad, double pm_y_rad)
480 {
481 int i = 0;
482 if (!model) return;
483 model->pm_x_rad = pm_x_rad;
484 model->pm_y_rad = pm_y_rad;
485
486 /* Set recursively for all child stations. */
487 if (oskar_station_has_child(model))
488 {
489 for (i = 0; i < model->num_elements; ++i)
490 {
491 oskar_station_set_polar_motion(model->child[i], pm_x_rad, pm_y_rad);
492 }
493 }
494 }
495
oskar_station_set_phase_centre(oskar_Station * model,int coord_type,double longitude_rad,double latitude_rad)496 void oskar_station_set_phase_centre(oskar_Station* model,
497 int coord_type, double longitude_rad, double latitude_rad)
498 {
499 if (!model) return;
500 model->beam_coord_type = coord_type;
501 model->beam_lon_rad = longitude_rad;
502 model->beam_lat_rad = latitude_rad;
503 }
504
oskar_station_set_gaussian_beam_values(oskar_Station * model,double fwhm_rad,double ref_freq_hz)505 void oskar_station_set_gaussian_beam_values(oskar_Station* model,
506 double fwhm_rad, double ref_freq_hz)
507 {
508 if (!model) return;
509 model->gaussian_beam_fwhm_rad = fwhm_rad;
510 model->gaussian_beam_reference_freq_hz = ref_freq_hz;
511 }
512
oskar_station_set_normalise_array_pattern(oskar_Station * model,int value)513 void oskar_station_set_normalise_array_pattern(oskar_Station* model, int value)
514 {
515 if (!model) return;
516 model->normalise_array_pattern = value;
517 }
518
oskar_station_set_normalise_element_pattern(oskar_Station * model,int value)519 void oskar_station_set_normalise_element_pattern(oskar_Station* model, int value)
520 {
521 if (!model) return;
522 model->normalise_element_pattern = value;
523 }
524
oskar_station_set_enable_array_pattern(oskar_Station * model,int value)525 void oskar_station_set_enable_array_pattern(oskar_Station* model, int value)
526 {
527 if (!model) return;
528 model->enable_array_pattern = value;
529 }
530
oskar_station_set_seed_time_variable_errors(oskar_Station * model,unsigned int value)531 void oskar_station_set_seed_time_variable_errors(oskar_Station* model,
532 unsigned int value)
533 {
534 if (!model) return;
535 model->seed_time_variable_errors = value;
536 }
537
oskar_station_set_swap_xy(oskar_Station * model,int value)538 void oskar_station_set_swap_xy(oskar_Station* model, int value)
539 {
540 if (!model) return;
541 model->swap_xy = value;
542 }
543
544 #ifdef __cplusplus
545 }
546 #endif
547