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.h"
8 
9 #include "mem/oskar_mem.h"
10 #include <stdio.h>
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
oskar_station_different(const oskar_Station * a,const oskar_Station * b,int * status)16 int oskar_station_different(const oskar_Station* a, const oskar_Station* b,
17         int* status)
18 {
19     int i = 0, j = 0, n = 0, feed = 0, dim = 0;
20     if (!a || !b) return 0;
21     if (*status) return 1;
22 
23     /* Don't check the unique ID, for obvious reasons! */
24     /* Check if the meta-data are different. */
25     n = a->num_elements;
26     if (a->station_type != b->station_type ||
27             a->normalise_final_beam != b->normalise_final_beam ||
28             a->beam_coord_type != b->beam_coord_type ||
29             a->beam_lon_rad != b->beam_lon_rad ||
30             a->beam_lat_rad != b->beam_lat_rad ||
31             a->pm_x_rad != b->pm_x_rad ||
32             a->pm_y_rad != b->pm_y_rad ||
33             a->identical_children != b->identical_children ||
34             a->num_elements != b->num_elements ||
35             a->num_element_types != b->num_element_types ||
36             a->normalise_array_pattern != b->normalise_array_pattern ||
37             a->normalise_element_pattern != b->normalise_element_pattern ||
38             a->enable_array_pattern != b->enable_array_pattern ||
39             a->common_element_orientation != b->common_element_orientation ||
40             a->common_pol_beams != b->common_pol_beams ||
41             a->array_is_3d != b->array_is_3d ||
42             a->apply_element_errors != b->apply_element_errors ||
43             a->apply_element_weight != b->apply_element_weight ||
44             a->gaussian_beam_fwhm_rad != b->gaussian_beam_fwhm_rad ||
45             a->gaussian_beam_reference_freq_hz != b->gaussian_beam_reference_freq_hz ||
46             a->num_permitted_beams != b->num_permitted_beams)
47     {
48         return 1;
49     }
50 
51     /* Check if child stations exist. */
52     if ((oskar_station_has_child(a) && !oskar_station_has_child(b)) ||
53             (!oskar_station_has_child(a) && oskar_station_has_child(b)))
54     {
55         return 1;
56     }
57 
58     /* Check if element patterns exist. */
59     if ( (oskar_station_has_element(a) && !oskar_station_has_element(b)) ||
60             (!oskar_station_has_element(a) && oskar_station_has_element(b)) )
61     {
62         return 1;
63     }
64 
65     /* Check if the memory contents are different. */
66     if (oskar_mem_different(a->noise_freq_hz, b->noise_freq_hz, 0, status))
67     {
68         return 1;
69     }
70     if (oskar_mem_different(a->noise_rms_jy, b->noise_rms_jy, 0, status))
71     {
72         return 1;
73     }
74 
75     for (feed = 0; feed < 2; feed++)
76     {
77         for (dim = 0; dim < 3; dim++)
78         {
79             if (oskar_mem_different(a->element_measured_enu_metres[feed][dim],
80                     b->element_measured_enu_metres[feed][dim], n, status))
81             {
82                 return 1;
83             }
84             if (oskar_mem_different(a->element_true_enu_metres[feed][dim],
85                     b->element_true_enu_metres[feed][dim], n, status))
86             {
87                 return 1;
88             }
89             if (oskar_mem_different(a->element_euler_cpu[feed][dim],
90                     b->element_euler_cpu[feed][dim], n, status))
91             {
92                 return 1;
93             }
94         }
95         if (oskar_mem_different(a->element_gain[feed],
96                 b->element_gain[feed], n, status))
97         {
98             return 1;
99         }
100         if (oskar_mem_different(a->element_phase_offset_rad[feed],
101                 b->element_phase_offset_rad[feed], n, status))
102         {
103             return 1;
104         }
105         if (oskar_mem_different(a->element_weight[feed],
106                 b->element_weight[feed], n, status))
107         {
108             return 1;
109         }
110         if (oskar_mem_different(a->element_cable_length_error[feed],
111                 b->element_cable_length_error[feed], n, status))
112         {
113             return 1;
114         }
115     }
116     if (oskar_mem_different(a->element_types,
117             b->element_types, n, status))
118     {
119         return 1;
120     }
121     if (oskar_mem_different(a->element_types_cpu,
122             b->element_types_cpu, n, status))
123     {
124         return 1;
125     }
126     if (oskar_mem_different(a->element_mount_types_cpu,
127             b->element_mount_types_cpu, n, status))
128     {
129         return 1;
130     }
131     if (oskar_mem_different(a->permitted_beam_az_rad,
132             b->permitted_beam_az_rad, n, status))
133     {
134         return 1;
135     }
136     if (oskar_mem_different(a->permitted_beam_el_rad,
137             b->permitted_beam_el_rad, n, status))
138     {
139         return 1;
140     }
141 
142     /* Check if element pattern filenames are different,
143      * for each element type. */
144     const int num_element_types = oskar_station_num_element_types(a);
145     for (j = 0; j < num_element_types; ++j)
146     {
147         const oskar_Element *e_a = 0, *e_b = 0;
148         e_a = oskar_station_element_const(a, j);
149         e_b = oskar_station_element_const(b, j);
150 
151         /* Check if number of frequencies in element models are different. */
152         const int num_freq_a = oskar_element_num_freq(e_a);
153         const int num_freq_b = oskar_element_num_freq(e_b);
154         if (num_freq_a != num_freq_b)
155         {
156             return 1;
157         }
158 
159         for (i = 0; i < num_freq_a; ++i)
160         {
161             const oskar_Mem *fname_a_x = 0, *fname_a_y = 0;
162             const oskar_Mem *fname_b_x = 0, *fname_b_y = 0;
163 
164             fname_a_x = oskar_element_x_filename_const(e_a, i);
165             fname_a_y = oskar_element_y_filename_const(e_a, i);
166             fname_b_x = oskar_element_x_filename_const(e_b, i);
167             fname_b_y = oskar_element_y_filename_const(e_b, i);
168             if (oskar_mem_different(fname_a_x, fname_b_x, 0, status))
169             {
170                 return 1;
171             }
172             if (oskar_mem_different(fname_a_y, fname_b_y, 0, status))
173             {
174                 return 1;
175             }
176         }
177     }
178 
179     /* Recursively check child stations. */
180     if (oskar_station_has_child(a) && oskar_station_has_child(b))
181     {
182         for (i = 0; i < n; ++i)
183         {
184             if (oskar_station_different(oskar_station_child_const(a, i),
185                     oskar_station_child_const(b, i), status))
186             {
187                 return 1;
188             }
189         }
190     }
191 
192     /* Stations must be the same! */
193     return 0;
194 }
195 
196 #ifdef __cplusplus
197 }
198 #endif
199