root/cdat/trunk/lats/latsgrib.c

Revision 28, 36.7 kB (checked in by drach, 11 years ago)

Initial revision

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