]> Pileus Git - ~andy/rsl/blob - ray_indexes.c
RSL v1.44
[~andy/rsl] / ray_indexes.c
1 /*
2     NASA/TRMM, Code 910.1.
3     This is the TRMM Office Radar Software Library.
4     Copyright (C) 1996, 1997
5             John H. Merritt
6             Space Applications Corporation
7             Vienna, Virginia
8
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.
13
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.
18
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.
22 */
23 /*
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
27  * up the RSL.
28  *
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
31  * they're not.
32  *
33  *   Routine                Affected?
34  *   ---------------        ------------
35  *   RSL_copy_sweep         No.
36  *   RSL_clear_sweep        No.
37  *   RSL_read_radar         No.
38  *   RSL_write_radar        No.
39  *   RSL_uf_to_radar        No.
40  *   RSL_nsig_to_radar      No.
41  *   RSL_toga_to_radar      No.
42  *   RSL_lassen_to_radar    No.
43  *   RSL_new_sweep          Yes.
44  *   RSL_get_value_from_ray Yes.
45  *   RSL_get...             No.
46  
47  *
48  * By: John Merritt
49  *     Space Applications Corporation
50  *     October 10, 1995
51  *
52  */
53
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57 #include "rsl.h"
58 extern int radar_verbose_flag;
59
60 /*********************************************************************/
61 /*                                                                   */
62 /*          set_high_and_low_pointers                                */
63 /*                                                                   */
64 /* By Dennis Flanigan                                                */
65 /* 5/2/95                                                            */
66 /*********************************************************************/
67 static void set_high_and_low_pointers(Hash_table *table)
68    {
69          /* This function modifies its argument. */
70
71    Azimuth_hash *last,*current,*ray_prev_ind;
72    Azimuth_hash *one,*two,*three,*four,*very_first,*very_last;
73    int not_sorted_flag;
74    int i;
75
76    /* Set ray_high,ray_low pointers in hash data structures.
77     */
78    if (table == NULL) return;
79    very_first = NULL;
80    very_last = NULL;
81    last = NULL;
82    current = NULL;
83    ray_prev_ind = NULL;
84    for(i = 0; i < table->nindexes;i++)
85       {
86       if(table->indexes[i] != NULL)
87          {
88          if(ray_prev_ind != NULL)
89             {
90             /* Connect last ray in last index to first ray in 
91              * this index.
92              */
93             ray_prev_ind->ray_high = table->indexes[i];
94             table->indexes[i]->ray_low = ray_prev_ind;
95             }
96
97          /* Connect all entries in this indexes.  Don't worry
98           * about ray angle order right now.
99           */
100          current = table->indexes[i];
101          while(current->next)
102             {
103             last = current;
104             current = current->next;
105                    
106             last->ray_high = current;
107             current->ray_low = last;
108             }
109
110          /* Set ray_high and ray_low so that entries are "sorted" */
111          not_sorted_flag = 1;  /* TRUE */
112          while(not_sorted_flag)
113             {
114             current = table->indexes[i];
115             not_sorted_flag = 0;  /* FALSE */
116             while(current->next)
117                {
118                /* last = current; */
119                current = current->next;
120                           
121                if(current->ray_low != NULL)
122                   {
123                   /* Someday want to test ray_angle */
124                   if(current->ray_low->ray->h.azimuth > current->ray->h.azimuth)
125                      {
126                      /* Need to switch the ray_high and ray_low
127                       * pointers so that order is one three two four.
128                       */
129                      not_sorted_flag = 1;  /* TRUE */
130                      one   = current->ray_low->ray_low;
131                      two   = current->ray_low;
132                      three = current;
133                      four  = current->ray_high;
134                                         
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;
141                      }
142                   }
143                }
144             }
145
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
149           * pointer.
150           */
151          current = table->indexes[i];
152          while(current->ray_high) current = current->ray_high;
153          ray_prev_ind = current;
154          very_last = current;
155
156          /* If this is first non-NULL hash index, save lowest
157           * ray angle.
158           */
159          if(very_first == NULL)
160             {
161             current = table->indexes[i];
162             while(current->ray_low) current = current->ray_low;
163             very_first = current;
164             }
165          }
166       }
167
168    /* Tie the first and last azimuth_hash's together.
169     * (Future If PPI_SWEEP statement....)
170     */
171    very_first->ray_low = very_last;
172    very_last->ray_high = very_first;
173    }
174
175
176
177 static Azimuth_hash *hash_add_node(Azimuth_hash *node, void *ray)
178 {
179   Azimuth_hash *new_node;
180   
181   new_node = (Azimuth_hash *)calloc(1, sizeof(Azimuth_hash));
182   if (new_node == NULL) perror("hash_add_node");
183   else {
184    new_node->ray = ray;
185    new_node->next = node;
186  }
187   return new_node;
188 }
189
190 Hash_table *construct_sweep_hash_table(Sweep *s)
191 {
192   Hash_table *hash_table;
193   int i, iazim;
194   Ray *ray;
195   float res;
196   
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");
203         exit(-1);
204   }
205
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
211          */
212         hash_table->nindexes = 360.0 / s->h.beam_width;
213         res = s->h.beam_width;
214   }
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");
218         return hash_table;
219   }
220   
221   for (i=0; i<s->h.nrays; i++) {
222         ray = s->ray[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);
231    }
232         } else
233       hash_table->indexes[iazim] = hash_add_node(hash_table->indexes[iazim], ray);
234
235   }
236   
237   set_high_and_low_pointers(hash_table);
238   return hash_table;
239 }
240
241