3 This is the TRMM Office Radar Software Library.
4 Copyright (C) 1996, 1997
6 Space Applications Corporation
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License as published by the Free Software Foundation; either
12 version 2 of the License, or (at your option) any later version.
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Library General Public License for more details.
19 You should have received a copy of the GNU Library General Public
20 License along with this library; if not, write to the Free
21 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * Creates an array that is located in each sweep structure that is
25 * a hash for quick azimuth angle lookups. These routines in concert
26 * with rewrites of the 'RSL_get_value...' routines dramatically speed
29 * The following routines are affected by this change. Just so you don't
30 * think I'm absentminded, I list what might be affected and illustrate that
34 * --------------- ------------
40 * RSL_nsig_to_radar No.
41 * RSL_toga_to_radar No.
42 * RSL_lassen_to_radar No.
44 * RSL_get_value_from_ray Yes.
49 * Space Applications Corporation
58 extern int radar_verbose_flag;
60 /*********************************************************************/
62 /* set_high_and_low_pointers */
64 /* By Dennis Flanigan */
66 /*********************************************************************/
67 static void set_high_and_low_pointers(Hash_table *table)
69 /* This function modifies its argument. */
71 Azimuth_hash *last,*current,*ray_prev_ind;
72 Azimuth_hash *one,*two,*three,*four,*very_first,*very_last;
76 /* Set ray_high,ray_low pointers in hash data structures.
78 if (table == NULL) return;
84 for(i = 0; i < table->nindexes;i++)
86 if(table->indexes[i] != NULL)
88 if(ray_prev_ind != NULL)
90 /* Connect last ray in last index to first ray in
93 ray_prev_ind->ray_high = table->indexes[i];
94 table->indexes[i]->ray_low = ray_prev_ind;
97 /* Connect all entries in this indexes. Don't worry
98 * about ray angle order right now.
100 current = table->indexes[i];
104 current = current->next;
106 last->ray_high = current;
107 current->ray_low = last;
110 /* Set ray_high and ray_low so that entries are "sorted" */
111 not_sorted_flag = 1; /* TRUE */
112 while(not_sorted_flag)
114 current = table->indexes[i];
115 not_sorted_flag = 0; /* FALSE */
118 /* last = current; */
119 current = current->next;
121 if(current->ray_low != NULL)
123 /* Someday want to test ray_angle */
124 if(current->ray_low->ray->h.azimuth > current->ray->h.azimuth)
126 /* Need to switch the ray_high and ray_low
127 * pointers so that order is one three two four.
129 not_sorted_flag = 1; /* TRUE */
130 one = current->ray_low->ray_low;
131 two = current->ray_low;
133 four = current->ray_high;
135 if(one != NULL) one->ray_high = three;
136 two->ray_low = three;
137 two->ray_high = four;
138 three->ray_low = one;
139 three->ray_high = two;
140 if(four != NULL) four->ray_low = two;
146 /* Save highest ray angle entry in index so that it may
147 * be connected to first entry of next index. The
148 * very_last pointer will be used to set very_first
151 current = table->indexes[i];
152 while(current->ray_high) current = current->ray_high;
153 ray_prev_ind = current;
156 /* If this is first non-NULL hash index, save lowest
159 if(very_first == NULL)
161 current = table->indexes[i];
162 while(current->ray_low) current = current->ray_low;
163 very_first = current;
168 /* Tie the first and last azimuth_hash's together.
169 * (Future If PPI_SWEEP statement....)
171 very_first->ray_low = very_last;
172 very_last->ray_high = very_first;
177 static Azimuth_hash *hash_add_node(Azimuth_hash *node, void *ray)
179 Azimuth_hash *new_node;
181 new_node = (Azimuth_hash *)calloc(1, sizeof(Azimuth_hash));
182 if (new_node == NULL) perror("hash_add_node");
185 new_node->next = node;
190 Hash_table *construct_sweep_hash_table(Sweep *s)
192 Hash_table *hash_table;
197 if (s == NULL) return NULL;
198 hash_table = (Hash_table *) calloc(1, sizeof(Hash_table));
199 hash_table->nindexes = s->h.nrays;
200 if (hash_table->nindexes < 0) {
201 fprintf(stderr, "Unable to construct sweep hash table because nrays = %d\n", s->h.nrays);
202 fprintf(stderr, "FATAL error... unable to continue.\n");
206 res = 360.0 / hash_table->nindexes;
207 /* Check that this makes sense with beam width. */
208 if ((res > 2*s->h.beam_width) && (s->h.beam_width != 0)) {
209 /* Problem. Too few rays so force a
210 * reasonable hash table size
212 hash_table->nindexes = 360.0 / s->h.beam_width;
213 res = s->h.beam_width;
215 hash_table->indexes = (Azimuth_hash **)calloc(hash_table->nindexes, sizeof(Azimuth_hash *));
216 if (hash_table->indexes == NULL) {
217 if (radar_verbose_flag) perror("construct_sweep_hash_table");
221 for (i=0; i<s->h.nrays; i++) {
223 if (ray == NULL) continue;
224 iazim = (int)(ray->h.azimuth/res + res/2.0); /* Centered on bin. */
225 if (iazim >= hash_table->nindexes) iazim -= hash_table->nindexes ;
226 /* fprintf(stderr,"ray# %d, azim %f, iazim %d\n", ray->h.ray_num, ray->h.azimuth, iazim); */
227 if (iazim > hash_table->nindexes || iazim < 0) {
228 if (radar_verbose_flag){
229 fprintf(stderr,"ERROR: ");
230 fprintf(stderr,"ray# %d, azim %f, iazim %d, nrays %d, nindexes %d\n", ray->h.ray_num, ray->h.azimuth, iazim, s->h.nrays, hash_table->nindexes);
233 hash_table->indexes[iazim] = hash_add_node(hash_table->indexes[iazim], ray);
237 set_high_and_low_pointers(hash_table);