3 This is the TRMM Office Radar Software Library.
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.
26 #include <netinet/in.h>
30 int dorade_verbose = 0;
32 void dorade_verbose_on()
36 void dorade_verbose_off()
41 /**********************************************************************/
43 /* dorade_read_comment_block */
45 /**********************************************************************/
46 Comment_block *dorade_read_comment_block(FILE *in)
49 cb = (Comment_block *) calloc(1, sizeof(Comment_block));
51 perror("dorade_read_comment_block");
54 fread(cb->code, sizeof(cb->code), 1, in);
55 fread(&cb->len, sizeof(cb->len), 1, in); cb->len = ntohl(cb->len);
56 cb->comment = (char *) calloc(cb->len, sizeof(char));
57 if (cb->comment == NULL) {
58 perror("dorade_read_comment_block: cb->comment");
61 fread(cb->comment, sizeof(char), cb->len, in);
65 /**********************************************************************/
67 /* dorade_read_volume_desc */
69 /**********************************************************************/
70 Volume_desc *dorade_read_volume_desc (FILE *in)
74 vd = (Volume_desc *) calloc(1, sizeof(Volume_desc));
76 perror("dorade_read_volume_desc");
80 fread(vd, sizeof(Volume_desc), 1, in);
81 /* Now, convert from Big Endian. */
82 vd->len = ntohl(vd->len);
83 vd->version = ntohs(vd->version);
84 vd->volume_number = ntohs(vd->volume_number);
85 vd->max_bytes = ntohl(vd->max_bytes);
86 vd->year = ntohs(vd->year);
87 vd->month = ntohs(vd->month);
88 vd->day = ntohs(vd->day);
89 vd->hour = ntohs(vd->hour);
90 vd->minute = ntohs(vd->minute);
91 vd->second = ntohs(vd->second);
92 vd->gen_year = ntohs(vd->gen_year);
93 vd->gen_month = ntohs(vd->gen_month);
94 vd->gen_day = ntohs(vd->gen_day);
95 vd->nsensors = ntohs(vd->nsensors);
99 extern int little_endian(void);
100 extern void swap_4_bytes(void *word);
101 extern void swap_2_bytes(void *word);
104 /* Sensor descriptor routines. */
105 /**********************************************************************/
107 /* dorade_read_radar_desc */
109 /**********************************************************************/
110 Radar_desc *dorade_read_radar_desc (FILE *in)
115 rd = (Radar_desc *) calloc(1, sizeof(Radar_desc));
117 perror("dorade_read_radar_desc");
121 fread(rd, sizeof(Radar_desc), 1, in);
122 /* Now, convert from Big Endian. */
123 if (little_endian()) {
124 swap_4_bytes(&rd->len);
125 swap_4_bytes(&rd->radar_constant); /* Yes, even the ieee floating values. */
126 swap_4_bytes(&rd->peak_power);
127 swap_4_bytes(&rd->noise_power);
128 swap_4_bytes(&rd->rcvr_gain);
129 swap_4_bytes(&rd->ant_gain);
130 swap_4_bytes(&rd->radar_system_gain);
131 swap_4_bytes(&rd->horizontal_beam_width);
132 swap_4_bytes(&rd->vertical_beam_width);
133 swap_2_bytes(&rd->radar_type);
134 swap_2_bytes(&rd->scan_mode);
135 swap_4_bytes(&rd->scan_rate);
136 swap_4_bytes(&rd->start_angle);
137 swap_4_bytes(&rd->stop_angle);
138 swap_2_bytes(&rd->nparam_desc);
139 swap_2_bytes(&rd->ndesc);
140 swap_2_bytes(&rd->compress_code);
141 swap_2_bytes(&rd->compress_algo);
142 swap_4_bytes(&rd->data_reduction_param1);
143 swap_4_bytes(&rd->data_reduction_param2);
144 swap_4_bytes(&rd->longitude);
145 swap_4_bytes(&rd->latitude);
146 swap_4_bytes(&rd->altitude);
147 swap_4_bytes(&rd->unambiguous_velocity);
148 swap_4_bytes(&rd->unambiguous_range);
149 swap_2_bytes(&rd->nfreq);
150 swap_2_bytes(&rd->npulse_periods);
151 for (i=0; i<5; i++) {
152 swap_4_bytes(&rd->freq[i]);
153 swap_4_bytes(&rd->period[i]);
158 /**********************************************************************/
160 /* dorade_read_parameter_desc */
162 /**********************************************************************/
163 Parameter_desc *dorade_read_parameter_desc (FILE *in)
167 pd = (Parameter_desc *) calloc(1, sizeof(Parameter_desc));
169 perror("dorade_read_parameter_desc");
173 fread(pd, sizeof(Parameter_desc), 1, in);
174 /* Now, convert from Big Endian. */
175 if (little_endian()) {
176 swap_4_bytes(&pd->len);
177 swap_2_bytes(&pd->ipp);
178 swap_2_bytes(&pd->xmit_freq);
179 swap_4_bytes(&pd->rcvr_bandwidth);
180 swap_2_bytes(&pd->pulse_width);
181 swap_2_bytes(&pd->polarization);
182 swap_2_bytes(&pd->nsamp_in_dwell_time);
183 swap_2_bytes(&pd->parameter_type);
184 swap_4_bytes(&pd->threshold_value);
185 swap_4_bytes(&pd->scale_factor);
186 swap_4_bytes(&pd->offset_factor);
187 swap_4_bytes(&pd->missing_data_flag);
192 /**********************************************************************/
194 /* dorade_read_cell_range_vector */
196 /**********************************************************************/
197 Cell_range_vector *dorade_read_cell_range_vector (FILE *in)
199 Cell_range_vector *cv;
203 cv = (Cell_range_vector *) calloc(1, sizeof(Cell_range_vector));
205 perror("dorade_read_cell_range_vector");
209 fread(&cv->code, sizeof(cv->code), 1, in);
210 fread(&cv->len, sizeof(cv->len), 1, in);
211 fread(&cv->ncells, sizeof(cv->ncells), 1, in);
212 if (little_endian()) {
213 swap_4_bytes(&cv->len);
214 swap_4_bytes(&cv->ncells);
216 cv->range_cell = (float *)calloc(cv->ncells, sizeof(float));
217 if (!cv->range_cell) {
218 perror("dorade_read_cell_range_vector: cv->range_cell");
221 fread(cv->range_cell, sizeof(float), cv->ncells, in);
223 if (little_endian()) {
224 for (i=0; i<cv->ncells; i++)
225 swap_4_bytes(&cv->range_cell[i]);
228 /* Usually reading the range cells does not read to the end
229 * of the Cell_range_vector structure. We may be reading
230 * a non seekable device!
232 i = cv->len /* Remove a few bytes that precede. */
237 buff = (char *)malloc(i);
238 if (!buff) return cv;
239 fread(buff, sizeof(char), i, in);
244 /**********************************************************************/
246 /* dorade_read_correction_factor_desc */
248 /**********************************************************************/
249 Correction_factor_desc *dorade_read_correction_factor_desc(FILE *in)
251 Correction_factor_desc *cf;
253 cf = (Correction_factor_desc *) calloc(1, sizeof(Correction_factor_desc));
255 perror("dorade_read_correction_factor_desc");
259 fread(cf, sizeof(Correction_factor_desc), 1, in);
260 /* Now, convert from Big Endian. */
261 if (little_endian()) {
262 swap_4_bytes(&cf->len);
263 swap_4_bytes(&cf->azimuth);
264 swap_4_bytes(&cf->elevation);
265 swap_4_bytes(&cf->range);
266 swap_4_bytes(&cf->longitude);
267 swap_4_bytes(&cf->latitude);
268 swap_4_bytes(&cf->altitude);
269 swap_4_bytes(&cf->height);
270 swap_4_bytes(&cf->speed_east_west);
271 swap_4_bytes(&cf->speed_north_south);
272 swap_4_bytes(&cf->vertical_velocity);
273 swap_4_bytes(&cf->heading);
274 swap_4_bytes(&cf->roll);
275 swap_4_bytes(&cf->pitch);
276 swap_4_bytes(&cf->drift);
277 swap_4_bytes(&cf->rotation_angle);
278 swap_4_bytes(&cf->tilt_angle);
283 /**********************************************************************/
285 /* dorade_read_sensor */
287 /**********************************************************************/
288 Sensor_desc *dorade_read_sensor (FILE *in)
290 /* Read one 'Sensor #n' descriptor from FILE. */
295 sd = (Sensor_desc *) calloc (1, sizeof(Sensor_desc));
297 perror("dorade_read_sensor");
301 sd->radar_desc = dorade_read_radar_desc(in);
302 sd->nparam = sd->radar_desc->nparam_desc;
304 sd->p_desc = (Parameter_desc **) calloc(sd->nparam, sizeof(Parameter_desc *));
306 perror("dorade_read_sensor: sd->p_desc");
309 for (i=0; i<sd->nparam; i++) {
310 sd->p_desc[i] = dorade_read_parameter_desc(in);
313 sd->cell_range_vector = dorade_read_cell_range_vector(in);
314 sd->correction_factor_desc = dorade_read_correction_factor_desc(in);
319 /**********************************************************************/
321 /* dorade_read_sweep_info */
323 /**********************************************************************/
324 Sweep_info *dorade_read_sweep_info(FILE *in)
328 si = (Sweep_info *) calloc(1, sizeof(Sweep_info));
330 perror("dorade_read_sweep_info");
334 fread(si, sizeof(Sweep_info), 1, in);
335 /* FIXME: ?? For now, VOLD is what we expect when there
336 * are no more SWIB. This is a data driven EOF.
337 * Returning NULL should suffice.
339 if(strncmp(si->code, "SWIB", 4) != 0) {
340 /* Ignore the rest of the file. */
345 /* Now, convert from Big Endian. */
346 if (little_endian()) {
347 swap_4_bytes(&si->len);
348 swap_4_bytes(&si->sweep_num);
349 swap_4_bytes(&si->nrays);
350 swap_4_bytes(&si->start_angle);
351 swap_4_bytes(&si->stop_angle);
352 swap_4_bytes(&si->fixed_angle);
353 swap_4_bytes(&si->filter_flag);
359 /* Data Ray routines. */
361 /**********************************************************************/
363 /* dorade_read_ray_info */
365 /**********************************************************************/
366 Ray_info *dorade_read_ray_info (FILE *in)
370 ri = (Ray_info *) calloc(1, sizeof(Ray_info));
372 perror("dorade_read_ray_info");
376 fread(ri, sizeof(Ray_info), 1, in);
377 /* Now, convert from Big Endian. */
378 if (little_endian()) {
379 swap_4_bytes(&ri->len);
380 swap_4_bytes(&ri->sweep_num);
381 swap_4_bytes(&ri->jday);
382 swap_2_bytes(&ri->hour);
383 swap_2_bytes(&ri->minute);
384 swap_2_bytes(&ri->second);
385 swap_2_bytes(&ri->msec);
386 swap_4_bytes(&ri->azimuth);
387 swap_4_bytes(&ri->elevation);
388 swap_4_bytes(&ri->peak_power);
389 swap_4_bytes(&ri->scan_rate);
390 swap_4_bytes(&ri->status);
396 /**********************************************************************/
398 /* dorade_read_platform_info */
400 /**********************************************************************/
401 Platform_info *dorade_read_platform_info (FILE *in)
405 pi = (Platform_info *) calloc(1, sizeof(Platform_info));
407 perror("dorade_read_platform_info");
411 fread(pi, sizeof(Platform_info), 1, in);
412 /* Now, convert from Big Endian. */
413 if (little_endian()) {
414 swap_4_bytes(&pi->len);
415 swap_4_bytes(&pi->longitude);
416 swap_4_bytes(&pi->latitude);
417 swap_4_bytes(&pi->altitude);
418 swap_4_bytes(&pi->height);
419 swap_4_bytes(&pi->ew_speed);
420 swap_4_bytes(&pi->ns_speed);
421 swap_4_bytes(&pi->v_speed);
422 swap_4_bytes(&pi->heading);
423 swap_4_bytes(&pi->roll);
424 swap_4_bytes(&pi->pitch);
425 swap_4_bytes(&pi->drift);
426 swap_4_bytes(&pi->rotation);
427 swap_4_bytes(&pi->tilt);
428 swap_4_bytes(&pi->ew_wind_speed);
429 swap_4_bytes(&pi->ns_wind_speed);
430 swap_4_bytes(&pi->v_wind_speed);
431 swap_4_bytes(&pi->heading_rate);
432 swap_4_bytes(&pi->pitch_rate);
437 /**********************************************************************/
439 /* dorade_read_parameter_info */
441 /**********************************************************************/
443 Parameter_data *dorade_read_parameter_data(FILE *in)
448 pd = (Parameter_data *) calloc(1, sizeof(Parameter_data));
450 perror("dorade_read_parameter_data: pd");
454 fread(&pd->code, sizeof(pd->code), 1, in);
455 fread(&pd->len, sizeof(pd->len), 1, in);
456 fread(&pd->name, sizeof(pd->name), 1, in);
457 if (little_endian()) swap_4_bytes(&pd->len);
458 /* Length is in parameter data block? or calculate if from pd->len. */
460 len = pd->len /* Use pd->len for now. */
461 - sizeof(pd->code) /* Remove a few bytes from */
462 - sizeof(pd->len) /* the count. */
464 pd->data = (char *)calloc(len, sizeof(char));
466 perror("dorade_read_parameter_data: pd->data");
469 fread(pd->data, sizeof(char), len, in);
471 /* FIXME: Big endian conversion in caller? Is that the right place? */
475 /**********************************************************************/
477 /* dorade_read_sweep */
479 /**********************************************************************/
480 Sweep_record *dorade_read_sweep(FILE *fp, Sensor_desc **sd)
488 Parameter_desc **parameter_desc;
493 sr = (Sweep_record *) calloc (1, sizeof(Sweep_record));
495 perror("dorade_read_sweep");
499 nparam = sd[0]->nparam;
500 parameter_desc = sd[0]->p_desc;
503 sr->s_info = si = dorade_read_sweep_info(fp);
506 return NULL; /* EOF or error. */
508 sr->nrays = si->nrays;
509 if (dorade_verbose) {
510 printf("=====< NEW SWIB >=====\n");
511 dorade_print_sweep_info(si);
513 sr->data_ray = (Data_ray **) calloc(si->nrays, sizeof(Data_ray *));
516 return NULL; /* EOF or error. */
519 for (i=0; i<si->nrays; i++) {
520 if (dorade_verbose) printf("---------- Ray %d ----------\n", i);
521 sr->data_ray[i] = (Data_ray *) calloc(1, sizeof(Data_ray));
522 if (!sr->data_ray[0]) {
524 return NULL; /* EOF or error. */
526 ri = dorade_read_ray_info(fp);
527 if (dorade_verbose) {
528 dorade_print_ray_info(ri);
530 pi = dorade_read_platform_info(fp);
531 if (dorade_verbose) {
532 dorade_print_platform_info(pi);
534 sr->data_ray[i]->ray_info = ri;
535 sr->data_ray[i]->platform_info = pi;
536 sr->data_ray[i]->parameter_data = (Parameter_data **) calloc(nparam, sizeof(Parameter_data *));
537 sr->data_ray[i]->data_len = (int *) calloc(nparam, sizeof(int));
538 sr->data_ray[i]->word_size = (int *) calloc(nparam, sizeof(int));
539 sr->data_ray[i]->nparam = nparam;
541 for (j=0; j<nparam; j++) {
542 pd = dorade_read_parameter_data(fp);
543 /* Perform big endian conversion. */
544 len = pd->len /* Use pd->len for now. */
545 - sizeof(pd->code) /* Remove a few bytes from */
546 - sizeof(pd->len) /* the count. */
548 sr->data_ray[i]->parameter_data[j] = pd;
549 sr->data_ray[i]->data_len[j] = len;
550 if (parameter_desc[j]->parameter_type == 2)
551 sr->data_ray[i]->word_size[j] = 2; /* 2 bytes per word */
552 else if (parameter_desc[j]->parameter_type == 3 ||
553 parameter_desc[j]->parameter_type == 4)
554 sr->data_ray[i]->word_size[j] = 4; /* 4 bytes per word */
556 if (little_endian()) { /* Numbers were read big-endian. */
557 if (sr->data_ray[i]->word_size[j] == 2)
558 for (k=0; k<len; k+=2)
559 swap_2_bytes(&pd->data[k]);
560 else if (sr->data_ray[i]->word_size[j] == 4)
561 for (k=0; k<len; k+=4)
562 swap_4_bytes(&pd->data[k]);
569 /**********************************************************************/
571 /* dorade_read_ray */
573 /**********************************************************************/
574 Data_ray *dorade_read_ray (FILE *in);
577 /* MEMORY MANAGEMENT ROUTINES */
579 /**********************************************************************/
581 /* dorade_free_data_ray */
583 /**********************************************************************/
584 void dorade_free_data_ray(Data_ray *r)
587 if (r == NULL) return;
590 free(r->platform_info);
591 if (r->parameter_data) {
592 for (i=0; i<r->nparam; i++)
593 free(r->parameter_data[i]);
594 free(r->parameter_data);
599 /**********************************************************************/
601 /* dorade_free_sweep */
603 /**********************************************************************/
604 void dorade_free_sweep(Sweep_record *s)
607 if (s == NULL) return;
610 for (i=0; i<s->nrays; i++)
611 dorade_free_data_ray(s->data_ray[i]);
614 if (s->s_info) free(s->s_info);