]> Pileus Git - ~andy/rsl/blob - cube.c
Changes from Bart (2009-10-28)
[~andy/rsl] / cube.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 /* Mike Kolander
24  * Space Applications Corporation
25  * NASA/Goddard 910.1
26  */
27 #include <stdlib.h>
28 #include <string.h>
29 #include "rsl.h"
30
31 extern int radar_verbose_flag;
32
33 /*************************************************************/
34 /*                                                           */
35 /*                     RSL_free_slice                        */
36 /*                                                           */
37 /*************************************************************/
38 void RSL_free_slice(Slice *slice)
39 {
40         /* Frees memory allocated to a slice structure, and associated
41                  pointer and data arrays.
42   */
43
44         if (slice != NULL)
45         {
46           if (slice->data != NULL)
47                 {
48                         if (slice->data[0] != NULL)
49                     free(slice->data[0]);     /* Free the 2D data array. */
50                         free(slice->data);     /* Free the vector of pointers. */
51                 }
52                 free(slice);   /* Free the slice structure. */
53         }
54 }
55
56 /*************************************************************/
57 /*                                                           */
58 /*                     RSL_new_slice                         */
59 /*                                                           */
60 /*************************************************************/
61 Slice *RSL_new_slice(int nrows, int ncols)
62 {
63         /* Allocates memory for a slice structure, and associated pointer
64                  and data arrays.
65         */
66         Slice *s;
67         Slice_value *data;
68         int row;
69         
70         /* Allocate a slice. */
71         s = (Slice *)calloc(1, sizeof(Slice));
72         if (s == NULL) perror("RSL_new_slice");
73         /* Allocate a vector of 'nrows' pointers. */
74         s->data = (Slice_value **)calloc(nrows, sizeof(Slice_value *));
75         if (s->data == NULL) perror("RSL_new_slice");
76         /* Allocate a 2 dimensional array for the actual data values. */
77         data = (Slice_value *)calloc(nrows*ncols, sizeof(Slice_value));
78         if (data == NULL) perror("RSL_new_slice");
79         /* Fill all the 'nrows' pointer slots created above. */
80         for (row=0; row<nrows; row++)
81                 s->data[row] = data + row*ncols;
82
83         return(s);
84 }
85
86 /*************************************************************/
87 /*                                                           */
88 /*                      RSL_new_cube                         */
89 /*                                                           */
90 /*************************************************************/
91 Cube *RSL_new_cube(int ncarpi)
92 {
93         /* Allocate memory for a cube structure, and an associated array
94                  of carpi pointers.
95   */
96   Cube *cube; 
97
98         cube = (Cube *) calloc(1, sizeof(Cube));
99         if (cube == NULL) return(NULL);
100   cube->carpi = (Carpi **) calloc(ncarpi, sizeof(Carpi *));
101   if (cube->carpi == NULL) return(NULL);
102         return(cube);
103 }
104
105 /*************************************************************/
106 /*                                                           */
107 /*                     RSL_free_cube                         */
108 /*                                                           */
109 /*************************************************************/
110 void RSL_free_cube(Cube *cube)
111 {
112         /* Frees memory allocated to a cube structure and associated
113            carpi structures.
114   */
115         int j;
116         
117         if (cube != NULL)
118         {
119                 if (cube->carpi != NULL)
120                 {
121             for (j=0; j<cube->nz; j++)
122               if (cube->carpi[j] != NULL)
123                 RSL_free_carpi(cube->carpi[j]);
124                         free(cube->carpi);
125                 }
126                 free(cube);
127         }
128 }
129
130 /*************************************************************/
131 /*                                                           */
132 /*                     RSL_volume_to_cube                    */
133 /*                                                           */
134 /*************************************************************/
135 Cube *RSL_volume_to_cube(Volume *v, float dx, float dy, float dz,
136                                           int nx, int ny, int nz, float grnd_r,
137                                           int radar_x, int radar_y, int radar_z)
138 /* radar_z = 0 is the only thing that makes sense. Why pass it? */
139 {
140   float lat=0;
141   float lon=0;
142   int i;
143   Cube *cube;
144   
145   if (v == NULL) return NULL;
146   /* check validity of radar site coordinates in cube. */
147   if (radar_z != 0) return NULL;
148   if ((radar_x < 0) || (radar_x > nx)) return NULL;
149   if ((radar_y < 0) || (radar_y > ny)) return NULL;
150   
151   cube = (Cube *)RSL_new_cube(nz);
152   if (cube == NULL) return NULL;
153
154   cube->nx = nx;
155   cube->ny = ny;
156   cube->nz = nz;
157   cube->dx = dx;
158   cube->dy = dy;
159   cube->dz = dz;
160   if (v->h.type_str != (char *) NULL)
161         cube->data_type = (char *)strdup(v->h.type_str);
162   cube->lat = lat;
163   cube->lon = lon;
164   
165   /* Create nz carpis */
166   for (i=0; i<nz; i++)
167           cube->carpi[i] = (Carpi *)RSL_volume_to_carpi(v, (i+1)*dz, grnd_r,
168                                                                                                                                                                                                         dx, dy, nx, ny,
169                                                                                                                                                                                                         radar_x, radar_y,
170                                                                                                                                                                                                         lat, lon);
171   return cube;
172 }
173
174 /*************************************************************/
175 /*                                                           */
176 /*                  RSL_get_slice_from_cube                  */
177 /*                                                           */
178 /*************************************************************/
179 Slice *RSL_get_slice_from_cube(Cube *cube, int x, int y, int z)
180 /*
181    Check validity of parameters x,y,z , which define the plane of the
182    required slice. Two of the three parameters must equal -1 and the
183    third must be nonnegative; eg, the vertical plane y=100 is 
184    specified by the parameters x=-1, y=100, z=-1
185
186    Assumes valid ranges for x, y, z are:
187       0 <= x <= nx-1 ,    0 <= y <= ny-1 ,    1 <= z <= nz
188    The range of z starts at 1 , since a cappi (or carpi) at 
189    height z=0 makes no sense.
190 */
191 {
192         int i, j;
193         Slice *slice;
194
195         if (cube == NULL) return(NULL);
196
197         /* Slice defined by the plane y = const */
198         if ((x == -1) && (z == -1) && (y > -1) && (y < cube->ny))
199         {
200                 slice = (Slice *) RSL_new_slice(cube->nz, cube->nx);
201                 slice->data_type = (char *)strdup(cube->data_type);
202           slice->dx = cube->dx;
203           slice->dy = cube->dz;
204           slice->nx = cube->nx;
205           slice->ny = cube->nz;
206                 slice->f = cube->carpi[0]->f;
207                 slice->invf = cube->carpi[0]->invf;
208                   /* Retrieve the required data values from the cube and place into
209                          the slice structure. */
210           for (j=0; j<cube->nz; j++)
211                   for (i=0; i<cube->nx; i++)
212                           slice->data[j][i] = (Slice_value) cube->carpi[j]->data[y][i];
213         }
214
215
216         /* Slice defined by the plane x = const */
217         else if ((y == -1) && (z == -1) && (x > -1) && (x < cube->nx))
218         {
219                 slice = (Slice *) RSL_new_slice(cube->nz, cube->ny);
220                 slice->data_type = (char *)strdup(cube->data_type);
221           slice->dx = cube->dy;
222           slice->dy = cube->dz;
223           slice->nx = cube->ny;
224           slice->ny = cube->nz;
225                 slice->f = cube->carpi[0]->f;
226                 slice->invf = cube->carpi[0]->invf;
227           /* Retrieve the required data values from the cube and place into
228                          the slice structure. */
229           for (j=0; j<cube->nz; j++)
230                         for (i=0; i<cube->ny; i++)
231                           slice->data[j][i] = (Slice_value) cube->carpi[j]->data[i][x];
232         }
233
234
235         /* Want slice defined by the plane z = const ; ie, a carpi */
236         else if ((x == -1) && (y == -1) && (z > 0) && (z <= cube->nz))
237         {
238                 slice = (Slice *) RSL_new_slice(cube->ny, cube->nx);
239                 slice->data_type = (char *)strdup(cube->data_type);
240           slice->dx = cube->dx;
241           slice->dy = cube->dy;
242           slice->nx = cube->nx;
243           slice->ny = cube->ny;
244                 slice->f = cube->carpi[z-1]->f;
245                 slice->invf = cube->carpi[z-1]->invf;
246           /* Just copy carpi data values into slice structure. */
247                 for (j=0; j<cube->ny; j++)
248                   for (i=0; i<cube->nx; i++)
249                           slice->data[j][i] = (Slice_value) cube->carpi[z-1]->data[j][i];
250         }
251
252
253         else  /* Invalid parameters. */
254         {
255           if (radar_verbose_flag)
256                 {
257                         fprintf(stderr,"\nRSL_get_slice_from_cube(): passed invalid parameters\n");
258                         fprintf(stderr,"nx:%d ny:%d nz:%d x:%d y:%d z:%d\n",cube->nx,
259                                                         cube->ny,cube->nz,x,y,z);
260                 }
261           return(NULL);
262         }
263         
264         return(slice);
265 }