1 #ifndef GRADSDES_H
2 #define GRADSDES_H
3 
4 #define gaint int
5 #define gadouble double
6 #define gafloat float
7 #define galloc(x, y) malloc(x)
8 #define gree(x, y) free(x)
9 #define gaprnt(i, ch) printf("%s", ch)
10 
11 /* Handling of missing data values. After the data I/O is done,
12    grid values are tested to see if they are within a small range
13    (+-value/EPSILON) of the missing value. If true, then the undef
14    mask is set to 0. If false, then the grid data values are good,
15    and the undef mask is set to 1. Everywhere else in the code,
16    undef tests are done on the mask values, not the data. */
17 
18 #define EPSILON 1e5
19 
20 #include <stdio.h>
21 
22 /* Date/time structure */
23 struct dt
24 {
25   gaint yr;
26   gaint mo;
27   gaint dy;
28   gaint hr;
29   gaint mn;
30 };
31 
32 /* Structure that describes a variable in a file.  These structures
33    are built in arrays that are hung off of gafile structures.         */
34 struct gavar
35 {
36   char varnm[128];      /* Variable description.                */
37   char abbrv[16];       /* Variable abbreviation.               */
38   char longnm[257];     /* netcdf/hdf var name if different     */
39   gadouble units[16];   /* Units indicator.
40                            Vals 0-7 are for variable codes:
41                            grib, non-float data, nc/hdf dims
42                            Vals  8-11 are for grib level codes  */
43   gaint offset;         /* Offset in grid elements of the start
44                            of this variable within a time group
45                            within this file.                    */
46   gaint recoff;         /* Record (XY grid) offset of the start
47                            of this variable within a time group */
48   gaint ncvid;          /* netcdf vid for this variable         */
49   gaint sdvid;          /* hdf vid for this variable            */
50   gaint levels;         /* Number of levels for this variable.
51                            0 is special and indiates one grid is
52                            available for the surface only.      */
53   gaint dfrm;           /* format  type indicator
54                            1 - unsigned char
55                            4 - int                              */
56   gaint var_t;          /* variable t transform                 */
57   gadouble scale;       /* scale factor for unpacking data      */
58   gadouble add;         /* offset value for unpacking data      */
59   gadouble undef;       /* undefined value                      */
60   gaint vecpair;        /* Variable has a vector pair           */
61   gaint isu;            /* Variable is the u-component of a vector pair */
62   gaint isdvar;         /* Variable is a valid data variable (for SDF files) */
63   gaint nvardims;       /* Number of variable dimensions        */
64   gaint vardimids[100]; /* Variable dimension IDs.                */
65 };
66 
67 /* Sructure for string substitution in templating -- the %ch template.
68    This forms a linked list chained from pchsub1 in gafile */
69 struct gachsub
70 {
71   struct gachsub *forw; /* Forward pointer */
72   gaint t1;             /* First time for this substitution */
73   gaint t2;             /* Last time.  -99 indicates open ended */
74   char *ch;             /* Substitution string */
75 };
76 
77 /* Structure for ensemble metadata */
78 struct gaens
79 {
80   char name[16];    /* name of ensemble */
81   gaint length;     /* length of time axis */
82   struct dt tinit;  /* initial time */
83   gaint gt;         /* initial time in grid units */
84   gaint grbcode[4]; /* grib2 codes */
85 };
86 
87 #define MAX_RECLEN 512
88 #define MAX_NAMELEN 512
89 typedef struct
90 {
91   char name[MAX_NAMELEN];
92   char dnam[MAX_NAMELEN];
93   char title[MAX_NAMELEN];
94   int bswap;
95   long gsiz;   /* Number of elements in a grid (x*y)    */
96                /* This is for actual grid on disk,
97                   not psuedo grid (when pp in force) */
98   long tsiz;   /* Number of elements in an entire time
99                   group (all variables at all levels
100                   for one time).                        */
101   gaint trecs; /* Number of records (XY grids) per time
102                   group.                                */
103   long fhdr;
104   struct gachsub *pchsub1; /* Pointer to first %ch substitution */
105   gaint ncflg;             /* 1==netcdf  2==hdfsds */
106   long xyhdr;
107   int seqflg;
108   int yrflg;
109   int zrflg;
110   int pa2mb;
111   int calendar;
112   /* init !? */
113   FILE *infile;        /* File pointer.                         */
114   gaint type;          /* Type of file:  1 = grid
115                                          2 = simple station
116                                          3 = mapped station
117                                          4 = defined grid       */
118   gadouble undef;      /* Global undefined value for this file  */
119   gadouble ulow, uhi;  /* Undefined limits for missing data test  */
120   gaint dnum[5];       /* Dimension sizes for this file.        */
121   gaint vnum;          /* Number of variables.                  */
122   struct gavar *pvar1; /* Pointer to an array of structures.
123                           Each structure in the array has info
124                           about the specific variable.          */
125   struct gaens *ens1;  /* pointer to array of ensemble structures */
126   gaint wrap;          /* The grid globally 'wraps' in X        */
127   gadouble (*gr2ab[5])(double *, double);
128   /* Addresses of routines to do conversion
129      from grid coordinates to absolute
130      coordinates for X, Y, Z.  All Date/time
131      conversions handled by gr2t.          */
132   gadouble (*ab2gr[5])(double *, double);
133   /* Addresses of routines to do conversion
134      from absolute coordinates to grid
135      coordinates for X,Y,Z.  All date/time
136      conversions handled by t2gr.          */
137   gadouble *grvals[5]; /* Pointers to conversion information for
138                           grid-to-absolute conversion routines. */
139   gadouble *abvals[5]; /* Pointers to conversion information for
140                           absolute-to-grid conversion routines. */
141   gaint linear[5];     /* Indicates if a dimension has a linear
142                           grid/absolute coord transformation
143                           (Time coordinate always linear).      */
144   gaint idxflg;        /* File records are indexed; 1==grib,station 2==grib2 */
145   gaint flt64;         /* 20120711 Uwe Schulzweida: added support for 64 bit floats */
146   gaint tmplat;        /* File name templating:
147                            3==templating on E and T
148                            2==templating only on E
149                            1==templating only on T, or when
150                               ddf has 'options template', but no % in dset
151                            0==no templating  */
152   gaint *fnums;        /* File number for each time */
153   gaint fnumc;         /* Current file number that is open */
154   gaint fnume;         /* Current ensemble file number that is open */
155 } dsets_t;
156 
157 void dsets_init(dsets_t *dsets);
158 
159 int read_gradsdes(char *filename, dsets_t *pfi);
160 
161 gadouble liconv(gadouble *, gadouble);
162 gadouble gr2lev(gadouble *, gadouble);
163 gadouble lev2gr(gadouble *, gadouble);
164 void gr2t(gadouble *, gadouble, struct dt *);
165 char *gafndt(char *, struct dt *, struct dt *, gadouble *, struct gachsub *, struct gaens *, gaint, gaint, gaint *);
166 
167 gaint cmpwrd(const char *ch1, const char *ch2);
168 char *intprs(char *ch, int *val);
169 void gabswp(void *r, gaint cnt);
170 void gabswp2(void *r, gaint cnt);
171 
172 #endif /* GRADSDES_H */
173