4 #define ICE_TYPE_NSIDC 1
5 #define ICE_TYPE_OISST 2
7 static int ice_initalized = 0;
9 static float ice_threshold = 0;
30 #define NAMING_CONVENTION_REFERENCE \
31 "http://nsidc.org/data/docs/daac/nsidc0051_gsfc_seaice.gd.html#namingconvention"
39 #define EC 0.081816153
40 #define E2 0.006693883
51 static double slat = 0.0, sinslat, tc, mc;
60 static size_t OI4NX = 1440;
61 static size_t OI4NY = 720;
64 static float **iceref;
81 int32 dims[H4_MAX_VAR_DIMS];
85 char name[H4_MAX_NC_NAME];
89 int16 bit = pow(2, mon);
96 sds_index = SDnametoindex(sd_id,
"ice_mask");
97 if (sds_index == -1) {
98 printf(
"-E- %s: Error seeking ice_mask SDS from %s.\n",
104 sds_id = SDselect(sd_id, sds_index);
109 printf(
"-E- %s: Error reading SDS info for ice_mask from %s.\n",
113 if (dims[0] !=
NY || dims[1] !=
NX) {
114 printf(
"-E- %s: Dimension mis-match in ice_mask file %s.\n Expecting %d x %d\n Reading %d x %d\n",
115 __FILE__,
file,
NX,
NY, (
int) dims[1], (
int) dims[0]);
119 for (
j = 0;
j <
NY;
j++) {
129 printf(
"-E- %s: Error reading SDS ice_mask from %s.\n",
135 for (
i = 0;
i <
NX;
i++)
136 ice[
j][
i] = (ice_data[
i] & bit) > 0;
140 status = SDendaccess(sds_id);
142 printf(
"Loaded old ice climatology HDF file.\n");
162 #define COPYNAME(orig,copy){ \
163 (copy) = (char *)strdup( orig ); \
164 if( (copy) == NULL ){ \
165 fprintf(stderr,"-E- %s line %d: Memory allocation error\n", \
166 __FILE__,__LINE__); \
167 exit(EXIT_FAILURE); \
171 #define READIT(file,handle,rows,cols,array){ \
172 if( ( (handle) = fopen((file),"rb")) == NULL ){ \
173 fprintf(stderr,"-E- %s line %d: Could not open file, \"%s\" .\n", \
174 __FILE__,__LINE__,(file)); \
176 exit(EXIT_FAILURE); \
178 if( fseek( (handle) ,300,SEEK_SET) == -1 ){ \
180 "-E- %s line %d: Could not skip header of file, \"%s\" .\n", \
181 __FILE__,__LINE__,(file)); \
183 exit(EXIT_FAILURE); \
186 fread((array), sizeof(unsigned char), (rows)*(cols), handle) \
189 fprintf(stderr,"-E- %s line %d: Error reading file, \"%s\" .\n", \
190 __FILE__,__LINE__,(file)); \
192 exit(EXIT_FAILURE); \
204 char *nfile, *sfile, *
p;
221 p = strrchr(nfile,
'.');
222 if (
p ==
NULL ||
p <= nfile || (*(
p - 1) !=
'n' && *(
p - 1) !=
's')) {
223 printf(
"-E- %s line %d: ", __FILE__, __LINE__);
224 printf(
"File, \"%s\", doesn't follow naming convention described at %s .\n",
230 p = strrchr(sfile,
'.');
242 printf(
"Loaded raw NSIDC ice files.\n");
252 int32 dims[H4_MAX_VAR_DIMS];
256 char name[H4_MAX_NC_NAME];
270 if (SDreadattr(sd_id, SDfindattr(sd_id,
"start_year"), (VOIDP) (&startYear))) {
271 printf(
"-E- %s: Error reading start_year from monthly file %s.\n",
277 if (SDreadattr(sd_id, SDfindattr(sd_id,
"end_year"), (VOIDP) (&endYear))) {
278 printf(
"-E- %s: Error reading end_year from monthly file %s.\n",
286 if (
year < startYear)
293 sprintf(northName,
"ice_%d_%02d_north",
year, month);
294 sprintf(southName,
"ice_%d_%02d_south",
year, month);
301 sds_index = SDnametoindex(sd_id, northName);
302 if (sds_index == -1) {
303 printf(
"-E- %s: Error seeking %s SDS from %s.\n",
304 __FILE__, northName,
file);
309 sds_id = SDselect(sd_id, sds_index);
314 printf(
"-E- %s: Error reading SDS info for %s from %s.\n",
315 __FILE__, northName,
file);
319 printf(
"-E- %s: Dimension mis-match in %s file %s.\n",
320 __FILE__, northName,
file);
322 printf(
" Reading %d x %d\n", (
int) dims[0], (
int) dims[1]);
334 printf(
"-E- %s: Error reading SDS %s from %s.\n",
335 __FILE__, northName,
file);
340 status = SDendaccess(sds_id);
347 sds_index = SDnametoindex(sd_id, southName);
348 if (sds_index == -1) {
349 printf(
"-E- %s: Error seeking %s SDS from %s.\n",
350 __FILE__, southName,
file);
355 sds_id = SDselect(sd_id, sds_index);
360 printf(
"-E- %s: Error reading SDS info for %s from %s.\n",
361 __FILE__, southName,
file);
365 printf(
"-E- %s: Dimension mis-match in %s file %s.\n",
366 __FILE__, southName,
file);
368 printf(
" Reading %d x %d\n", (
int) dims[0], (
int) dims[1]);
380 printf(
"-E- %s: Error reading SDS %s from %s.\n",
381 __FILE__, southName,
file);
386 status = SDendaccess(sds_id);
388 printf(
"Loaded monthly NSIDC ice climatology HDF file.\n");
398 int32 dims[H4_MAX_VAR_DIMS];
402 char name[H4_MAX_NC_NAME];
413 sds_index = SDnametoindex(sd_id,
"north");
414 if (sds_index == -1) {
415 printf(
"-E- %s: Error seeking north SDS from %s.\n", __FILE__,
file);
420 sds_id = SDselect(sd_id, sds_index);
425 printf(
"-E- %s: Error reading SDS info for north from %s.\n",
430 printf(
"-E- %s: Dimension mis-match in north file %s.\n",
433 printf(
" Reading %d x %d\n", (
int) dims[0], (
int) dims[1]);
445 printf(
"-E- %s: Error reading SDS north from %s.\n",
451 status = SDendaccess(sds_id);
458 sds_index = SDnametoindex(sd_id,
"south");
459 if (sds_index == -1) {
460 printf(
"-E- %s: Error seeking south SDS from %s.\n", __FILE__,
file);
465 sds_id = SDselect(sd_id, sds_index);
470 printf(
"-E- %s: Error reading SDS info for south from %s.\n",
475 printf(
"-E- %s: Dimension mis-match in south file %s.\n",
478 printf(
" Reading %d x %d\n", (
int) dims[0], (
int) dims[1]);
490 printf(
"-E- %s: Error reading SDS south from %s.\n",
496 status = SDendaccess(sds_id);
498 printf(
"Loaded near real time NSIDC ice HDF file.\n");
504 double sinlat,
t, rho,
x,
y, ii, jj,
i,
j,
u,
v, d[4], sum,
interp;
505 float delta, xdist, ydist;
506 int sgn, rows, cols, ix, jy, cnt,
n;
510 if (
lat >= 90 ||
lat <= -90) {
539 while (
lon < 0)
lon += 360;
540 while (
lon > 360)
lon -= 360;
548 sinlat = sin((
double)
lat);
564 t = tan((
double) (
PI / 4 -
lat / 2))
565 / pow((
double) ((1 -
EC * sinlat) / (1 +
EC * sinlat)), (
double) (
EC / 2));
581 tc = tan((
double) (
PI / 4 - slat / 2))
582 / pow((
double) ((1 -
EC * sinslat) / (1 +
EC * sinslat)), (
double) (
EC / 2));
587 mc = cos((
double) slat) / sqrt((
double) (1 -
E2 * sinslat * sinslat));
593 rho =
RE * mc *
t / tc;
598 x = rho * sgn * sin((
double) (sgn *
lon));
599 y = -rho * sgn * cos((
double) (sgn *
lon));
602 jj = rows - (
y + ydist -
CELL / 2) / (
CELL);
612 if (ii < 0 || ii > cols || jj < 0 || jj > rows) {
620 d[0] = *(
data + (
int) jj * cols + (
int) ii);
652 for (jy =
j; jy <
j + 2; jy++) {
653 for (ix =
i; ix <
i + 2; ix++) {
654 if (ix >= 0 && ix < cols && jy >= 0 && jy < rows) {
660 d[
n] = *(
data + jy * cols + ix);
680 for (
n = 0;
n < 4;
n++) {
699 return (
float) (
interp / 250.0);
717 char* varName =
"ice";
718 int ncid, ndims, nvars, ngatts, unlimdimid;
726 if (nc_open(icefile, NC_NOWRITE, &ncid) != NC_NOERR) {
730 if (nc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid) != NC_NOERR) {
735 if (nc_inq_attlen(ncid, NC_GLOBAL,
"title", &length) != NC_NOERR) {
739 char titleStr[length + 2];
740 if (nc_get_att_text(ncid, NC_GLOBAL,
"title", titleStr) != NC_NOERR) {
744 titleStr[length] = 0;
746 if (strstr(titleStr,
"Daily-OI") ||
747 strstr(titleStr,
"NOAA/NCEI 1/4 Degree Daily Optimum Interpolation Sea Surface Temperature (OISST) Analysis")) {
748 printf(
"Loading Daily V2 0.25-deg OISST Ice field from %s\n\n", icefile);
749 }
else if (strstr(titleStr,
"CMC")) {
750 varName =
"sea_ice_fraction";
753 nc_inq_dimid(ncid,
"lat", &YdimID);
754 nc_inq_dimlen(ncid, YdimID, &
OI4NY);
755 nc_inq_dimid(ncid,
"lon", &XdimID);
756 nc_inq_dimlen(ncid, XdimID, &
OI4NX);
757 printf(
"Loading Daily CMC Ice field from %s\n\n", icefile);
763 if (nc_inq_varid(ncid, varName, &varid) != NC_NOERR) {
769 static short **icetmp;
779 if (nc_get_var_short(ncid, varid, &icetmp[0][0]) != NC_NOERR) {
780 fprintf(
stderr,
"-E- %s line %d: Error reading %s from %s.\n",
781 __FILE__, __LINE__, varName, icefile);
785 if (nc_get_att_float(ncid, varid,
"scale_factor", &
slope) != NC_NOERR) {
786 fprintf(
stderr,
"-E- %s line %d: error reading scale factor.\n",
791 if (nc_get_att_float(ncid, varid,
"add_offset", &
offset) != NC_NOERR) {
792 fprintf(
stderr,
"-E- %s line %d: error reading scale offset.\n",
807 if (icetmp[
j][
i] > -999)
812 iceref[
j + 1][0] = iceref[
j + 1][
OI4NX];
813 iceref[
j + 1][
OI4NX + 1] = iceref[
j + 1][1];
816 iceref[0][
i] = iceref[1][
i];
825 float dx = 360.0 /
OI4NX;
826 float dy = 180.0 /
OI4NY;
842 xx =
i * dx - 180.0 - dx / 2;
843 yy =
j * dy - 90.0 - dy / 2;
852 ftmp += iceref[
j ][
i ];
856 ftmp += iceref[
j ][
i + 1];
859 if (iceref[
j + 1][
i + 1] >
BAD_FLT + 1) {
860 ftmp += iceref[
j + 1][
i + 1];
864 ftmp += iceref[
j + 1][
i ];
869 reftmp[0][0] = (iceref[
j ][
i ] >
BAD_FLT + 1 ? iceref[
j ][
i ] : ftmp);
870 reftmp[0][1] = (iceref[
j ][
i + 1] >
BAD_FLT + 1 ? iceref[
j ][
i + 1] : ftmp);
871 reftmp[1][1] = (iceref[
j + 1][
i + 1] >
BAD_FLT + 1 ? iceref[
j + 1][
i + 1] : ftmp);
872 reftmp[1][0] = (iceref[
j + 1][
i ] >
BAD_FLT + 1 ? iceref[
j + 1][
i ] : ftmp);
874 ice = (1 -
t)*(1 -
u) * reftmp[0][0] +
t * (1 -
u) * reftmp[0][1] +
t *
u * reftmp[1][1] + (1 -
t) *
u * reftmp[1][0];
905 char titleStr[256] =
"";
911 ice_threshold = threshold;
915 sd_id = SDstart(
file, DFACC_RDONLY);
917 fprintf(
stderr,
"-E- %s line %d: Could not open %s as an HDF file.\n",
918 __FILE__, __LINE__,
file);
922 attr_index = SDfindattr(sd_id,
"Title");
923 if (attr_index == -1) {
936 status = SDreadattr(sd_id, attr_index, titleStr);
938 fprintf(
stderr,
"-E- %s line %d: Could not read the global attribute \"Title\" from, %s .\n",
939 __FILE__, __LINE__,
file);
945 if (strcmp(titleStr,
"Sea Ice Concentration Daily") == 0) {
948 }
else if (strcmp(titleStr,
"Sea Ice Concentration Monthly") == 0) {
952 fprintf(
stderr,
"-E- %s line %d: Global attribute \"Title\" not valid from, %s .\n",
953 __FILE__, __LINE__,
file);
965 if (nc_open(
file, NC_NOWRITE, &ncid) == NC_NOERR) {
997 switch (ice_file_type) {
1005 fprintf(
stderr,
"-E- %s line %d: Ice file type=%d is invalid.\n",
1006 __FILE__, __LINE__, ice_file_type);
1019 if (!ice_initalized)
1022 switch (ice_file_type) {
1030 fprintf(
stderr,
"-E- %s line %d: Ice file type=%d is invalid.\n",
1031 __FILE__, __LINE__, ice_file_type);