ocssw  1.0
/disk01/web/ocssw/build/src/l2gen/ice_mask.c (r8096/r5616)
Go to the documentation of this file.
00001 #include "l12_proto.h"
00002 
00003 static int ice_initalized = 0;
00004 static int using_nsidc = 0;
00005 static float ice_threshold = 0;
00006 
00007 /***********************************************
00008  *
00009  * global variabls for the old ice mask
00010  *
00011  ***********************************************/
00012 
00013 #define NX 4096
00014 #define NY 2048
00015 
00016 static char ice[NY][NX];
00017 
00018 
00019 /***********************************************
00020  *
00021  * global variabls for NSIDC ice data
00022  *
00023  ***********************************************/
00024 
00025 #define NAMING_CONVENTION_REFERENCE \
00026 "http://nsidc.org/data/docs/daac/nsidc0051_gsfc_seaice.gd.html#namingconvention"
00027 
00028 #define NROWS   448
00029 #define NCOLS   304
00030 #define SROWS   332
00031 #define SCOLS   316
00032 
00033 #define RE  6378.273    /* Earth's equatorial radius */
00034 #define EC  0.081816153 /* Eccentricity */
00035 #define E2  0.006693883 /* Eccentricity squared */
00036 #define SLAT    70.0        /* Standard latitude */
00037 #define CELL    25.0        /* Stereographic pixel dimension (km) */
00038 #define NODATA  -1.0
00039 
00040 static unsigned char    north[NROWS][NCOLS], south[SROWS][SCOLS];
00041 static double       slat=0.0, sinslat, tc, mc;
00042 
00043 
00044 
00045 int ice_mask_init_old(char *file, int day, int32 sd_id)
00046 {
00047    int32 sds_id; 
00048    int32 status;
00049    int32 sds_index;
00050    int32 rank; 
00051    int32 nt; 
00052    int32 dims[H4_MAX_VAR_DIMS]; 
00053    int32 nattrs;
00054    int32 start[2]; 
00055    int32 edges[2];
00056    char  name[H4_MAX_NC_NAME];
00057 
00058    int16 ice_data[NX];
00059    int16 mon = (int) day/31;   /* month of year (no need for perfection) */
00060    int16 bit = pow(2,mon);     /* bit mask associated with this month    */
00061    int16 i, j;
00062 
00063 
00064    /* Get the SDS index */
00065    sds_index = SDnametoindex(sd_id,"ice_mask");
00066    if (sds_index == -1) {
00067        printf("-E- %s:  Error seeking ice_mask SDS from %s.\n",
00068                __FILE__, file);
00069        return(1);
00070    }
00071 
00072    /* Select the SDS */
00073    sds_id = SDselect(sd_id, sds_index);
00074 
00075    /* Verify the characteristics of the array */
00076    status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
00077    if (status != 0) {
00078        printf("-E- %s:  Error reading SDS info for ice_mask from %s.\n",
00079            __FILE__,file);
00080        return(1);
00081    }
00082    if (dims[0] != NY || dims[1] != NX) {
00083        printf("-E- %s:  Dimension mis-match in ice_mask file %s.\n  Expecting %d x %d\n  Reading   %d x %d\n",
00084               __FILE__,file,NX,NY,(int)dims[1],(int)dims[0]);
00085        return(1);
00086    }
00087 
00088    for (j=0; j<NY; j++) {
00089 
00090        /* Read one row from the array     */
00091        start[0] = j;        /* row offset */
00092        start[1] = 0;        /* col offset */
00093        edges[0] = 1;        /* row count  */
00094        edges[1] = dims[1];  /* col count  */
00095 
00096        status = SDreaddata(sds_id, start, NULL, edges, (VOIDP) ice_data);
00097        if (status != 0) {
00098            printf("-E- %s:  Error reading SDS ice_mask from %s.\n",
00099                   __FILE__,file);
00100            return(1);
00101        }
00102 
00103        /* Set byte array for if monthly bit set in ice data */
00104        for (i=0; i<NX; i++)
00105            ice[j][i] = (ice_data[i] & bit) > 0;
00106    }
00107 
00108    /* Terminate access to the array */
00109    status = SDendaccess(sds_id);
00110 
00111    printf("Loaded old ice climatology HDF file.\n");
00112    return(0);
00113 }
00114 
00115 
00116 char ice_mask_old(float lon, float lat)
00117 {
00118     int16 i, j;
00119     
00120     i = MAX(MIN((int16) ((lon+180.0)/360.0 * NX),NX-1),0);
00121     j = MAX(MIN((int16) (( 90.0-lat)/180.0 * NY),NY-1),0);
00122     return(ice[j][i]);
00123 }
00124 
00125 
00126 float get_icefrac_old(float lon, float lat)
00127 {
00128     if(ice_mask_old(lon, lat))
00129         return 1.0;
00130     
00131     return 0.0;
00132 }
00133        
00134 
00135 #define COPYNAME(orig,copy){                    \
00136 (copy) = (char *)strdup( orig );                \
00137 if( (copy) == NULL ){                       \
00138   fprintf(stderr,"-E- %s line %d: Memory allocation error\n",   \
00139   __FILE__,__LINE__);                       \
00140   exit(EXIT_FAILURE);                       \
00141 }                               \
00142 }
00143 
00144 #define READIT(file,handle,rows,cols,array){                \
00145 if( ( (handle) = fopen((file),"rb")) == NULL ){             \
00146   fprintf(stderr,"-E- %s line %d: Could not open file, \"%s\" .\n", \
00147   __FILE__,__LINE__,(file));                        \
00148   perror("");                               \
00149   exit(EXIT_FAILURE);                           \
00150 }                                   \
00151 if( fseek( (handle) ,300,SEEK_SET) == -1 ){             \
00152   fprintf(stderr,                           \
00153   "-E- %s line %d: Could not skip header of file, \"%s\" .\n",      \
00154   __FILE__,__LINE__,(file));                        \
00155   perror("");                               \
00156   exit(EXIT_FAILURE);                           \
00157 }                                   \
00158 if(                                 \
00159 fread((array), sizeof(unsigned char), (rows)*(cols), handle)        \
00160 != (rows)*(cols)                            \
00161 ){                                  \
00162   fprintf(stderr,"-E- %s line %d: Error reading file, \"%s\" .\n",  \
00163   __FILE__,__LINE__,(file));                        \
00164   perror("");                               \
00165   exit(EXIT_FAILURE);                           \
00166 }                                   \
00167 }
00168 
00169 
00170 int ice_mask_init_nsidc_raw(char *file)
00171 {
00172 
00173     /*
00174       Read ice data from the north and south pole files the first time
00175       this function is called and whenever the icefile name changes.
00176       Subsequent calls just refer to ice values stored in static arrays.
00177     */
00178     
00179     char    *nfile, *sfile, *p;
00180     FILE    *fh;
00181     
00182     COPYNAME(file,nfile);
00183     COPYNAME(file,sfile);
00184 
00185     /*
00186       According to the file naming convention, the filename for the
00187       north polar file has an 'n' immediately befor the last '.' in
00188       the name; the south polar file has an 's' in the same position
00189       with all other characters being the same.  Both files are expected
00190       to be present in the same directory.
00191     */
00192     p = strrchr(nfile,'.');
00193     if(p == NULL || p <= nfile || (*(p-1) != 'n' && *(p-1) != 's')){
00194         printf("-E- %s line %d: ", __FILE__,__LINE__);
00195         printf("File, \"%s\", doesn't follow naming convention described at %s .\n",
00196                 file,NAMING_CONVENTION_REFERENCE);
00197         return 1;
00198     }
00199     --p;
00200     *p = 'n';
00201     p = strrchr(sfile,'.');
00202     --p;
00203     *p = 's';
00204     
00205     READIT(nfile,fh,NROWS,NCOLS,north);
00206     fclose(fh);
00207     free(nfile);
00208     
00209     READIT(sfile,fh,SROWS,SCOLS,south);
00210     fclose(fh);
00211     free(sfile);
00212     
00213     printf("Loaded raw NSIDC ice files.\n");
00214     return 0;
00215 }
00216 
00217 
00218 int ice_mask_init_monthly(char *file, int year, int day, int32 sd_id)
00219 {
00220     int32 sds_id; 
00221     int32 status;
00222     int32 sds_index;
00223     int32 rank; 
00224     int32 nt; 
00225     int32 dims[H4_MAX_VAR_DIMS]; 
00226     int32 nattrs;
00227     int32 start[2]; 
00228     int32 edges[2];
00229     char  name[H4_MAX_NC_NAME];
00230     int32 startYear;
00231     int32 endYear;
00232     
00233     int16 month, dom;
00234 
00235     char northName[32];
00236     char southName[32];
00237 
00238     
00239     /* Find the file attribute named "start_year". */
00240     if(SDreadattr(sd_id, SDfindattr(sd_id, "start_year"),(VOIDP)(&startYear))) {
00241         printf("-E- %s:  Error reading start_year from monthly file %s.\n",
00242                __FILE__, file);
00243         return 1;
00244     }
00245 
00246     /* Find the file attribute named "end_year". */
00247     if(SDreadattr(sd_id, SDfindattr(sd_id, "end_year"),(VOIDP)(&endYear))) {
00248         printf("-E- %s:  Error reading end_year from monthly file %s.\n",
00249                __FILE__, file);
00250         return 1;
00251     }
00252 
00253     // if the requested year is not in the monthly file
00254     // use the closest year avaliable
00255 
00256     if(year < startYear) 
00257         year = startYear;
00258     if(year > endYear)
00259         year = endYear;
00260 
00261     // create the data set name for the monthly data
00262     yd2md(year, day, &month, &dom);
00263     sprintf(northName, "ice_%d_%02d_north", year, month);
00264     sprintf(southName, "ice_%d_%02d_south", year, month);
00265 
00266     //
00267     // read north array
00268     //
00269 
00270     /* Get the SDS index */
00271     sds_index = SDnametoindex(sd_id, northName);
00272     if (sds_index == -1) {
00273         printf("-E- %s:  Error seeking %s SDS from %s.\n",
00274                __FILE__, northName, file);
00275         return(1);
00276     }
00277 
00278     /* Select the SDS */
00279     sds_id = SDselect(sd_id, sds_index);
00280 
00281     /* Verify the characteristics of the array */
00282     status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
00283     if (status != 0) {
00284         printf("-E- %s:  Error reading SDS info for %s from %s.\n",
00285                __FILE__, northName, file);
00286         return(1);
00287     }
00288     if (dims[0] != NROWS || dims[1] != NCOLS) {
00289         printf("-E- %s:  Dimension mis-match in %s file %s.\n",
00290                __FILE__, northName, file);
00291         printf("  Expecting %d x %d\n",NROWS,NCOLS);
00292         printf("  Reading   %d x %d\n",(int)dims[0],(int)dims[1]);
00293         return(1);
00294     }
00295 
00296     // read the north array
00297     start[0] = 0;        /* row offset */
00298     start[1] = 0;        /* col offset */
00299     edges[0] = dims[0];  /* row count  */
00300     edges[1] = dims[1];  /* col count  */
00301 
00302     status = SDreaddata(sds_id, start, NULL, edges, (VOIDP) north);
00303     if (status != 0) {
00304         printf("-E- %s:  Error reading SDS %s from %s.\n",
00305                __FILE__, northName, file);
00306         return(1);
00307     }
00308 
00309     /* Terminate access to the north array */
00310     status = SDendaccess(sds_id);
00311     
00312     //
00313     // read south array
00314     //
00315 
00316     /* Get the SDS index */
00317     sds_index = SDnametoindex(sd_id, southName);
00318     if (sds_index == -1) {
00319         printf("-E- %s:  Error seeking %s SDS from %s.\n",
00320                __FILE__, southName, file);
00321         return(1);
00322     }
00323 
00324     /* Select the SDS */
00325     sds_id = SDselect(sd_id, sds_index);
00326 
00327     /* Verify the characteristics of the array */
00328     status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
00329     if (status != 0) {
00330         printf("-E- %s:  Error reading SDS info for %s from %s.\n",
00331                __FILE__, southName, file);
00332         return(1);
00333     }
00334     if (dims[0] != SROWS || dims[1] != SCOLS) {
00335         printf("-E- %s:  Dimension mis-match in %s file %s.\n",
00336                __FILE__, southName, file);
00337         printf("  Expecting %d x %d\n",SROWS,SCOLS);
00338         printf("  Reading   %d x %d\n",(int)dims[0],(int)dims[1]);
00339         return(1);
00340     }
00341 
00342     // read the south array
00343     start[0] = 0;        /* row offset */
00344     start[1] = 0;        /* col offset */
00345     edges[0] = dims[0];  /* row count  */
00346     edges[1] = dims[1];  /* col count  */
00347 
00348     status = SDreaddata(sds_id, start, NULL, edges, (VOIDP) south);
00349     if (status != 0) {
00350         printf("-E- %s:  Error reading SDS %s from %s.\n",
00351                __FILE__, southName, file);
00352         return(1);
00353     }
00354 
00355     /* Terminate access to the south array */
00356     status = SDendaccess(sds_id);
00357     
00358     printf("Loaded monthly NSIDC ice climatology HDF file.\n");
00359     return 0;
00360 }
00361 
00362 
00363 int ice_mask_init_daily(char *file, int year, int day, int32 sd_id)
00364 {
00365     int32 sds_id; 
00366     int32 status;
00367     int32 sds_index;
00368     int32 rank; 
00369     int32 nt; 
00370     int32 dims[H4_MAX_VAR_DIMS]; 
00371     int32 nattrs;
00372     int32 start[2]; 
00373     int32 edges[2];
00374     char  name[H4_MAX_NC_NAME];
00375     
00376     
00377     //
00378     // read north array
00379     //
00380 
00381     /* Get the SDS index */
00382     sds_index = SDnametoindex(sd_id, "north");
00383     if (sds_index == -1) {
00384         printf("-E- %s:  Error seeking north SDS from %s.\n", __FILE__, file);
00385         return(1);
00386     }
00387 
00388     /* Select the SDS */
00389     sds_id = SDselect(sd_id, sds_index);
00390 
00391     /* Verify the characteristics of the array */
00392     status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
00393     if (status != 0) {
00394         printf("-E- %s:  Error reading SDS info for north from %s.\n",
00395                __FILE__, file);
00396         return(1);
00397     }
00398     if (dims[0] != NROWS || dims[1] != NCOLS) {
00399         printf("-E- %s:  Dimension mis-match in north file %s.\n",
00400                __FILE__, file);
00401         printf("  Expecting %d x %d\n",NROWS,NCOLS);
00402         printf("  Reading   %d x %d\n",(int)dims[0],(int)dims[1]);
00403         return(1);
00404     }
00405     
00406     // read the north array
00407     start[0] = 0;        /* row offset */
00408     start[1] = 0;        /* col offset */
00409     edges[0] = dims[0];  /* row count  */
00410     edges[1] = dims[1];  /* col count  */
00411 
00412     status = SDreaddata(sds_id, start, NULL, edges, (VOIDP) north);
00413     if (status != 0) {
00414         printf("-E- %s:  Error reading SDS north from %s.\n",
00415                __FILE__, file);
00416         return(1);
00417     }
00418 
00419     /* Terminate access to the north array */
00420     status = SDendaccess(sds_id);
00421     
00422     //
00423     // read south array
00424     //
00425 
00426     /* Get the SDS index */
00427     sds_index = SDnametoindex(sd_id, "south");
00428     if (sds_index == -1) {
00429         printf("-E- %s:  Error seeking south SDS from %s.\n", __FILE__, file);
00430         return(1);
00431     }
00432 
00433     /* Select the SDS */
00434     sds_id = SDselect(sd_id, sds_index);
00435 
00436     /* Verify the characteristics of the array */
00437     status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
00438     if (status != 0) {
00439         printf("-E- %s:  Error reading SDS info for south from %s.\n",
00440                __FILE__, file);
00441         return(1);
00442     }
00443     if (dims[0] != SROWS || dims[1] != SCOLS) {
00444         printf("-E- %s:  Dimension mis-match in south file %s.\n",
00445                __FILE__, file);
00446         printf("  Expecting %d x %d\n",SROWS,SCOLS);
00447         printf("  Reading   %d x %d\n",(int)dims[0],(int)dims[1]);
00448         return(1);
00449     }
00450 
00451     // read the south array
00452     start[0] = 0;        /* row offset */
00453     start[1] = 0;        /* col offset */
00454     edges[0] = dims[0];  /* row count  */
00455     edges[1] = dims[1];  /* col count  */
00456 
00457     status = SDreaddata(sds_id, start, NULL, edges, (VOIDP) south);
00458     if (status != 0) {
00459         printf("-E- %s:  Error reading SDS south from %s.\n",
00460                __FILE__, file);
00461         return(1);
00462     }
00463 
00464     /* Terminate access to the south array */
00465     status = SDendaccess(sds_id);
00466 
00467     printf("Loaded near real time NSIDC ice HDF file.\n");
00468     return 0;
00469 }
00470 
00471 
00472 float get_icefrac_nsidc(float lon, float lat){
00473 
00474   double    sinlat, t, rho, x, y, ii, jj, i, j, u, v, d[4], sum, interp;
00475   float     delta, xdist, ydist;
00476   int       sgn, rows, cols, ix, jy, cnt, n;
00477   unsigned char *data;
00478 
00479 
00480   if( lat >= 90 || lat <= -90 ){
00481     return 0.0;
00482   }
00483 
00484   /*
00485   The north polar stereographic projection has the 45 West meridian
00486   running vertically from pole to bottom center;  the south polar
00487   stereographic projection has the 0 meridian running vertically
00488   from pole to top center.
00489   */
00490   if( lat >= 0 ){
00491     delta = 45;
00492     sgn = 1;
00493     xdist = 3850.0; /* distance from pole to left edge */
00494     ydist = 5350.0; /* distance from pole to bottom edge */
00495     rows = NROWS;
00496     cols = NCOLS;
00497     data = &north[0][0];
00498   }
00499   else{
00500     delta = 0;
00501     sgn = -1;
00502     lat = -lat;
00503     xdist = 3950.0; /* distance from pole to left edge */
00504     ydist = 3950.0; /* distance from pole to bottom edge */
00505     rows = SROWS;
00506     cols = SCOLS;
00507     data = &south[0][0];
00508   }
00509 
00510   while( lon <   0 ) lon += 360;
00511   while( lon > 360 ) lon -= 360;
00512 
00513   lon += delta;
00514 
00515   /* Convert input coordinates to radians. */
00516   lat  *= PI/180;
00517   lon  *= PI/180;
00518 
00519   sinlat  = sin( (double)lat );
00520 
00521   /*
00522   The FORTRAN routines from the sidads.colorado.edu site use the
00523   ellipsoidal form of the stereographic projection equations, so
00524   I use them here as well; however, I think this may be a bit of
00525   overkill at 25-kilometer resolution.
00526   */
00527 
00528   /*
00529   Equation 15-9 from page 161 of
00530   Map Projections -- A Working Manual
00531   John P. Snyder
00532   U.S. Geological Survey Professional Paper 1395
00533   Fourth Printing 1997
00534   */
00535   t = tan( (double)( PI/4 - lat/2 ) )
00536     / pow( (double)((1 - EC*sinlat)/(1 + EC*sinlat)), (double)(EC/2) );
00537 
00538   /*
00539   The variables, tc and mc, are derived from the latitude of true
00540   scale, slat, and do not depend on the input parameters, so I only
00541   need to compute them once.  Actually, I could just replace these
00542   by constants, but the following lines make it clearer where the
00543   constants come from.
00544   */
00545   if( slat == 0.0 ){
00546     slat = SLAT * PI/180;
00547     sinslat = sin(slat);
00548 
00549     /*
00550     Equation 15-9 from page 161 of aforementioned publication.
00551     */
00552     tc = tan( (double)( PI/4 - slat/2 ) )
00553       / pow( (double)((1 - EC*sinslat)/(1 + EC*sinslat)), (double)(EC/2) );
00554 
00555     /*
00556     Equation 14-15 from page 101 of aforementioned publication.
00557     */
00558     mc = cos( (double)slat )/sqrt( (double)( 1 - E2*sinslat*sinslat ) );
00559   }
00560 
00561   /*
00562   Equation 21-34 from page 161 of aforementioned publication.
00563   */
00564   rho = RE*mc*t/tc;
00565 
00566   /*
00567   Equations 21-30 and 21-31 from page 161 of aforementioned publication.
00568   */
00569   x =  rho*sgn*sin( (double)( sgn*lon ) );
00570   y = -rho*sgn*cos( (double)( sgn*lon ) );
00571 
00572   ii =        ( x + xdist - CELL/2 )/( CELL );
00573   jj = rows - ( y + ydist - CELL/2 )/( CELL );
00574 
00575   /*
00576   Interpolate data from ice-cover files to get ice fraction
00577   at the specified coordinate.  Make sure to handle cases
00578   where data is flagged as missing (value > 250) for one
00579   reason or another.  Also handle cases where input coordinate
00580   maps outside of the area covered by the ice data files.
00581   */
00582 
00583   if( ii < 0 || ii > cols || jj < 0 || jj > rows){
00584     /*
00585     The input coordinate pair was outside of the areas
00586     represented by the northern and southern data files.
00587     */
00588     return 0;
00589   }
00590 
00591   d[0] = *(data + (int)jj*cols + (int)ii);
00592   if( d[0] > 250 ){
00593     /*
00594     The input coordinate pair mapped to a pixel that
00595     is marked as something other than an ice fraction.
00596     */
00597     return 0.0;
00598   }
00599 
00600   /*
00601   Choose the 4 pixels whose centers mark the corners of a
00602   square that encloses the user's specified input coordinate.
00603   Put the values of the 4 pixels in the array, d.
00604   */
00605   u = modf( ii, &i );
00606   v = modf( jj, &j );
00607 
00608   if( u < 0.5 ){
00609     i--;
00610     u += 0.5;
00611   }
00612   else{
00613     u -= 0.5;
00614   }
00615   if( v < 0.5 ){
00616     j--;
00617     v += 0.5;
00618   }
00619   else{
00620     v -= 0.5;
00621   }
00622   sum = 0;
00623   cnt = 0;
00624   n = 0;
00625   for( jy = j; jy < j + 2; jy++ ){
00626     for( ix = i; ix < i + 2; ix++){
00627       if( ix >= 0 && ix < cols && jy >= 0 && jy < rows ){
00628 
00629         /*
00630         This pixel is within the bounds of the
00631         reference array, so store its value.
00632         */
00633         d[n] = *(data + jy*cols + ix);
00634 
00635         if( d[n] <= 250 ){
00636           /*
00637           This is a valid value so include it in the mean that
00638           will be used to fill in flagged or out-of-bound pixels.
00639           */
00640           sum += d[n];
00641           cnt++;
00642         }
00643       }
00644       else{
00645         /*
00646         Use a flag value of 255 to indicate
00647         that this pixel is out of bounds.
00648         */
00649         d[n] = 255;
00650       }
00651       n++;
00652     }
00653   }
00654   for( n = 0; n < 4; n++ ){
00655     /*
00656     Replace missing values with mean of other non-missing values.
00657     This only affects pixels adjacent to the one the actually
00658     contains the desired Earth coordinate.  If the desired coordinate
00659     did not fall within a valid ice pixel, then this function already
00660     returned a NODATA value higher up in the code.
00661     */
00662     if( d[n] > 250 ){ d[n] = sum/cnt; }
00663   }
00664 
00665   /* Bi-linear interpolation. */
00666   interp = (1 - u)*(1 - v) * d[0]
00667          +      u *(1 - v) * d[1]
00668          + (1 - u)*     v  * d[2]
00669          +      u *     v  * d[3];
00670 
00671   return (float)(interp/250.0);
00672 }
00673 
00674 
00675 char ice_mask_nsidc(float lon, float lat)
00676 {
00677     if(get_icefrac_nsidc(lon, lat) > ice_threshold)
00678         return 1;
00679     else
00680         return 0;
00681 }
00682 
00683 
00684 
00685 /*************************************************************
00686  * init the ice mask functions.  
00687  *
00688  * file      - file name of the ice data file
00689  * year      - year of the ice file
00690  * day       - day of year
00691  * threshold - ice fraction above which the ice mask returns 1
00692  *
00693  * return 0 if OK or 1 if error
00694  *
00695  *************************************************************/
00696 int ice_mask_init(char *file, int year, int day, float threshold)
00697 {
00698     int32 sd_id;
00699     int32 attr_index;
00700     int32 status;
00701     int result;
00702     char titleStr[256] = "";
00703 
00704 
00705     ice_initalized = 0;
00706     using_nsidc = 0;
00707 
00708     // set the threshold global variable
00709     ice_threshold = threshold;
00710     
00711     /* Open the file and initiate the SD interface */
00712     sd_id = SDstart(file, DFACC_RDONLY);
00713     if (sd_id == -1) {
00714 
00715         // if the file is not an HDF file then try to open it as a raw
00716         // NSIDC file
00717         result = ice_mask_init_nsidc_raw(file);
00718         if(result == 0) {
00719             ice_initalized = 1;
00720             using_nsidc = 1;
00721         }
00722         return( result );
00723     }
00724 
00725     // look for the global attribute "Title"
00726     attr_index = SDfindattr(sd_id, "Title");
00727     if (attr_index == -1) {
00728         
00729         // Title not found, assume it is an old ice HDF climatolgy file 
00730         result = ice_mask_init_old(file, day, sd_id);
00731         using_nsidc = 0;
00732         
00733     } else {
00734         
00735         // Read the attribute data.
00736         status = SDreadattr(sd_id, attr_index, titleStr);
00737         if(status == FAIL) {
00738             fprintf(stderr, "-E- %s line %d: Could not read the global attribute \"Title\" from, %s .\n",
00739                     __FILE__,__LINE__,file);
00740             result = HDF_FUNCTION_ERROR;
00741         } else {
00742    
00743             // read title OK
00744             if(strcmp(titleStr, "Sea Ice Concentration Daily") == 0) {
00745                 result = ice_mask_init_daily(file, year, day, sd_id);
00746                 using_nsidc = 1;
00747             } else if(strcmp(titleStr, "Sea Ice Concentration Monthly") == 0) {
00748                 result = ice_mask_init_monthly(file, year, day, sd_id);
00749                 using_nsidc = 1;
00750             } else {
00751                 fprintf(stderr, "-E- %s line %d: Global attribute \"Title\" not valid from, %s .\n",
00752                         __FILE__,__LINE__,file);
00753                 result = 1;
00754             }
00755         } // Title read OK
00756     } // Title found
00757 
00758    
00759     /* Terminate access to the SD interface and close the file */
00760     status = SDend(sd_id);
00761 
00762     if(result == 0)
00763         ice_initalized = 1;
00764 
00765     return result;
00766 }
00767 
00768 
00769 /********************************************************
00770  * get the ice mask at this location
00771  * 
00772  * return 1 if icefrac above ice threshold else return 0
00773  *
00774  ********************************************************/
00775 char ice_mask(float lon, float lat)
00776 {
00777     if(!ice_initalized)
00778         return 0;
00779 
00780     if(using_nsidc) 
00781         return ice_mask_nsidc(lon, lat);
00782     else
00783         return ice_mask_old(lon, lat);
00784 }
00785 
00786 
00787 /**************************************
00788  *  function to return the ice fraction  
00789  **************************************/
00790 float ice_fraction(float lon, float lat)
00791 {
00792     if(!ice_initalized)
00793         return NODATA;
00794     
00795     if(using_nsidc) 
00796         return get_icefrac_nsidc(lon, lat);
00797     else
00798         return get_icefrac_old(lon, lat);
00799 }
00800