root/cdat/trunk/lats/latsgrib.c

Revision 214, 36.8 kB (checked in by drach, 11 years ago)

- Modified copyright

Line 
1 /* -*-Mode: C;-*-
2  * Module:      LATS GRIB functions
3  *
4  * Copyright:   1998, Regents of the University of California
5  *
6  * Authors:     Bob Drach, Lawrence Livermore National Laboratory
7  *              drach@llnl.gov
8  *
9  *              Mike Fiorino, Lawrence Livermore National Laboratory
10  *              fiorino@pcmdi.llnl.gov
11  *
12  * Version:     $Id$
13  *
14  * Revision History:
15  *
16  * $Log: latsgrib.c,v $
17  * Revision 1.1.1.1  1998/01/15 00:10:44  drach
18  * Standard repository
19  *
20  * Revision 1.24  1998/01/09 22:27:29  drach
21  * - Ported to SGI Irix V6
22  * - Added routines to delete grids and vertical dimensions, for CDAT
23  * - Cleaned up memory leaks
24  *
25  * Revision 1.23  1997/11/11 19:20:57  drach
26  * - Brought GrADS source into line with cdunif
27  *
28  * Revision 1.22  1997/10/15 17:53:16  drach
29  * - remove name collisions with cdunif
30  * - only one vertical dimension with GrADS/GRIB
31  * - in sync with Mike's GrADS src170
32  * - parameter table in sync with standard model output listing
33  *
34  * Revision 1.21  1996/12/18 22:06:22  fiorino
35  * initialize fltpnt in gagmap.c to cover c90 compiler problem
36  * added support for climatological and 365-day calendars in GrADS
37  *
38  * Revision 1.20  1996/12/12 18:39:45  fiorino
39  * 961212
40  *
41  * Mike's changes to parm table
42  * GraDS updated source
43  * and improvements in GrADS output to handle yearly data and 365-day calendars
44  * added gaprnt routine in latsfort.c to aid link with straight GraDS source
45  *
46  * Revision 1.19  1996/10/22  19:05:07  fiorino
47  * latsgrib bug in .ctl creator
48  *
49  * Revision 1.18  1996/10/16 22:10:00  drach
50  * - Added automatic gribmap generation
51  * - Restricted LATS_GRADS_GRIB convention to one grid per file
52  *
53  * Revision 1.17  1996/10/10 23:15:44  drach
54  * - lats_create filetype changed to convention, with options LATS_PCMDI,
55  *   LATS_GRADS_GRIB, and LATS_COARDS.
56  * - monthly data defaults to 16-bit compression
57  * - LATS_MONTHLY_TABLE_COMP option added to override 16-bit compression
58  * - AMIP II standard parameter file
59  * - parameter file incorporates GRIB center and subcenter
60  * - if time delta is positive, check that (new_time - old_time)=integer*delta
61  *
62  * Revision 1.16  1996/09/30 18:57:26  drach
63  * - Relax test for GrADS/GRIB equal-spacing
64  *
65  * Revision 1.15  1996/09/25 23:16:04  fiorino
66  * added grib map code
67  * corrected convertions of lat/lon dx/dy to ints in the GDS
68  *
69  * Revision 1.14  1996/08/20  18:34:08  drach
70  * - lats_create has a new argument: calendar
71  * - lats_grid: longitude, latitude dimension vectors are now double
72  *   precision (double, C).
73  * - lats_vert_dim: vector of levels is now double precision (double,
74  *   C). lats_vert_dim need not be called for single-value/surface
75  *   dimensions, if defined in the parameter table. Multi-valued vertical
76  *   dimensions, such as pressure levels, must be defined with
77  *   lats_vert_dim.
78  * - lats_var: set level ID to 0 for implicitly defined surface
79  *   dimension.
80  * - lats_write: level value is double precision (double, C).
81  * - lats_parmtab: replaces routine lats_vartab.
82  * - FORTRAN latserropt added: allows program to set error handling
83  *   options.
84  * - The parameter file format changed.
85  *
86  * Revision 1.13  1996/08/12 19:19:47  drach
87  * - various bug fixes (fiorino)
88  *
89  * Revision 1.12  1996/07/20  01:23:26  drach
90  * - Restored compatible amip2.parms
91  * - Provide default file comments for GrADS control file title
92  *
93  * Revision 1.11  1996/07/17 18:17:26  fiorino
94  * outout long_name and units to var description in .ctl file
95  *
96  * Revision 1.10  1996/07/17  01:04:33  fiorino
97  * bug in .ctl file for ydef
98  *
99  * Revision 1.9  1996/07/12 00:36:25  drach
100  * - (GRIB) use undefined flag only when set via lats_miss_XX
101  * - (GRIB) use delta when checking for missing data
102  * - (GRIB) define maximum and default precision
103  * - fixed lats_vartab to work correctly.
104  * - Added report of routine names, vertical dimension types
105  *
106  * Revision 1.8  1996/06/27 01:12:27  drach
107  * - Added setting timestat entry (removed from latsint.c)
108  *
109  * Revision 1.7  1996/06/11 21:43:33  fiorino
110  * version 0.1 --  first version for Bob D to test
111  *
112  * Revision 1.6  1996/05/31  18:58:06  fiorino
113  * v0.0
114  * before the new stuff from Bob
115  *
116  * Revision 1.5  1996/05/10  23:06:22  fiorino
117  * - test of commit
118  *
119  * Revision 1.4  1996/05/10  22:44:40  drach
120  * - Initial version before GRIB driver added:
121  * - Made grids, vertical dimensions file-independent
122  *
123  * Revision 1.3  1996/05/03 18:59:24  drach
124  * - Moved vertical dimension definition from lats_var to lats_vert_dim
125  * - Changed lats_miss_double to lats_miss_float
126  * - Made time dimension file-dependent, revised lats_write accordingly
127  * - Added lats_var_nc, lats_vert_dim_nc
128  * - Allow GRIB-only compilation
129  * - Added FORTRAN interface
130  *
131  * Revision 1.2  1996/04/25  23:32:05  drach
132  * - Added checks for correct number of times, levels written
133  * - Stubbed in statistics routines
134  *
135  * Revision 1.1  1996/04/25 00:53:00  drach
136  * Initial repository version
137  *
138  *
139  */
140
141 #define _POSIX_SOURCE 1
142 #include <stdlib.h>
143 #include <float.h>
144 #include <math.h>
145 #include "fgrib.h"
146 #include "fgrib_init.h"
147 #include "latsint.h"
148
149 #include "grads.h"
150 #define GRADS_CLIM_YEAR 2
151
152
153 /*mf 961205 --- expose Mike Fiorino's global struct to these routines for 365 day calandars mf*/
154 extern struct gamfcmn mfcmn;
155 /*mf 961205 --- expose Mike Fiorino's global struct to these routines for 365 day calandars mf*/
156
157 #define LATS_VERT_UNDEF 99
158
159 typedef struct latsgribfile {
160   FILE *gfi;
161   FILE *cfi;
162   latsCompTime time;  /* beginning time */
163   int gbmode;
164   char ctlname[256];
165 } latsGribFile;
166
167
168 /*---
169   prototypes
170 ---*/
171
172 int lats_pds_set(latsFile *file, latsVar *var,
173                  int levindex, int timeindex, latsCompTime time, grib_pds *);
174
175 int lats_gds_set(latsFile *file, latsVar *var,
176                  int levindex, int timeindex, latsCompTime time, grib_gds_ll *);
177
178 void lats_flt2int(float *, int *, int);
179
180 /* Generate a time statistic for a GRIB file. Return a pointer to the entry on success,
181  * 0 on failure.
182  */
183 latsTimeStatEntry* latsTimeStatLookup(latsTimeFreq frequency, int delta, latsTimeStat statistic){
184   latsTimeStatEntry *stat;
185
186   if((stat = (latsTimeStatEntry *)malloc(sizeof(latsTimeStatEntry)))==(latsTimeStatEntry *)0)
187     return 0;
188   stat->frequency = frequency;
189   stat->delta = delta;
190   stat->stat = statistic;
191
192   switch(frequency){
193   case LATS_YEARLY:
194     stat->grib_unit = 4;
195     break;
196   case LATS_MONTHLY:
197     stat->grib_unit = 3;
198     break;
199   case LATS_WEEKLY:
200     stat->grib_unit = 2;
201     break;
202   case LATS_DAILY:
203     stat->grib_unit = 2;
204     break;
205   case LATS_HOURLY:
206     stat->grib_unit = 1;
207     break;
208   case LATS_FORECAST_HOURLY:
209     stat->grib_unit = 1;
210     break;
211   case LATS_FIXED:
212     stat->grib_unit = 1;
213     break;
214   default:
215     latsError("GRIB (latsgrib.c) --> Invalid frequency: %d",frequency);
216     return 0;
217   }
218  
219   stat->grib_p3 = stat->grib_p2 = stat->grib_p1 = 0;
220   switch(statistic){
221   case LATS_AVERAGE:
222     stat->grib_p2 = delta;
223     stat->grib_timerange = 3;
224     break;
225   case LATS_INSTANT:
226     stat->grib_timerange = 0;
227     break;
228   case LATS_ACCUM:
229     stat->grib_p2 = delta;
230     stat->grib_timerange = 4;
231     break;
232   case LATS_OTHER_TIME_STAT:
233   default:
234     latsError("GRIB (latsgrib.c) --> Invalid time statistic: %d", statistic);
235     return 0;
236   }
237
238   if(frequency == LATS_WEEKLY) stat->grib_p2 *= 7;
239   if(frequency == LATS_FORECAST_HOURLY) stat->grib_timerange=10;
240
241   return stat;
242 }
243
244 /*-------------
245   Close a GRIB file. Returns 1 on success, 0 on failure.
246  --------------*/
247
248 int lats_close_grib(latsFile *file){
249
250   FILE *cfi;
251   FILE *gfi;
252   latsVar *var;
253   latsVar *vara[LATS_MAX_PARMS];
254   latsGribFile *gbfile;
255   char gmppath[LATS_MAX_PATH];
256   char gmpfile[LATS_MAX_PATH];
257   char grbfile[LATS_MAX_PATH];
258
259   char *mons[12] = {"jan","feb","mar","apr","may","jun","jul","aug",
260                     "sep","oct","nov","dec"};
261
262   char grads_options [3][50];
263
264   int i,j,k,j1,j2,ik;
265   int ni,nj,nk,nt;
266   int nvara;
267
268
269   float dx,dy,dum1;
270   float lonb,latb,lone,late;
271   int tv;
272
273   float *glon,*glat;
274   int nlev,ntype,l1,l2;
275   float undef;
276   int xdir=0,ydir=0,zdir=0;
277
278   int options_set=0;
279   int notaucheck;
280
281   gbfile = (latsGribFile *)file->depend;
282   gfi=gbfile->gfi;
283
284
285   if(file->convention != LATS_GRIB_ONLY) {
286
287
288     /*-----------------!!!!!!!!!!!!!!!!
289
290       Force gribmap to match by the base DTG ALWAYS
291       appropriate for AMIP II, but will have to be changed for NWP
292
293       !!!!!!!!!!!!!!!!!!-----------*/
294
295     if(file->frequency == LATS_FORECAST_HOURLY) {
296       notaucheck=0;
297     } else {
298       notaucheck=1;
299     }
300
301     /*---
302       set the calendar to support 365 day calendars in LATS_GRADS_GRIB
303       ---*/
304
305     mfcmn.cal365=1;
306     if( !(file->calendar & cdHasLeap) == 0) mfcmn.cal365=0;
307
308     cfi=stdout;
309     cfi=gbfile->cfi;
310  
311     if(VERB) {
312       printf("cccccccc nvertdim    %d\n",file->nvertdim);
313       printf("cccccccc nvar        %d\n",file->nvar);
314       printf("cccccccc ngrid       %d\n",file->ngrid);
315       printf("cccccccc ntimewriten %d\n",file->ntimewritten);
316     }
317
318     /*--- calc the grid from the first variable ----*/
319
320     var = file->varlist;
321
322     ni=var->grid->nlon;
323     nj=var->grid->nlat;
324     latb=var->grid->lats[0];
325     late=var->grid->lats[nj-1];
326     lonb=var->grid->lons[0];
327     lone=var->grid->lons[ni-1];
328  
329     /*--- check if uniform --- */
330
331 /* --- single value check, set dx to 0 ---- */
332
333     if(ni == 1) {
334
335       dx=0.0;
336
337     } else {
338 /*
339  * 970517 - add fuzz to check of constant grid increment ; for cray
340  */
341
342       dx=fabs(var->grid->lons[1]-var->grid->lons[0]);
343       for(i=2;i<ni;i++) {
344         if( fabs((fabs(var->grid->lons[i]-var->grid->lons[i-1]) - (double)dx )) > LATS_LINEAR_GRID_DELTA*dx) {
345           dx=-1.0;
346           break;
347         }
348       }
349
350     }
351
352
353     if(nj == 1) {
354
355       dy=0.0;
356
357     } else {
358
359       dy=fabs(var->grid->lats[1]-var->grid->lats[0]);
360       for(j=2;j<nj;j++) {
361         if( fabs((fabs(var->grid->lats[j]-var->grid->lats[j-1]) - (double)dy )) > LATS_LINEAR_GRID_DELTA*dy) {
362           dy=-1.0;
363           break;
364         }
365       }
366
367     }
368
369     /*----- undef is anything you like in GRIB ----*/
370
371     undef=1e20;
372
373     /*---
374       pull out the GRIB file name
375       ---*/
376
377     j=strlen(file->path)-5;
378     while( (size_t)j > 0 ) {
379       if( ( *(file->path+j) == '/' ) ||  ( *(file->path+j) == '\\' ) ) {
380         break;
381       }
382       j--;
383     }
384
385     if(j==0) {
386       j1=0;
387     } else {
388       j1=j+1;
389     }
390
391     for(j=j1;j<strlen(file->path);j++) {
392       j2=j-j1;
393       *(grbfile+j2)=*(file->path+j);
394     }
395     *(grbfile+j2+1)='\0';
396
397
398     /*---
399       pull out the gribmap file name
400       ---*/
401
402     strcpy(gmppath, file->path);
403     strcpy(gmppath+strlen(gmppath)-4, ".gmp");
404
405     j=strlen(file->path)-5;
406
407     while( (size_t)j > 0 ) {
408       if( ( *(gmppath+j) == '/' ) ||  ( *(gmppath+j) == '\\' ) ) {
409         break;
410       }
411       j--;
412     }
413
414
415     if(j==0) {
416       j1=0;
417     } else {
418       j1=j+1;
419     }
420
421     for(j=j1;j<strlen(gmppath);j++) {
422       j2=j-j1;
423       *(gmpfile+j2)=*(gmppath+j);
424     }
425     *(gmpfile+j2+1)='\0';
426
427     /*---
428       now set up the data stuff in the .ctl file
429       ---*/
430
431     fprintf(cfi,"dset ^%s\n",grbfile);
432     fprintf(cfi,"title %s\n",file->comments);
433     fprintf(cfi,"undef %g\n",undef);
434     fprintf(cfi,"dtype grib\n");
435     fprintf(cfi,"index ^%s\n",gmpfile);
436
437     /*---
438       options
439       ---*/
440
441     strcpy(grads_options[0]," ");
442     strcpy(grads_options[1]," ");
443     strcpy(grads_options[2]," ");
444     strcpy(grads_options[3]," ");
445
446     if(latb>late) {
447       ydir=1;
448       latb=late;
449       options_set=1;
450       strcpy(grads_options[0],"yrev");
451     }
452
453     if(mfcmn.cal365) {
454       options_set=1;
455       strcpy(grads_options[1],"365_day_calendar");
456     }
457    
458     if(options_set) {
459       fprintf(cfi,"options %s %s %s %s\n",grads_options[0],
460               grads_options[1],grads_options[2],grads_options[3]);
461     }
462
463     /*---------- xdef ------------ */
464
465     if(dx > 0.0) {
466       fprintf(cfi,"xdef %d linear %f %f\n",ni,lonb,dx);
467     } else {
468
469       if(ni == 1) {
470         fprintf(cfi,"xdef %d levels % 7.3f\n",ni,var->grid->lons[0]);
471       } else {
472         fprintf(cfi,"xdef %d levels\n",ni);
473         if(xdir) {
474           for (i=ni-1;i>=0;i--) {
475             fprintf(cfi,"% 7.3f ",var->grid->lons[i]);
476             if((i-ni)%10 == 0) fprintf(cfi,"\n");
477           }
478         } else {
479           for (i=0;i<ni;i++) {
480             fprintf(cfi,"% 7.3f ",var->grid->lons[i]);
481             if((i-1)%10 == 0) fprintf(cfi,"\n");
482           }
483         }
484         if(ni%10 != 0) fprintf(cfi,"\n");
485        
486       }
487     }
488
489     /*---------- ydef ------------ */
490
491     if(nj == 1) {
492       fprintf(cfi,"ydef %d levels % 7.3f\n",nj,var->grid->lats[0]);
493     } else {
494
495       if(dy > 0.0) {
496         fprintf(cfi,"ydef %d linear %f %f\n",nj,latb,dy);
497       } else {
498         fprintf(cfi,"ydef %d levels\n",nj);
499         if(ydir) {
500           for (j=nj-1;j>=0;j--) {
501             fprintf(cfi,"% 7.3f ",var->grid->lats[j]);
502             if((j-nj)%10 == 0) fprintf(cfi,"\n");
503           }
504         } else {
505           for (j=0;j<nj;j++) {
506             fprintf(cfi,"% 7.3f ",var->grid->lats[j]);
507             if((j-1)%10 == 0) fprintf(cfi,"\n");
508           }
509         }
510         if(nj%10 != 0) fprintf(cfi,"\n");
511       }
512
513     }
514
515     /*---------- zdef ---------- */
516
517     nk=0;
518     k=0;
519     ik=0;
520     for(i=0;i<file->nvertdim;i++) {
521       if(file->vertlist[i].nlev > k) {
522         k=file->vertlist[i].nlev;
523         ik=i;
524       }
525     }
526
527     if(k == 0) {
528
529       fprintf(cfi,"zdef 1 levels 1013\n");
530
531     } else {
532
533       nk=file->vertlist[ik].nlev;
534 /*
535  *
536  *  round the level vealues to ints because GRIB 1 does not
537  *  support storing of floats in the PDS for levels
538  *
539  */
540       if(nk == 1) {
541
542         dum1=(float)file->vertlist[ik].levs[0]+0.5;
543         fprintf(cfi,"zdef %d levels %d\n",nk,(int)dum1);
544
545       } else {
546
547         fprintf(cfi,"zdef %d levels\n",nk);
548         if(file->vertlist[ik].levs[0] <= file->vertlist[ik].levs[nk-1]) zdir=1;
549         if(zdir) {
550           for (k=nk-1;k>=0;k--) {
551             dum1=(float)file->vertlist[ik].levs[k]+0.5;
552             fprintf(cfi,"%d ",(int)dum1);
553             if((k-nk)%10 == 0) fprintf(cfi,"\n");
554           }
555         } else {
556           for (k=0;k<nk;k++) {
557             dum1=(float)file->vertlist[ik].levs[k]+0.5;
558             fprintf(cfi,"%d ",(int)dum1);
559             if((k+1)%10 == 0) fprintf(cfi,"\n");
560           }
561         }
562         if(nk%10 != 0) fprintf(cfi,"\n");
563       }
564
565     }
566     /*---------- tdef ------------ */
567
568
569     if(file->frequency == LATS_FIXED) {
570
571       fprintf(cfi,"tdef 1 linear 00Z1jan0001 1dy\n");
572
573     } else {
574
575       /*---
576         COARDS convention for climo -> my convention for climo year
577         ---*/
578
579       if( !(file->calendar & cdStandardCal) ) {
580         gbfile->time.year = GRADS_CLIM_YEAR;
581       }
582
583       fprintf(cfi,"tdef %d linear %dZ%d%s%04d ",file->ndelta,
584               (int)gbfile->time.hour,
585               gbfile->time.day,
586               mons[gbfile->time.month-1],
587               gbfile->time.year );
588
589       if(file->frequency == LATS_HOURLY)  fprintf(cfi," %dhr\n",file->delta);
590       if(file->frequency == LATS_FORECAST_HOURLY)  fprintf(cfi," %dhr\n",file->delta);
591       if(file->frequency == LATS_DAILY)   fprintf(cfi," %ddy\n",file->delta);
592       if(file->frequency == LATS_WEEKLY)  fprintf(cfi," %ddy\n",file->delta*7);
593       if(file->frequency == LATS_MONTHLY) fprintf(cfi," %dmo\n",file->delta);
594       if(file->frequency == LATS_YEARLY) fprintf(cfi," %dyr\n",file->delta);
595
596     }
597
598     /*----------- vars ------------ */
599
600     fprintf(cfi,"vars %d\n",file->nvar);
601 /*
602  *
603  * save var struct so we can reverse order (the way we defined the vars)
604  * to the ctl file
605  *
606  */
607     nvara=file->nvar-1;
608     for(var = file->varlist; var; var = var->next){
609       vara[nvara]=var;
610       nvara--;
611     }
612
613 /*
614  * original version
615  *
616  *   for(var = file->varlist; var; var = var->next){
617  *
618  *  write out the vars the way we defined them
619  */
620
621     for( nvara=0 ; nvara < file->nvar ; nvara++ ){
622       var=vara[nvara];
623
624       /* If the vertical dimension was declared explicitly
625          via lats_vert_dim ...*/
626       if(var->vertdim != NULL){
627         ntype=var->vertdim->type->gribid;
628         l1=var->vertdim->type->grib_p1;
629         l2=var->vertdim->type->grib_p2;
630       }
631       /* Else if the vertical dimension is implicit, via the
632          leveltype of the variable in the parameter table ...*/
633       else if(var->parm->levelset == 1){
634         ntype=var->parm->verttype->gribid;
635         if(var->parm->verttype->grib_p3 != 0) {
636           l1=var->parm->verttype->grib_p3;
637           l2=0;
638         } else {
639           l1=var->parm->verttype->grib_p1;
640           l2=var->parm->verttype->grib_p2;
641         }
642       }
643       /* Else no vertical dimension */
644       else{
645         ntype=LATS_VERT_UNDEF;
646         l1=0;
647         l2=0;
648       }
649
650       if(var->parm->levelset == 1 ) {
651         nlev=0;
652
653         if(var->parm->verttype->grib_p3 != 0) {
654           fprintf(cfi,"%-8s %2d  %3d,%3d,%3d %s [%s]\n",
655                   var->name,nlev,var->parm->id,
656                   ntype,l1,  /*----- set above -----*/
657                   var->parm->title,var->parm->units);
658         } else {
659           fprintf(cfi,"%-8s %2d  %3d,%3d,%3d,%3d %s [%s]\n",
660                   var->name,nlev,var->parm->id,
661                   ntype,l1,l2,
662                   var->parm->title,var->parm->units);
663         }
664
665       } else {
666
667         fprintf(cfi,"%-8s %2d  %3d,%3d %s [%s]\n",
668                 var->name,var->nlev,var->parm->id,ntype,
669                 var->parm->title,var->parm->units);
670
671       }
672    
673     }
674
675     fprintf(cfi,"endvars\n");
676
677     /*------ close ------*/
678
679     fclose(gfi);
680     fclose(cfi);
681
682     /*----- run gribmap ----*/
683
684     latsgribmap(gbfile->ctlname,notaucheck);
685
686     free(gbfile);
687     return 1;
688
689
690     /*--- only create GRIB data ---- */
691
692   } else {
693
694     fclose(gfi);
695     free(gbfile);
696     return 1;
697    
698   }
699
700 }
701
702 /*----------------------------------------
703  *
704  * Create a GRIB file. Returns the file ID, or 0 on error
705  *
706  ---------------------------------------*/
707
708 int lats_create_grib(latsFile *file){
709   FILE *gfi;
710   FILE *cfi;
711   latsGribFile *gbfile;
712   char *gname;
713   int j;
714
715   gname = (char *)malloc(strlen(file->path)+5);
716   if(gname == NULL) {
717     latsError("GRIB (latsgrib.c) --> Allocating memory for GRIB file name %s", file->path);
718     return 0;
719   }
720  
721   j=0;
722   while( (size_t)j < strlen(file->path) ) {
723     *(gname+j) = *(file->path+j);
724     j++;
725   }
726   *(gname+j) = '\0';
727
728   if((gbfile = (latsGribFile *)malloc(sizeof(latsGribFile)))==0){
729     latsError("GRIB (latsgrib.c) --> Allocating memory for GRIB file name %s", file->path);
730     return 0;
731   }
732
733   gfi=fopen(gname,"wb") ;
734   if(gfi == NULL) {
735     latsError("GRIB (latsgrib.c) --> lats_create create .grb failed for %s\n",gname);
736     return 0;
737   }
738
739   if(file->convention != LATS_GRIB_ONLY) {
740                                              /* Make sure that GrADS control file has a title */
741     if(strlen(file->comments)==0)
742       strcpy(file->comments, file->center);
743
744     j=0;
745     while( (size_t)j < strlen(file->path) ) {
746       *(gname+j) = *(file->path+j);
747       j++;
748     }
749     *(gname+j) = '\0';
750       strcpy(gname+strlen(gname)-4,".ctl");
751      
752       cfi=fopen(gname,"w") ;
753       if(cfi == NULL) {
754         latsError("GRIB (latsgrib.c) --> lats_create create .ctl failed for %s\n",gname);
755         return 0;
756       }
757
758   } else {
759
760     cfi=NULL;
761
762   }
763  
764 /*------ initialize the first time flag in gbfile struct */
765
766   gbfile->gbmode=1;
767   gbfile->gfi=gfi;
768   gbfile->cfi=cfi;
769   strcpy(gbfile->ctlname,gname);
770   free(gname);
771
772
773   file->depend = (void *)gbfile;
774
775
776   return file->id;
777
778 }
779
780
781 /*----------------------------------------
782  * Define a grid for a GRIB 'file'.
783  * Return 1 on success, 0 on failure;
784  *
785  * Note: this routine is called by lats_var for the
786  *   first variable which is defined on this grid.
787  *
788  * Note: This routine is a no-op
789  -----------------------------------------*/
790 int lats_grid_grib(latsFile *file, latsGrid *grid){
791         if(file->ngrid > 1 && file->convention==LATS_GRADS_GRIB){
792                 latsError("GRIB (latsgrib.c) --> Only one grid per file supported in the GrADS/GRIB convention; file: %s, grid: %s",
793                           file->path, grid->name);
794                 return 0;
795         }
796         return 1;
797 }
798
799 /* Define a variable to be written to a GRIB file.
800  * 'grid' is the grid structure.
801  * 'vertdim' is the vertical dimension structure, or 0 no level.
802  * Return the variable ID on success, 0 on failure.
803  */
804
805 int lats_var_grib(latsFile *file, latsVar *var, latsGrid *grid, latsVertDim *vertdim){
806
807   return var->id;
808 }
809
810 /*----------------------------------------
811  *
812  * Write a vertical dimension 'vertdim' to GRIB 'file'.
813  * Return dimension ID on success, 0 on failure.
814  *
815  -----------------------------------------*/
816 int lats_vert_dim_grib(latsFile *file, latsVertDim *vertdim) {
817
818   if(file->latsmode != LATS_MODE_DEFINE){
819     latsError("GRIB (latsgrib.c) --> lats_vert_dim calls must precede any lats_write call");
820     return 0;
821   }
822
823   return file->nvertdim;
824 }
825
826 /*----------------------------------------
827  *
828  * Write a horizontal lon-lat section 'data' for variable 'var' to GRIB 'file'.
829  * 'levindex' is the 0-origin index, into var->levs, of the level value, or -1 if there are no levels.
830  * 'timeindex' is the 0-origin index of the time value, or -1 if there are no times.
831  * Return 1 on success, 0 on failure.
832  *
833  -----------------------------------------*/
834
835 int lats_write_grib(latsFile *file, latsVar *var,
836                     int levindex, int timeindex, latsCompTime time, void *data) {
837
838   FILE *gfi;
839   int i,j,k;
840   float undef, undef_delta;
841   int rc,rcp,rcg,rcb;
842   int glen;
843   float *dataf;
844   latsGribFile *gbfile;
845  
846  
847 /*---
848   GRIB section pointers
849 ---*/
850
851   grib_is *is;
852   grib_pds *pds;
853   grib_gds_ll *gds; 
854   grib_bms *bms;
855   grib_bds *bds;
856   grib_es *es;
857
858 /*---
859   point to  the default static GRIB section structs
860 ---*/
861
862   is=&FGRIBAPI_is;
863   pds=&FGRIBAPI_pds;
864   gds=&FGRIBAPI_gds;
865   bms=&FGRIBAPI_bms;
866   bds=&FGRIBAPI_bds;
867   es=&FGRIBAPI_es;
868
869   pds->pds=(unsigned char *) malloc(pds->len);
870
871 /*---
872   initial checks
873 ---*/
874
875   if(var->parm->datatype == LATS_INT) {
876
877     lats_flt2int(data,data,(var->grid->nlon*var->grid->nlat));
878
879 /*    return 100;  */
880   }
881
882 /*---
883   point to the GRIB file struct
884 ---*/
885
886   gbfile = (latsGribFile *)file->depend;
887
888   gfi=gbfile->gfi;
889    
890   if(VERB) {
891     printf("vvv %s\n",var->name);
892     if(var->parm->datatype == LATS_FLOAT) printf("vvv DATA TYPE is float\n");
893     if(var->parm->datatype == LATS_INT) printf("vvv DATA TYPE is int\n");
894     printf("vvv GRIB id = %d\n",var->parm->id);
895     printf("vvv GRIB dsf = %d\n",var->scalefac);
896     printf("vvv GRIB bits per grid point = %d\n",var->precision);
897   }
898
899 /*---
900  * undef values
901  ---*/
902
903   if(var->hasmissing) {
904
905     if(var->parm->datatype == LATS_FLOAT) {
906       if(VERB) {
907         printf("vvv %g missing float\n",var->missing.f);
908         printf("vvv %g missing delta float\n",var->missingdelta);
909       }
910       undef=var->missing.f;
911       undef_delta = var->missingdelta;
912     }
913
914     if(var->parm->datatype == LATS_INT) {
915       if(VERB) {
916         printf("vvv %d missing integer\n",var->missing.i);
917         printf("vvv %g missing delta integer\n",var->missingdelta);
918       }
919       undef=(float)var->missing.i;
920       undef_delta = 0.0;
921     }
922
923   } else {
924     if(VERB) printf("vvv NO MISSING DATA\n");
925   }
926
927
928 /*---
929  * create the PDS, GDS and BDS (BMS)
930  ---*/
931
932   rcp=lats_pds_set(file,var,levindex,timeindex,time,pds) ;
933   rcg=lats_gds_set(file,var,levindex,timeindex,time,gds) ;
934   rcb=bds_set(data,pds,bds,bms,undef,gds->ni*gds->nj,pds->nbits,var->hasmissing,undef_delta);
935
936   if(rcp) {
937     latsError("GRIB (latsgrib.c) --> bds_set failed rc = %d\n",rcp);
938     return 0;
939   } else if(rcg) {
940     latsError("GRIB (latsgrib.c) --> gds_set failed rc = %d\n",rcg);
941     return 0;
942   } else if(rcb) {
943     latsError("GRIB (latsgrib.c) --> bds_set failed rc = %d\n",rcb);
944     return 0;
945   }
946
947   glen=is->len + pds->len + gds->len + bms->len + bds->len + es->len ;
948
949   if(VERB) printf("vvv glen %d %d %d %d %d %d\n",
950                   glen,is->len,pds->len,gds->len,bms->len,bds->len,es->len);
951
952   rc=is_set(is,glen) ;
953   if(rc) {
954     latsError("GRIB (latsgrib.c) --> is_set failed rc = %d\n",rc);
955     return 0;
956   }
957
958 /*---
959  * write out the sections
960  ---*/
961
962   rc=fwrite(is->is,sizeof(char),is->len,gfi) ;
963   rc=fwrite(pds->pds,sizeof(char),pds->len,gfi) ;
964   rc=fwrite(gds->gds,sizeof(char),gds->len,gfi) ;
965   if(bms->len) rc=fwrite(bms->bms,sizeof(char),bms->len,gfi) ;
966   rc=fwrite(bds->bds,sizeof(char),bds->len,gfi) ;
967   rc=fwrite(es->es,sizeof(char),es->len,gfi) ;
968
969   if(gbfile->gbmode) {
970     gbfile->time=time;
971     gbfile->gbmode=0;
972   }
973
974   free(pds->pds);
975   free(gds->gds);
976
977   return 1;
978
979 }
980
981 int is_set(grib_is *is, unsigned int glen) {
982   set_int3(&is->is[4],glen);
983   is->is[7]=1;
984   return 0;
985 }
986
987 /*-----------------------------------
988  *
989  *  LATS GRIB PDS routine
990  *
991  -------------------------------------*/
992
993 int lats_pds_set(latsFile *file, latsVar *var,
994                     int levindex, int timeindex, latsCompTime time, grib_pds *pds) {
995
996   unsigned char cent,yr,mo,da,hr,mn;
997   float dum1;
998
999 /*---
1000   time processing
1001 ---*/
1002
1003   if(file->frequency == LATS_FORECAST_HOURLY) {
1004
1005     cent=(unsigned char)(((int)((float)(file->btime.year*0.01)+0.001))+1);
1006     yr=(unsigned char)(((float)file->btime.year-((float)cent-1.0)*100.0)+0.1);
1007     mo=(unsigned char)(file->btime.month);
1008     da=(unsigned char)(file->btime.day);
1009     hr=(unsigned char)((int)file->btime.hour+0.1);
1010     mn=0;                                      /* set minute to 0 */
1011
1012
1013   } else {
1014
1015     cent=(unsigned char)(((int)((float)(time.year*0.01)+0.001))+1);
1016     yr=(unsigned char)(((float)time.year-((float)cent-1.0)*100.0)+0.1);
1017     mo=(unsigned char)(time.month);
1018     da=(unsigned char)(time.day);
1019     hr=(unsigned char)((int)time.hour+0.1);
1020     mn=0;                                      /* set minute to 0 */
1021
1022   }
1023
1024   /*mf 970820
1025     --- correct coding for last year of the century is:
1026
1027     year=100
1028     century=century-1
1029
1030     mf*/
1031
1032   if(yr == 0) {
1033     yr=100;
1034     cent=cent-1;
1035   }
1036
1037
1038 /*---
1039   case with 0 start year -- set to 1776
1040 ---*/
1041 /*DDDD 970122 disable because lats.c should prevent this */
1042 /*
1043   if(yr == 0 && cent == 0) {
1044     cent=( GRADS_CLIM_YEAR / 100 ) + 1;
1045     yr=GRADS_CLIM_YEAR - ( ( GRADS_CLIM_YEAR / 100 ) * 100 ) ;
1046   }
1047 */
1048
1049 /*---
1050   set time to the default for fixed data irregardless of the input time
1051 ---*/
1052 /*DDDD 970122 disable because lats.c should prevent this */
1053 /*
1054   if(file->frequency == LATS_FIXED ) {
1055
1056     cent=1;
1057     yr=1;
1058     mo=1;
1059     da=1;
1060     hr=0;
1061   }
1062 */
1063
1064 /*---
1065   set time to the default for climo data irregardless of the input time
1066 ---*/
1067
1068   if( !(file->calendar & cdStandardCal) && !(file->frequency == LATS_FIXED) ) {
1069     cent=( GRADS_CLIM_YEAR / 100 ) + 1;
1070     yr=GRADS_CLIM_YEAR - ( ( GRADS_CLIM_YEAR / 100 ) * 100 ) ;
1071   }
1072
1073   if(VERB) {
1074     printf("------- %d %d %d %d %d\n",cent,yr,mo,da,hr)  ;
1075     printf("ttt %d %d %d %f\n",time.year,time.month,time.day,time.hour);
1076   }
1077
1078 /*
1079    ------------ set the pds
1080 */
1081
1082   pds->ver=128;                    /* our own table version */
1083   pds->ctr=file->grib_center;      /* from table */
1084   pds->sctr=file->grib_subcenter;  /* subcenter is AMIP II */
1085   pds->proc=file->centerid;        /* dummy model */
1086
1087   pds->parm=var->parm->id;
1088                                              /* Note: Get scalefac, precision from var->..., */
1089                                              /* since these have correct values if parameter */
1090                                              /* table has been overridden (e.g., for monthly data) */
1091
1092   pds->dsf=var->scalefac;
1093   pds->nbits=var->precision;
1094   if(pds->dsf == -999 && pds->nbits == -999)
1095           pds->nbits = DEFAULT_NBITS;        /* If no precision or decimal scale factor set,
1096                                               use default number of bits. */
1097 /*
1098    ----------- vertical defintion
1099 */
1100
1101                                              /* If the vertical dimension was declared explicitly
1102                                               via lats_vert_dim ...*/
1103   if(var->vertdim != NULL){
1104
1105       pds->ltyp=var->vertdim->type->gribid;
1106       dum1=(float)var->vertdim->levs[levindex]+0.5;
1107       pds->l12=(int)dum1;
1108
1109 /*     
1110       if(pds->ltyp == 100) {
1111         pds->l12=var->vertdim->levs[levindex];
1112       } else {
1113         pds->l1=var->vertdim->type->grib_p1;
1114         pds->l2=var->vertdim->type->grib_p2;
1115         pds->l12=var->vertdim->type->grib_p3;
1116       }
1117 */
1118      
1119   }
1120                                              /* Else if the vertical dimension is implicit, via the
1121                                               leveltype of the variable in the parameter table ...*/
1122   else if(var->parm->levelset == 1){
1123       pds->ltyp=var->parm->verttype->gribid;
1124       pds->l1=var->parm->verttype->grib_p1;
1125       pds->l2=var->parm->verttype->grib_p2;
1126       pds->l12=var->parm->verttype->grib_p3;
1127   }
1128                                              /* Else no vertical dimension */
1129   else {
1130       pds->ltyp=LATS_VERT_UNDEF;
1131       pds->l1=0;
1132       pds->l2=0;
1133   }
1134
1135   pds->cent=cent;
1136   pds->yr=yr;
1137   pds->mo=mo;
1138   pds->da=da;
1139   pds->hr=hr;
1140   pds->mn=mn;
1141
1142 if(var->timestat == NULL ) {
1143   printf("Sayoonara, where out of here, timestat not properly set\n");
1144   printf("contact fiorino@llnl.gov\n");
1145   exit (6969);
1146 }
1147
1148 /*---
1149    -------- the time is defined in latsTimeStatLookup
1150 ---*/
1151
1152   pds->ftu=var->timestat->grib_unit; 
1153   pds->p1=var->timestat->grib_p1;
1154   pds->p2=var->timestat->grib_p2;
1155   pds->p12=var->timestat->grib_p3;
1156   pds->tri=var->timestat->grib_timerange;
1157
1158 /*
1159  *    forecast hour uses time range of of 10 from latsTimeStatLookup
1160  *    set the forecast hour in p12
1161  */
1162
1163   if(file->frequency == LATS_FORECAST_HOURLY) {
1164     pds->p12=file->fhour;
1165   }
1166
1167
1168 /*----
1169   if climo set time range indicator to 51
1170 ---*/
1171
1172   if( (file->calendar & cdClimCal) ) pds->tri=51;
1173
1174 /*---
1175   CREATE THE PDS
1176 ----*/
1177
1178   set_int3(&pds->pds[0],pds->len);
1179
1180   pds->pds[3]=pds->ver;
1181   pds->pds[4]=pds->ctr;
1182   pds->pds[5]=pds->proc;
1183   pds->pds[6]=pds->grid;
1184
1185   pds->pds[7]=0;
1186   if(pds->gflg) SETBIT(pds->pds[7],7);
1187                                              /* By default, no bit map section
1188                                                 pds->bflg is set in bds_set.
1189                                               */
1190 /*   if(pds->bflg) SETBIT(pds->pds[7],6);
1191  */
1192
1193   pds->pds[8]=pds->parm;
1194   pds->pds[9]=pds->ltyp;
1195
1196 /*
1197  *
1198  * strict GRIB standard  - Gospel according to John
1199  *
1200  */
1201
1202 /*
1203   if( (pds->ltyp == 100) ||
1204      (pds->ltyp == 103) ||
1205      (pds->ltyp == 107) ||
1206      (pds->ltyp == 105) ||
1207      (pds->ltyp == 109) ||
1208      (pds->ltyp == 111) ||
1209      (pds->ltyp == 113) ||
1210      (pds->ltyp == 115) ||
1211      (pds->ltyp == 125) ||
1212      (pds->ltyp == 160) )   {
1213
1214  */
1215
1216 /*
1217  *
1218  *  looser LATS standard
1219  *
1220  */
1221
1222   if(var->vertdim != NULL ||
1223      (var->parm->levelset==1 && var->parm->verttype->grib_p3 != 0)){
1224      set_int2(&pds->pds[10],((int)pds->l12+0.5));
1225   } else {
1226     pds->pds[10]=pds->l1;
1227     pds->pds[11]=pds->l2;
1228   }
1229
1230   pds->pds[12]=pds->yr;
1231   pds->pds[13]=pds->mo;
1232   pds->pds[14]=pds->da;
1233   pds->pds[15]=pds->hr;
1234   pds->pds[16]=pds->mn;
1235   pds->pds[17]=pds->ftu;
1236
1237   if( (pds->tri == 10) ) {
1238     set_int2(&pds->pds[18],pds->p12);
1239   } else {
1240     pds->pds[18]=pds->p1;
1241     pds->pds[19]=pds->p2;
1242   }
1243   pds->pds[20]=pds->tri;
1244   set_int2(&pds->pds[21],pds->nave);
1245   pds->pds[23]=pds->nmis;
1246   pds->pds[24]=pds->cent;
1247   pds->pds[25]=pds->sctr;
1248   set_int2(&pds->pds[26],(unsigned int)abs(pds->dsf));
1249   if(pds->dsf<0) SETBIT(pds->pds[26],7);
1250
1251   if(VERB) {
1252
1253     printf("PPP (1-3)      %d\n",pds->len);
1254     printf("PPP 4          %d %d\n",pds->pds[3],pds->ver);
1255     printf("PPP 5          %d %d\n",pds->pds[4],pds->ctr);
1256     printf("PPP 6          %d %d\n",pds->pds[5],pds->proc);
1257     printf("PPP 7          %d %d\n",pds->pds[6],pds->grid);
1258     printf("PPP 8 B1       %d %d\n",pds->pds[7],pds->gflg);
1259     printf("PPP 8 B2       %d %d\n",pds->pds[7],pds->bflg);
1260     printf("PPP 9          %d %d\n",pds->pds[8],pds->parm);
1261     printf("PPP 10         %d %d\n",pds->pds[9],pds->ltyp);
1262     printf("PPP (11-12)    %d %d %d %d %d\n",
1263            pds->pds[10],pds->pds[11],pds->l1,pds->l2,pds->l12);
1264     printf("PPP 13         %d %d\n",pds->pds[12],pds->yr);
1265     printf("PPP 14         %d %d\n",pds->pds[13],pds->mo);
1266     printf("PPP 15         %d %d\n",pds->pds[14],pds->da);
1267     printf("PPP 16         %d %d\n",pds->pds[15],pds->hr);
1268     printf("PPP 17         %d %d\n",pds->pds[16],pds->mn);
1269     printf("PPP 18         %d %d\n",pds->pds[17],pds->ftu);
1270     printf("PPP (19-20)    %d %d %d %d %d\n",
1271            pds->pds[18],pds->pds[19],pds->p1,pds->p2,pds->p12);
1272     printf("PPP 21         %d %d\n",pds->pds[20],pds->tri);
1273     printf("PPP (22-23)    %d\n",pds->nave);
1274     printf("PPP 24         %d %d\n",pds->pds[23],pds->nmis);
1275     printf("PPP 25         %d %d\n",pds->pds[24],pds->cent);
1276     printf("PPP 26         %d %d\n",pds->pds[25],pds->sctr);
1277     printf("PPP (27-28)    %d\n",INT2(pds->pds[26],pds->pds[27]));
1278
1279   }
1280
1281   return 0;
1282 }
1283
1284
1285 /*-----------------------------------
1286  *
1287  *  LATS GRIB GDS routine
1288  *
1289  -------------------------------------*/
1290
1291 int lats_gds_set(latsFile *file, latsVar *var,
1292                     int levindex, int timeindex, latsCompTime time, grib_gds_ll *gds) {
1293
1294
1295   int i,j,k;
1296   int ni,nj;
1297   float dx,dy, dtmp;
1298   float lonb,latb,lone,late;
1299   int tv;
1300
1301   double *glon,*glat;
1302   int ndx;
1303
1304   float undef;
1305   /*---
1306     grid type
1307     ---*/
1308
1309   ni=var->grid->nlon;
1310   nj=var->grid->nlat;
1311   latb=var->grid->lats[0];
1312   late=var->grid->lats[nj-1];
1313   lonb=var->grid->lons[0];
1314   lone=var->grid->lons[ni-1];
1315  
1316   /*--- check if uniform --- */
1317                                              /* Note: lats[], lons[] were checked for
1318                                                 strict monotonicity in lats_grid/latsCheckMono
1319                                               */
1320
1321   dx=fabs(var->grid->lons[1]-var->grid->lons[0]);
1322   dy=fabs(var->grid->lats[1]-var->grid->lats[0]);
1323   for(i=2;i<ni;i++) {
1324           dtmp = fabs(var->grid->lons[i]-var->grid->lons[i-1]);
1325           if(dtmp<=(1.0-LATS_LINEAR_GRID_DELTA)*dx || dtmp>=(1.0+LATS_LINEAR_GRID_DELTA)*dx){
1326                   dx=-1.0;
1327                   break;
1328           }
1329   }
1330
1331   for(j=2;j<nj;j++) {
1332           dtmp = fabs(var->grid->lats[j]-var->grid->lats[j-1]);
1333           if(dtmp<=(1.0-LATS_LINEAR_GRID_DELTA)*dy || dtmp>=(1.0+LATS_LINEAR_GRID_DELTA)*dy){
1334                   dy=-1.0;
1335                   break;
1336           }
1337   }
1338
1339 /*---
1340  * check if grid OK
1341  *--*/
1342
1343   if(lonb>lone) {
1344     latsError("GRIB (latsgrib.c) --> has longitude DECREASING with increasing index");
1345     return 999;
1346   }
1347
1348
1349   if( (var->grid->type == LATS_LINEAR)
1350      && ( (dx < 0.0) || (dy < 0.0) ) ) {
1351     latsError("GRIB (latsgrib.c) --> grid classified as LATS_LINEAR but dx and dy are NOT constant");
1352     return 999;
1353   }
1354
1355   if(VERB) {
1356
1357     if(var->grid->type == LATS_GAUSSIAN) {
1358       printf("ggg TYPE a gauss grid\n");
1359       printf("ggg dx = %g\n",dx);
1360     }
1361
1362     if(var->grid->type == LATS_LINEAR) {
1363       printf("ggg TYPE uniform lat/lon grid\n");
1364       printf("ggg dx, dy = %g %g\n",dx,dy);
1365     }
1366  
1367     if(var->grid->type == LATS_GENERIC) printf("ggg TYPE generic grid\n");
1368
1369   }
1370
1371
1372 /*---
1373   drt=0 ---- data representation type for equidistant lon/lat grid
1374 ---*/
1375
1376   if(var->grid->type == LATS_LINEAR) {
1377
1378     gds->nv=0;
1379     gds->pv=255;
1380     gds->drt=0;
1381     gds->ni=ni;
1382     gds->nj=nj;
1383     gds->len=32;
1384
1385 /*---
1386   drt=4 ---- Gaussian Grids
1387 ---*/
1388
1389   } else if(var->grid->type == LATS_GAUSSIAN) {
1390     gds->nv=0;
1391     gds->pv=255;
1392     gds->drt=4;
1393     gds->len=32;
1394     gds->ni=ni;
1395     gds->nj=nj;
1396     dy=(int)(((gds->nj)/2));
1397
1398 /*---
1399   drt=220 ----  PCMDI CONVENTION FOR generic lon/lat grids
1400 ---*/
1401   } else if(var->grid->type == LATS_GENERIC) {
1402     gds->nv=0;
1403     gds->pv=255;
1404     gds->drt=220;
1405     gds->ni=ni;
1406     gds->nj=nj;
1407     gds->len=24 + ((ni)*3) + ((nj)*3);
1408     /*    printf("generic lat/lon GRID gds len = %d\n",gds->len); */
1409   }
1410
1411 /*----
1412  * CREATE THE GDS
1413  ----*/
1414
1415   gds->gds=(unsigned char *) malloc(gds->len);
1416   set_int3(&gds->gds[0],gds->len);
1417
1418   gds->gds[3]=gds->nv;
1419   gds->gds[4]=gds->pv;
1420   gds->gds[5]=gds->drt;
1421   set_int2(&gds->gds[6],gds->ni);
1422   set_int2(&gds->gds[8],gds->nj);
1423   gds->lat1=(int)(fabs(latb*1000.0)+0.5);
1424   gds->lon1=(int)(fabs(lonb*1000.0)+0.5);
1425   if(latb<0) gds->lat1=-gds->lat1;
1426   if(lonb<0) gds->lon1=-gds->lon1;
1427   set_int3(&gds->gds[10],(unsigned int)abs(gds->lat1));
1428   if(latb<0) SETBIT(gds->gds[10],7);
1429   set_int3(&gds->gds[13],(unsigned int)abs(gds->lon1));
1430   if(lonb<0) SETBIT(gds->gds[13],7);
1431  
1432   gds->gds[16]=0;
1433   gds->rcdi=1; /* dx and dy will be specfied for this grid */
1434   if(gds->rcdi) SETBIT(gds->gds[16],7);
1435   if(gds->rcre) SETBIT(gds->gds[16],6);
1436   if(gds->rcuv) SETBIT(gds->gds[16],3);
1437
1438   gds->lat2=(int)(late*1000+0.5);
1439   gds->lon2=(int)(lone*1000+0.5);
1440   set_int3(&gds->gds[17],(unsigned int)abs(gds->lat2));
1441   if(late<0) SETBIT(gds->gds[17],7);
1442   set_int3(&gds->gds[20],(unsigned int)abs(gds->lon2));
1443   if(lone<0) SETBIT(gds->gds[20],7);
1444
1445   if(gds->drt != 220) {
1446     gds->dx=(int)(dx*1000+0.5);
1447     /* For Gaussian, dy is the number of latitudes between equator and pole */
1448     if(gds->drt == 4)
1449             gds->dy = dy;
1450     else
1451             gds->dy=(int)(dy*1000+0.5);
1452     set_int2(&gds->gds[23],(unsigned int)abs(gds->dx));
1453     if(dx<0) SETBIT(gds->gds[23],7);
1454     set_int2(&gds->gds[25],(unsigned int)abs(gds->dy));
1455     if(dy<0) SETBIT(gds->gds[25],7);
1456
1457 /*---  scan mode flags 
1458     (lon,lat) grids only
1459     (lone > lonb ) (xrev not supported)
1460 ----*/
1461
1462     gds->gds[27]=0;
1463     if(latb < late) gds->smj=1 ;
1464
1465     if(gds->smi) SETBIT(gds->gds[27],0);
1466     if(gds->smj) SETBIT(gds->gds[27],1);
1467     if(gds->smdir) SETBIT(gds->gds[27],2);
1468
1469
1470   } else {
1471
1472 /*---
1473  * code the lon and lats
1474  ---*/
1475
1476     glon=var->grid->lons;
1477     glat=var->grid->lats;
1478     ndx=23;
1479
1480     for(i=0;i<ni;i++) {
1481      
1482       set_int3(&gds->gds[ndx],(unsigned int)abs((int)(*(glon+i)*1000+0.5)));
1483         if(*(glon+i)<0) SETBIT(gds->gds[ndx],7);
1484       if(VERB) printf("lon....... gggg %d %d %f\n",i,ndx,*(glon+i));
1485       ndx+=3;
1486
1487     }
1488
1489     for(j=0;j<nj;j++) {
1490      
1491       set_int3(&gds->gds[ndx],(unsigned int)abs((int)(*(glat+j)*1000+0.5)));
1492       if(*(glat+j)<0) SETBIT(gds->gds[ndx],7);
1493       if(VERB) printf("lat....... gggg %d %d %f\n",j,ndx,*(glat+j));
1494       ndx+=3;
1495
1496     }
1497
1498   }
1499
1500   if(VERB) {
1501     printf("GGG (1-3)      %d\n",gds->len);
1502     printf("GGG 4          %d\n",gds->gds[3]);
1503     printf("GGG 5          %d\n",gds->gds[4]);
1504     printf("GGG 6          %d\n",gds->gds[5]);
1505     printf("GGG (7-8)      %d\n",gds->ni);
1506     printf("GGG (9-10)     %d\n",gds->nj);
1507     printf("GGG (11-13)    %d\n",INT3(gds->gds[10],gds->gds[11],gds->gds[12]));
1508     printf("GGG (14-16)    %d\n",INT3(gds->gds[13],gds->gds[14],gds->gds[15]));
1509     printf("GGG 17         %d\n",gds->gds[16]);
1510     printf("GGG (18-20)    %d\n",INT3(gds->gds[17],gds->gds[18],gds->gds[19]));
1511     printf("GGG (21-23)    %d\n",INT3(gds->gds[20],gds->gds[21],gds->gds[22]));
1512     if(gds->drt != 220) {
1513       printf("GGG (24-25)    %d\n",INT2(gds->gds[23],gds->gds[24]));
1514       printf("GGG (26-27)    %d\n",INT2(gds->gds[25],gds->gds[26]));
1515       printf("GGG 28         %d\n",gds->gds[27]);
1516     } else {
1517
1518     }
1519   }
1520
1521   return 0;
1522
1523 }
1524
1525 void lats_flt2int(float *dataf, int *datai, int npts) {
1526
1527   float f1;
1528   int i1;
1529   int i;
1530
1531   for(i=0;i<npts;i++) {
1532     i1=*(datai+i);
1533     f1=(float)i1;
1534     *(dataf+i)=f1;
1535   }   
1536
1537 }
Note: See TracBrowser for help on using the browser.