]> Pileus Git - ~andy/rsl/blob - dorade.c
Changes from Bart (2009-10-28)
[~andy/rsl] / dorade.c
1 /*
2     NASA/TRMM, Code 910.1.
3     This is the TRMM Office Radar Software Library.
4     Copyright (C) 1999
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 #include <stdio.h>
25 #include <stdlib.h>
26 #include <netinet/in.h>
27 #include <string.h>
28 #include "dorade.h"
29
30 int dorade_verbose = 0;
31
32 void dorade_verbose_on()
33 {
34   dorade_verbose = 1;
35 }
36 void dorade_verbose_off()
37 {
38   dorade_verbose = 0;
39 }
40
41 static int do_swap = 0;
42
43 /**********************************************************************/
44 /*                                                                    */
45 /*                      read_extra_bytes                              */
46 /*                                                                    */
47 /**********************************************************************/
48 int read_extra_bytes(int nbytes, FILE *in)
49 {
50   char *extra;
51   int nread;
52   /*
53    * Read and discard nbytes bytes.  The return value is the byte count
54    * returned by fread, unless there is an error, then it is 0.
55    */
56   extra = (char *) malloc(nbytes);
57   if (!extra) {
58     perror("\nError: read_extra_bytes");
59     fprintf(stderr,"Tried to allocate %d bytes\n", nbytes);
60     return 0;
61   }
62   nread = fread(extra, sizeof(char), nbytes, in);
63   free(extra);
64   return nread;
65 }
66
67 /**********************************************************************/
68 /*                                                                    */
69 /*                      dorade_read_comment_block                     */
70 /*                                                                    */
71 /**********************************************************************/
72 Comment_block *dorade_read_comment_block(FILE *in)
73 {
74   Comment_block *cb;
75   cb = (Comment_block *) calloc(1, sizeof(Comment_block));
76   if (cb == NULL) {
77         perror("dorade_read_comment_block");
78         return NULL;
79   }
80   fread(cb->code, sizeof(cb->code), 1, in);
81   fread(&cb->len, sizeof(cb->len), 1, in);
82
83   /* Check for big endian data on little endian platform.  The smallest value
84    * cb->len could have is 8 (length of cb->code + cb->len), so we put that in
85    * first byte of test value, and also test for negative, since sign bit could
86    * be set in a larger value.
87    */
88   if (cb->len > 0x08000000 || cb->len < 0) do_swap = 1;
89   if (do_swap) cb->len = ntohl(cb->len);
90
91   /* Length of cb->comment is cb->len-8 since cb->code and cb->len have
92    * already been read.
93    */
94   cb->comment = (char *) calloc(cb->len-8, sizeof(char));
95   if (cb->comment == NULL) {
96         perror("dorade_read_comment_block: cb->comment");
97         return cb;
98   }
99   fread(cb->comment, sizeof(char), cb->len-8, in);
100   return cb;
101 }
102
103 /**********************************************************************/
104 /*                                                                    */
105 /*                      dorade_read_volume_desc                       */
106 /*                                                                    */
107 /**********************************************************************/
108 Volume_desc    *dorade_read_volume_desc    (FILE *in)
109 {
110   Volume_desc *vd;
111
112   vd = (Volume_desc *) calloc(1, sizeof(Volume_desc));
113   if(!vd) {
114         perror("dorade_read_volume_desc");
115         return NULL;
116   }
117
118   fread(vd, sizeof(Volume_desc), 1, in);
119   /* Now, convert from Big Endian. */
120   if (do_swap) {
121       vd->len = ntohl(vd->len);
122       vd->version = ntohs(vd->version);
123       vd->volume_number = ntohs(vd->volume_number);
124       vd->max_bytes = ntohl(vd->max_bytes);
125       vd->year = ntohs(vd->year);
126       vd->month = ntohs(vd->month);
127       vd->day = ntohs(vd->day);
128       vd->hour = ntohs(vd->hour);
129       vd->minute = ntohs(vd->minute);
130       vd->second = ntohs(vd->second);
131       vd->gen_year = ntohs(vd->gen_year);
132       vd->gen_month = ntohs(vd->gen_month);
133       vd->gen_day = ntohs(vd->gen_day);
134       vd->nsensors = ntohs(vd->nsensors);
135   }
136   return vd;
137 }
138
139 extern int little_endian(void);
140 extern void swap_4_bytes(void *word);
141 extern void swap_2_bytes(void *word);
142
143
144 /* Sensor descriptor routines. */
145 /**********************************************************************/
146 /*                                                                    */
147 /*                      dorade_read_radar_desc                        */
148 /*                                                                    */
149 /**********************************************************************/
150 Radar_desc     *dorade_read_radar_desc     (FILE *in)
151 {
152   Radar_desc *rd;
153   int i;
154
155   rd = (Radar_desc *) calloc(1, sizeof(Radar_desc));
156   if(!rd) {
157         perror("dorade_read_radar_desc");
158         return NULL;
159   }
160
161   fread(rd, sizeof(Radar_desc), 1, in);
162   /* Now, convert from Big Endian. */
163   if (do_swap) {
164         swap_4_bytes(&rd->len);
165         swap_4_bytes(&rd->radar_constant); /* Yes, even the ieee floating values. */
166         swap_4_bytes(&rd->peak_power);
167         swap_4_bytes(&rd->noise_power);
168         swap_4_bytes(&rd->rcvr_gain);
169         swap_4_bytes(&rd->ant_gain);
170         swap_4_bytes(&rd->radar_system_gain);
171         swap_4_bytes(&rd->horizontal_beam_width);
172         swap_4_bytes(&rd->vertical_beam_width);
173         swap_2_bytes(&rd->radar_type);
174         swap_2_bytes(&rd->scan_mode);
175         swap_4_bytes(&rd->scan_rate);
176         swap_4_bytes(&rd->start_angle);
177         swap_4_bytes(&rd->stop_angle);
178         swap_2_bytes(&rd->nparam_desc);
179         swap_2_bytes(&rd->ndesc);
180         swap_2_bytes(&rd->compress_code);
181         swap_2_bytes(&rd->compress_algo);
182         swap_4_bytes(&rd->data_reduction_param1);
183         swap_4_bytes(&rd->data_reduction_param2);
184         swap_4_bytes(&rd->longitude);
185         swap_4_bytes(&rd->latitude);
186         swap_4_bytes(&rd->altitude);
187         swap_4_bytes(&rd->unambiguous_velocity);
188         swap_4_bytes(&rd->unambiguous_range);
189         swap_2_bytes(&rd->nfreq);
190         swap_2_bytes(&rd->npulse_periods);
191         for (i=0; i<5; i++) {
192           swap_4_bytes(&rd->freq[i]);
193           swap_4_bytes(&rd->period[i]);
194         }
195   }
196   /* If RADD block is longer than structure, read through extra bytes.
197    * This sometimes happens.
198    */
199   if (rd->len > sizeof(Radar_desc)) {
200       if (read_extra_bytes(rd->len - sizeof(Radar_desc), in) <= 0)
201           fprintf(stderr,"Called from %s, line: %d\n", __FILE__, __LINE__ - 1);
202   }
203   return rd;
204 }
205 /**********************************************************************/
206 /*                                                                    */
207 /*                      dorade_read_parameter_desc                    */
208 /*                                                                    */
209 /**********************************************************************/
210 Parameter_desc *dorade_read_parameter_desc (FILE *in)
211 {
212   Parameter_desc *pd;
213
214   pd = (Parameter_desc *) calloc(1, sizeof(Parameter_desc));
215   if(!pd) {
216         perror("dorade_read_parameter_desc");
217         return NULL;
218   }
219
220   fread(pd, sizeof(Parameter_desc), 1, in);
221   /* Now, convert from Big Endian. */
222   if (do_swap) {
223         swap_4_bytes(&pd->len);
224         swap_2_bytes(&pd->ipp);
225         swap_2_bytes(&pd->xmit_freq);
226         swap_4_bytes(&pd->rcvr_bandwidth);
227         swap_2_bytes(&pd->pulse_width);
228         swap_2_bytes(&pd->polarization);
229         swap_2_bytes(&pd->nsamp_in_dwell_time);
230         swap_2_bytes(&pd->parameter_type);
231         swap_4_bytes(&pd->threshold_value);
232         swap_4_bytes(&pd->scale_factor);
233         swap_4_bytes(&pd->offset_factor);
234         swap_4_bytes(&pd->missing_data_flag);
235   }
236   /* If the descriptor block is longer than the structure, read past the extra bytes.
237    */
238   if (pd->len > sizeof(Parameter_desc)) {
239       if (read_extra_bytes(pd->len - sizeof(Parameter_desc), in) <= 0)
240           fprintf(stderr,"Called from %s, line: %d\n", __FILE__, __LINE__ - 1);
241   }
242   return pd;
243 }
244
245 /**********************************************************************/
246 /*                                                                    */
247 /*                      dorade_read_cell_range_vector                 */
248 /*                                                                    */
249 /**********************************************************************/
250 Cell_range_vector      *dorade_read_cell_range_vector     (FILE *in)
251 {
252   Cell_range_vector *cv;
253   char *buff;
254   int i;
255
256   cv = (Cell_range_vector *) calloc(1, sizeof(Cell_range_vector));
257   if(!cv) {
258         perror("dorade_read_cell_range_vector");
259         return NULL;
260   }
261
262   fread(&cv->code, sizeof(cv->code), 1, in);
263   fread(&cv->len, sizeof(cv->len), 1, in);
264   fread(&cv->ncells, sizeof(cv->ncells), 1, in);
265   if (do_swap) {
266         swap_4_bytes(&cv->len);
267         swap_4_bytes(&cv->ncells);
268   }
269   cv->range_cell = (float *)calloc(cv->ncells, sizeof(float));
270   if (!cv->range_cell) {
271         perror("dorade_read_cell_range_vector: cv->range_cell");
272         return cv;
273   }
274   fread(cv->range_cell, sizeof(float), cv->ncells, in);
275
276   if (do_swap) {
277         for (i=0; i<cv->ncells; i++)
278           swap_4_bytes(&cv->range_cell[i]);
279   }
280
281   /* Usually reading the range cells does not read to the end
282    * of the Cell_range_vector structure.  We may be reading
283    * a non seekable device!
284    */
285   i = cv->len            /* Remove a few bytes that precede. */
286         - sizeof(cv->code)
287         - sizeof(cv->len)
288         - sizeof(cv->ncells)
289         - cv->ncells*4;
290   buff = (char *)malloc(i);
291   if (!buff) return cv;
292   fread(buff, sizeof(char), i, in);
293   free(buff);
294   return cv;
295 }
296
297 /**********************************************************************/
298 /*                                                                    */
299 /*                      dorade_read_correction_factor_desc            */
300 /*                                                                    */
301 /**********************************************************************/
302 Correction_factor_desc *dorade_read_correction_factor_desc(FILE *in)
303 {
304   Correction_factor_desc *cf;
305   char *remaining;
306   int is_cfac = 0;
307
308   cf = (Correction_factor_desc *) calloc(1, sizeof(Correction_factor_desc));
309   if(!cf) {
310         perror("dorade_read_correction_factor_desc");
311         return NULL;
312   }
313
314   /* Make sure we have Correction Factor Descriptor. */
315   while (!is_cfac) {
316       fread(cf->code, sizeof(cf->code), 1, in);
317       if (strncmp(cf->code, "CFAC", 4) == 0)
318           is_cfac = 1;
319       else {
320           fread(&cf->len, sizeof(cf->len), 1, in);
321           if (do_swap) swap_4_bytes(&cf->len);
322           remaining = (char *) malloc(cf->len-8);
323           if (!remaining) {
324               perror("\ndorade_read_correction_factor_desc");
325               fprintf(stderr,"cf->len = %d\n\n", cf->len);
326               return NULL;
327           }
328           fread(remaining, sizeof(char), cf->len-8, in);
329           free(remaining);
330       }
331   }
332   fread(&cf->len, sizeof(Correction_factor_desc)-4, 1, in);
333   /* Now, convert from Big Endian. */
334   if (do_swap) {
335         swap_4_bytes(&cf->len);
336         swap_4_bytes(&cf->azimuth);
337         swap_4_bytes(&cf->elevation);
338         swap_4_bytes(&cf->range);
339         swap_4_bytes(&cf->longitude);
340         swap_4_bytes(&cf->latitude);
341         swap_4_bytes(&cf->altitude);
342         swap_4_bytes(&cf->height);
343         swap_4_bytes(&cf->speed_east_west);
344         swap_4_bytes(&cf->speed_north_south);
345         swap_4_bytes(&cf->vertical_velocity);
346         swap_4_bytes(&cf->heading);
347         swap_4_bytes(&cf->roll);
348         swap_4_bytes(&cf->pitch);
349         swap_4_bytes(&cf->drift);
350         swap_4_bytes(&cf->rotation_angle);
351         swap_4_bytes(&cf->tilt_angle);
352   }
353   return cf;
354 }
355
356 /**********************************************************************/
357 /*                                                                    */
358 /*                      dorade_read_sensor                            */
359 /*                                                                    */
360 /**********************************************************************/
361 Sensor_desc            *dorade_read_sensor (FILE *in)
362
363          /* Read one 'Sensor #n' descriptor from FILE. */
364 {
365   Sensor_desc            *sd;
366   int i;
367
368   sd = (Sensor_desc *) calloc (1, sizeof(Sensor_desc));
369   if (!sd) {
370         perror("dorade_read_sensor");
371         return NULL;
372   }
373
374   sd->radar_desc = dorade_read_radar_desc(in);
375   sd->nparam = sd->radar_desc->nparam_desc;
376
377   sd->p_desc = (Parameter_desc **) calloc(sd->nparam, sizeof(Parameter_desc *));
378   if (!sd->p_desc) {
379         perror("dorade_read_sensor: sd->p_desc");
380         return sd;
381   }
382   for (i=0; i<sd->nparam; i++) {
383         sd->p_desc[i] = dorade_read_parameter_desc(in);
384   }
385
386   sd->cell_range_vector = dorade_read_cell_range_vector(in);
387   sd->correction_factor_desc = dorade_read_correction_factor_desc(in);
388   return sd;
389 }
390
391
392 /**********************************************************************/
393 /*                                                                    */
394 /*                      dorade_read_sweep_info                        */
395 /*                                                                    */
396 /**********************************************************************/
397 Sweep_info *dorade_read_sweep_info(FILE *in)
398 {
399   Sweep_info *si;
400
401   si = (Sweep_info *) calloc(1, sizeof(Sweep_info));
402   if(!si) {
403         perror("dorade_read_sweep_info");
404         return NULL;
405   }
406
407   fread(si, sizeof(Sweep_info), 1, in);
408   /* FIXME: ?? For now, VOLD is what we expect when there
409    *           are no more SWIB.  This is a data driven EOF.
410    *           Returning NULL should suffice.
411    */
412   if(strncmp(si->code, "SWIB", 4) != 0) {
413         /* Ignore the rest of the file. */
414         free(si);
415         return NULL;
416   }
417
418   /* Now, convert from Big Endian. */
419   if (do_swap) {
420         swap_4_bytes(&si->len);
421         swap_4_bytes(&si->sweep_num);
422         swap_4_bytes(&si->nrays);
423         swap_4_bytes(&si->start_angle);
424         swap_4_bytes(&si->stop_angle);
425         swap_4_bytes(&si->fixed_angle);
426         swap_4_bytes(&si->filter_flag);
427   }
428
429   return si;
430 }
431
432 /* Data Ray routines. */
433
434 /**********************************************************************/
435 /*                                                                    */
436 /*                      dorade_read_ray_info                          */
437 /*                                                                    */
438 /**********************************************************************/
439 Ray_info       *dorade_read_ray_info      (FILE *in)
440 {
441   Ray_info *ri;
442
443   ri = (Ray_info *) calloc(1, sizeof(Ray_info));
444   if(!ri) {
445         perror("dorade_read_ray_info");
446         return NULL;
447   }
448
449   fread(ri, sizeof(Ray_info), 1, in);
450   /* Now, convert from Big Endian. */
451   if (do_swap) {
452         swap_4_bytes(&ri->len);
453         swap_4_bytes(&ri->sweep_num);
454         swap_4_bytes(&ri->jday);
455         swap_2_bytes(&ri->hour);
456         swap_2_bytes(&ri->minute);
457         swap_2_bytes(&ri->second);
458         swap_2_bytes(&ri->msec);
459         swap_4_bytes(&ri->azimuth);
460         swap_4_bytes(&ri->elevation);
461         swap_4_bytes(&ri->peak_power);
462         swap_4_bytes(&ri->scan_rate);
463         swap_4_bytes(&ri->status);
464   }
465
466   return ri;
467 }
468
469 /**********************************************************************/
470 /*                                                                    */
471 /*                      dorade_read_platform_info                     */
472 /*                                                                    */
473 /**********************************************************************/
474 Platform_info  *dorade_read_platform_info (FILE *in)
475 {
476   Platform_info *pi;
477   int len_first_two;
478
479   pi = (Platform_info *) calloc(1, sizeof(Platform_info));
480   if(!pi) {
481         perror("dorade_read_platform_info");
482         return NULL;
483   }
484
485   /* Read the id code to make sure we have "ASIB" for platform info.  If
486    * id is ASIB, then read data into the Platform_info structure.  If it is
487    * XSTF, read and discard remainder of block, which will have a different
488    * size than Platform_info.  XSTF is undocumented, but apparently it takes
489    * the place of ASIB when radar is grounded.
490    */
491
492   fread(pi->code, sizeof(pi->code), 1, in);
493   fread(&pi->len, sizeof(pi->len), 1, in);
494   if (do_swap) swap_4_bytes(&pi->len);
495   len_first_two = sizeof(pi->code) + sizeof(pi->len);
496     
497   if (strncmp(pi->code, "ASIB", 4) == 0) {
498       fread(&pi->longitude, sizeof(Platform_info)-len_first_two, 1, in);
499       /* Read past any extra bytes. */
500       if (pi->len > sizeof(Platform_info)) {
501           if (read_extra_bytes(pi->len - sizeof(Platform_info), in) <= 0)
502               fprintf(stderr,"Called from %s, line: %d\n",__FILE__,__LINE__-1);
503       }
504       /* Now, convert from Big Endian. */
505       if (do_swap) {
506           swap_4_bytes(&pi->longitude);
507           swap_4_bytes(&pi->latitude);
508           swap_4_bytes(&pi->altitude);
509           swap_4_bytes(&pi->height);
510           swap_4_bytes(&pi->ew_speed);
511           swap_4_bytes(&pi->ns_speed);
512           swap_4_bytes(&pi->v_speed);
513           swap_4_bytes(&pi->heading);
514           swap_4_bytes(&pi->roll);
515           swap_4_bytes(&pi->pitch);
516           swap_4_bytes(&pi->drift);
517           swap_4_bytes(&pi->rotation);
518           swap_4_bytes(&pi->tilt);
519           swap_4_bytes(&pi->ew_wind_speed);
520           swap_4_bytes(&pi->ns_wind_speed);
521           swap_4_bytes(&pi->v_wind_speed);
522           swap_4_bytes(&pi->heading_rate);
523           swap_4_bytes(&pi->pitch_rate);
524       }
525   } else if (strncmp(pi->code, "XSTF", 4) == 0) {
526       /* Read to end of XSTF block. */
527       if (read_extra_bytes(pi->len - len_first_two, in) <= 0)
528           fprintf(stderr,"Called from %s, line: %d\n", __FILE__, __LINE__ - 1);
529   } else {
530       fprintf(stderr,"Unexpected block id: \"%s\"."
531           "  Expected \"ASIB\" or \"XSTF\"\n", pi->code);
532   }
533
534   return pi;
535 }
536
537 /**********************************************************************/
538 /*                                                                    */
539 /*                      dorade_read_parameter_data                    */
540 /*                                                                    */
541 /**********************************************************************/
542
543 Parameter_data *dorade_read_parameter_data(FILE *in)
544 {
545   Parameter_data *pd;
546   int len;
547
548   pd = (Parameter_data *) calloc(1, sizeof(Parameter_data));
549   if(!pd) {
550         perror("dorade_read_parameter_data: pd");
551         return NULL;
552   }
553
554   fread(&pd->code, sizeof(pd->code), 1, in);
555   fread(&pd->len, sizeof(pd->len), 1, in);
556   fread(&pd->name, sizeof(pd->name), 1, in);
557   if (do_swap) swap_4_bytes(&pd->len);
558   /* Length is in parameter data block? or calculate if from pd->len. */
559
560   len = pd->len  /* Use pd->len for now. */
561         - sizeof(pd->code) /* Remove a few bytes from */
562         - sizeof(pd->len)  /* the count.              */
563         - sizeof(pd->name);
564   pd->data = (char *)calloc(len, sizeof(char));
565   if (!pd->data) {
566         perror("dorade_read_parameter_data: pd->data");
567         return pd;
568   }
569   fread(pd->data, sizeof(char), len, in);
570   
571   /* FIXME: Big endian conversion in caller?  Is that the right place? */
572
573   return pd;
574 }
575 /**********************************************************************/
576 /*                                                                    */
577 /*                      dorade_read_sweep                             */
578 /*                                                                    */
579 /**********************************************************************/
580 Sweep_record *dorade_read_sweep(FILE *fp, Sensor_desc **sd)
581 {
582   Sweep_record   *sr;
583
584   Sweep_info     *si;
585   Ray_info       *ri;
586   Platform_info  *pi;
587   Parameter_data *pd;
588   Parameter_desc **parameter_desc;
589
590   int i, j, k,len;
591   int nparam;
592
593   sr = (Sweep_record *) calloc (1, sizeof(Sweep_record));
594   if (!sr) {
595         perror("dorade_read_sweep");
596         return NULL;
597   }
598
599   nparam         = sd[0]->nparam;
600   parameter_desc = sd[0]->p_desc;
601
602  /* Expect SWIB */
603   sr->s_info = si = dorade_read_sweep_info(fp);
604   if (!si) {
605         free(sr);
606         return NULL;  /* EOF or error. */
607   }
608   sr->nrays = si->nrays;
609   if (dorade_verbose) {
610         printf("=====< NEW SWIB >=====\n");
611         dorade_print_sweep_info(si);
612   }
613   sr->data_ray = (Data_ray **) calloc(si->nrays, sizeof(Data_ray *));
614   if (!sr->data_ray) {
615         free(sr);
616         return NULL;  /* EOF or error. */
617   }
618
619   for (i=0; i<si->nrays; i++) {
620         if (dorade_verbose) printf("---------- Ray %d ----------\n", i);
621         sr->data_ray[i] = (Data_ray *) calloc(1, sizeof(Data_ray));
622         if (!sr->data_ray[0]) {
623           free(sr);
624           return NULL;  /* EOF or error. */
625         }
626         ri = dorade_read_ray_info(fp);
627         if (dorade_verbose) {
628           dorade_print_ray_info(ri);
629         }
630         pi = dorade_read_platform_info(fp);
631         if (dorade_verbose) {
632           dorade_print_platform_info(pi);
633         }
634         sr->data_ray[i]->ray_info = ri;
635         sr->data_ray[i]->platform_info = pi;
636         sr->data_ray[i]->parameter_data = (Parameter_data **) calloc(nparam, sizeof(Parameter_data *));
637         sr->data_ray[i]->data_len  = (int *) calloc(nparam, sizeof(int));
638         sr->data_ray[i]->word_size = (int *) calloc(nparam, sizeof(int));
639         sr->data_ray[i]->nparam    = nparam;
640
641         for (j=0; j<nparam; j++) {
642           pd = dorade_read_parameter_data(fp);
643           /* Perform big endian conversion. */
644           len = pd->len  /* Use pd->len for now. */
645                 - sizeof(pd->code) /* Remove a few bytes from */
646                 - sizeof(pd->len)  /* the count.              */
647                 - sizeof(pd->name);
648           sr->data_ray[i]->parameter_data[j] = pd;
649           sr->data_ray[i]->data_len[j] = len;
650           if (parameter_desc[j]->parameter_type == 2)
651                 sr->data_ray[i]->word_size[j] = 2; /* 2 bytes per word */
652           else if (parameter_desc[j]->parameter_type == 3 ||
653                            parameter_desc[j]->parameter_type == 4)
654                 sr->data_ray[i]->word_size[j] = 4; /* 4 bytes per word */
655                 
656           if (do_swap) { /* Numbers were read big-endian. */
657                 if (sr->data_ray[i]->word_size[j] == 2)
658                   for (k=0; k<len; k+=2)
659                         swap_2_bytes(&pd->data[k]);
660                 else if (sr->data_ray[i]->word_size[j] == 4)
661                   for (k=0; k<len; k+=4)
662                         swap_4_bytes(&pd->data[k]);
663           }
664         }
665   }
666   return sr;
667 }
668
669
670 /* MEMORY MANAGEMENT ROUTINES */
671
672 /**********************************************************************/
673 /*                                                                    */
674 /*                      dorade_free_data_ray                          */
675 /*                                                                    */
676 /**********************************************************************/
677 void dorade_free_data_ray(Data_ray *r)
678 {
679   int i;
680   if (r == NULL) return;
681
682   free(r->ray_info);
683   free(r->platform_info);
684   if (r->parameter_data) {
685         for (i=0; i<r->nparam; i++)
686           free(r->parameter_data[i]);
687         free(r->parameter_data);
688   }
689   free(r);
690 }
691
692 /**********************************************************************/
693 /*                                                                    */
694 /*                      dorade_free_sweep                             */
695 /*                                                                    */
696 /**********************************************************************/
697 void dorade_free_sweep(Sweep_record *s)
698 {
699   int i;
700   if (s == NULL) return;
701   
702   if (s->data_ray) {
703         for (i=0; i<s->nrays; i++)
704           dorade_free_data_ray(s->data_ray[i]);
705         free(s->data_ray);
706   }
707   if (s->s_info) free(s->s_info);
708   free(s);
709 }