OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
get_zno3.c
Go to the documentation of this file.
1 #include "l12_proto.h"
2 #include <sys/types.h>
3 #include <unistd.h>
4 #include <nc_gridutils.h>
5 
6 // module getz.c -retrieve mixed layer depth from World Ocean Atlas Climatology
7 
8 static float zbad = BAD_FLT;
9 
10 #define ZXANC 360
11 #define ZYANC 180
12 #define MINY 12
13 /* This program opens the netcdf/hdf zno3_climatology_woa1994 file located in ocssw//run/data/common. It extracts the mixed layer depth information from the hdf file. */
14 
15 /* :Title = "WOA Nitrocline Depth Monthly Climatology"
16  :Description = "World Ocean Atlas 1994, Mixed Layer Depth, Monthly"
17  :Reference = "http://www.nodc.noaa.gov/OC5/WOA94/mix.html"
18  */
19 
20 float get_zno3(float lon, float lat, int day) {
21  static int firstCall = 1;
22  static int zx = ZXANC;
23  static int zy = ZYANC;
24  static float dx = 360.0 / ZXANC;
25  static float dy = 180.0 / ZYANC;
26 
27  typedef float ref_t[ZXANC + 2];
28  static ref_t* zref;
29  static ref_t* z_sav;
30 
31  float zno3 = zbad;
32  int i, j, jj;
33  int status;
34  float xx, yy;
35  float t, u;
36 
37  if (firstCall) {
38  float ztmp[12][ZXANC][ZYANC];
39 
40  char sdsname[H4_MAX_NC_NAME];
41  char sdsname2[H4_MAX_NC_NAME];
42  int ncid, ndims, nvars, ngatts, unlimdimid;
43  int32 sds_id;
44  nc_type rh_type; /* variable type */
45  int rh_dimids[H4_MAX_VAR_DIMS]; /* dimension IDs */
46  int rh_natts; /* number of attributes */
47  int rh_ndims; /* number of dims */
48  int32 ix, iy, ct;
49  int32 lymin, lxmin, lymax, lxmax;
50  float sum;
51 
52  char *OCSSW_root, zclimatology_file[300];
53 
54  firstCall = 0;
55 
56  // allocate data
57  zref = (ref_t*) allocateMemory((ZYANC + 2) * sizeof (ref_t), "zref");
58  z_sav = (ref_t*) allocateMemory((ZYANC + 2) * sizeof (ref_t), "z_sav");
59 
60  if ((OCSSW_root = getenv("OCDATAROOT")) == NULL) {
61  printf(
62  "-E- %s: Error looking up environmental variable OCDATAROOT\n",
63  __FILE__);
64  exit(1);
65  }
66  strcpy(zclimatology_file, OCSSW_root);
67  strcat(zclimatology_file, "/common/zno3_climatology_woa2005.nc");
68 
69  printf("\nOpening z climatology file %s\n\n", zclimatology_file);
70 
71  /* calculate the correct date and day of the month using yd2md utility. */
72 
73  int16 mon = (int) day / 31; // month of year (no need for perfection..at least according to the sea surface salinity reference algorithm)
74 
75  /* Open the file */
76  strcpy(sdsname, "zno3");
77 
78  /* try netCDF first */
79  if (nc_open(zclimatology_file, NC_NOWRITE, &ncid) == NC_NOERR) {
80 
81  status = nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid);
82  if (status != NC_NOERR) {
83  fprintf(stderr, "-E- %s line %d: Error reading %s from %s.\n",
84  __FILE__, __LINE__, sdsname, zclimatology_file);
85  handle_nc_error(status, __FILE__, __LINE__);
86  }
87 
88  status = nc_inq_varid(ncid, sdsname, &sds_id);
89  if (status != NC_NOERR) {
90  fprintf(stderr, "-E- %s line %d: Error reading %s from %s.\n",
91  __FILE__, __LINE__, sdsname, zclimatology_file);
92  handle_nc_error(status, __FILE__, __LINE__);
93  }
94  nc_inq_varname(ncid, sds_id, sdsname2);
95  status = nc_inq_var(ncid, sds_id, 0, &rh_type, &rh_ndims, rh_dimids,
96  &rh_natts);
97 
98  //printf("rh_ndims=%d rh_dimids=%d %d %d \n",rh_ndims,rh_dimids[0],rh_dimids[1],rh_dimids[2]);
99 
100  printf("\nReading z climatology file %s ndims=%d nvars=%d sds_id=%d var=%s\n\n", zclimatology_file, ndims, nvars, sds_id, sdsname2);
101  /* Read the data. */
102  if (nc_get_var(ncid, sds_id, &ztmp[0][0][0]) != NC_NOERR) {
103  fprintf(stderr, "-E- %s line %d: Error reading %s from %s.\n",
104  __FILE__, __LINE__, sdsname, zclimatology_file);
105  exit(1);
106  }
107  printf("\nClosing z climatology file %s\n\n", zclimatology_file);
108 
109  /* Close the file */
110  if (nc_close(ncid) != NC_NOERR) {
111  fprintf(stderr, "-E- %s line %d: error closing %s.\n",
112  __FILE__, __LINE__, zclimatology_file);
113  exit(1);
114  }
115  } else {
116  fprintf(stderr, "-E- %s line %d: error opening %s.\n",
117  __FILE__, __LINE__, zclimatology_file);
118  exit(1);
119  }
120  /* rotate 180-deg and add wrapping border to simplify interpolation */
121  /* new grid is -180.5,180.5 in i=0,361 and -90.5,90.5 in j=0,181 */
122 
123 
124  jj = zy - 1;
125  for (j = 0; j < zy; j++) {
126  for (i = 0; i < zx; i++) {
127  //ii = (i < zx / 2) ? i + zx / 2 : i - zx / 2;
128  if (ztmp[mon][i][j] >= 0) {
129  zref[jj + 1][i + 1] = ztmp[mon][i][j];
130  } else
131  zref[jj + 1][i + 1] = zbad;
132  // printf("ZREF[%d][%d]=%f\n",jj+1,i,zref[jj+1][i]);
133  }
134  zref[jj + 1][0] = zref[jj + 1][zx];
135  zref[jj + 1][zx + 1] = zref[jj + 1][1];
136  jj--;
137  }
138  for (i = 0; i < zx + 2; i++) {
139  zref[0][i] = zref[1][i];
140  zref[zy + 1][i] = zref[zy][i];
141  }
142 
143  /*
144  * Extend the grid by 1 point (use only full grid boxes later)
145  */
146 
147 
148 
149  memcpy(z_sav, zref,
150  (ZYANC + 2) * (ZXANC + 2) * sizeof (float));
151  for (iy = 0; iy < zy + 2; iy++) {
152  lymin = (iy == 0) ? 0 : iy - 1;
153  lymax = (iy == zy + 1) ? zy + 1 : iy + 1;
154 
155  for (ix = 0; ix < zx + 2; ix++) {
156  if (zref[iy][ix] < zbad + 1) {
157  lxmin = (ix == 0) ? 0 : ix - 1;
158  lxmax = (ix == zx + 1) ? zx + 1 : ix + 1;
159 
160  sum = 0.;
161  ct = 0;
162  for (j = lymin; j < lymax + 1; j++)
163  for (i = lxmin; i < lxmax + 1; i++) {
164  if (z_sav[j][i] > zbad + 1) {
165  sum += z_sav[j][i];
166  ct++;
167  }
168  }
169  if (ct > 0)
170  zref[iy][ix] = sum / ct;
171  }
172  //printf("zref[%d][%d]=%f monidx=%d\n",iy,ix,zref[iy][ix],mon);
173 
174  }
175  }
176 
177  } /* end 1-time grid set up */
178 
179 
180  /* locate LL position within reference grid */
181  i = MAX(MIN((int) ((lon + 180.0 + dx / 2) / dx), ZXANC + 1), 0);
182  j = MAX(MIN((int) ((lat + 90.0 + dy / 2) / dy), ZYANC + 1), 0);
183 
184  /*
185  //printf("i=%d j=%d %f \n",i,j,zref[j][i]);
186  zno3 = zref[j][i];
187 
188  return (zno3);
189  */
190 
191  /* compute longitude and latitude of that grid element */
192  xx = i * dx - 180.0 - dx / 2;
193  yy = j * dy - 90.0 - dy / 2;
194 
195  /* Bilinearly interpolate, only using full grid boxes */
196  t = (lon - xx) / dx;
197  u = (lat - yy) / dy;
198 
199  if ((zref[j][i] > zbad + 1) && (zref[j][i + 1] > zbad + 1)
200  && (zref[j + 1][i] > zbad + 1)
201  && (zref[j + 1][i + 1] > zbad + 1)) {
202 
203  zno3 = (1 - t) * (1 - u) * zref[j][i] + t * (1 - u) * zref[j][i + 1]
204  + t * u * zref[j + 1][i + 1] + (1 - t) * u * zref[j + 1][i];
205 
206  } else
207  zno3 = zbad;
208 
209  return (zno3);
210 }
211 
#define MAX(A, B)
Definition: swl0_utils.h:26
integer, parameter int16
Definition: cubeio.f90:3
#define MIN(x, y)
Definition: rice.h:169
data_t t[NROOTS+1]
Definition: decode_rs.h:77
int j
Definition: decode_rs.h:73
int32_t day
int status
Definition: l1_czcs_hdf.c:32
void * allocateMemory(size_t numBytes, const char *name)
Definition: allocateMemory.c:7
#define NULL
Definition: decode_rs.h:63
float * lat
void handle_nc_error(int status, char *file, int line)
Definition: nc_gridutils.c:21
#define BAD_FLT
Definition: jplaeriallib.h:19
data_t u
Definition: decode_rs.h:74
#define ZXANC
Definition: get_zno3.c:10
float * lon
float get_zno3(float lon, float lat, int day)
Definition: get_zno3.c:20
#define ZYANC
Definition: get_zno3.c:11
int i
Definition: decode_rs.h:71
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")