ocssw  1.0
/disk01/web/ocssw/build/src/l2gen/mscal_struc.c
Go to the documentation of this file.
00001 /* ========================================================================
00002  *  Procedures create, read, and write mscalibration pixel data
00003  *
00004  * int crosscal_append(char *xcalfile, mscalstr calstr) - creates file, if
00005  *          it does not exist already, and appends data
00006  * int crosscal_read(char *xcalfile, int32_t subsmpl, mscalstr *calstr) - 
00007  *          reads subsampled pixel cross-calibration data and
00008  *          allocates memory and data to the calstr structure
00009  * int crosscal_add(char *xcalfile, int32_t subsmpl, mscalstr *calstr, int32_t *npixs, int32_t *ngranuls) 
00010  *                      reads cross-calibration data from an hdf file,
00011  *                  subsamples if needed, and adds pixel and granule
00012  *                  data to an already existing calstr structure
00013  *
00014  *     Programmer     Organization      Date       Description of change
00015  *   --------------   ------------    --------     ---------------------
00016  *   Ewa Kwiatkowska  SAIC           10 September 2003    Original development
00017  *   Joel Gales       Futuretech     24 October   2012    Add ds_id.fftype
00018  *   Joel Gales       Futuretech     14 June     2013     Add support for NETCDF4 output
00019  *
00020  * ======================================================================== */
00021 
00022 
00023 #include <stdio.h>
00024 #include <sys/types.h>
00025 #include <sys/stat.h>
00026 #include <stdlib.h>
00027 #include <fcntl.h>
00028 #include <string.h>
00029 #include <errno.h>
00030 #include <unistd.h>
00031 #include <libgen.h>
00032 #include <math.h>
00033 
00034 #include "l12_proto.h" // Must be first to find netcdf.h
00035 #include "passthebuck.h"
00036 #include "l2prod_struc.h"
00037 #include "filehandle.h"
00038 #include "hdf_utils.h"
00039 #include "mfhdf.h"
00040 #include "mscal_struc.h"
00041 
00042 static int32_t nbands;
00043 
00044 //int rdstrideSDS(int32 fileID, char *sdsname, int32 stride[2], VOIDP array_data);
00045 int read_glbl_attr(idDS ds_id, char *name, VOIDP ptr);
00046 int crosscal_create(char *xcalfile, idDS *ds_id, mscalstr calstr, int32_t npixs);
00047 int crosscal_readblocks(char *xcalfile, idDS *ds_id, int32_t *spix, int32_t *totalpixs, mscalstr *calstr);
00048 int crosscal_writeblocks(char *xcalfile, idDS ds_id, int32_t *spix, mscalstr calstr, int32_t nfiles);
00049 
00050 
00051 int crosscal_create(char *xcalfile, idDS *ds_id, mscalstr calstr, int32_t npixs)
00052 {
00053 
00054     char title[255];
00055     l2prodstr p, *ptr;
00056     int j;
00057     int dumdim;
00058     int nc_byt, nc_sht, nc_int, nc_flt;
00059 
00060     sprintf(title, "%s Level-2 cross-calibration pixels", sensorName[calstr.sensorID]);
00061 
00062     if ( strcmp(calstr.fmtofile, "NCDF") == 0) {
00063       *ds_id = startDS(xcalfile, FMT_L2NCDF, NC_NETCDF4, 0);
00064       if ( nc_def_dim((*ds_id).fid, "Number_of_Pixels", npixs, &dumdim)
00065        != NC_NOERR) exit(1);
00066       nc_byt = NC_BYTE;
00067       nc_sht = NC_SHORT;
00068       nc_int = NC_INT;
00069       nc_flt = NC_FLOAT;
00070     } else {
00071       *ds_id = startDS(xcalfile, FMT_L2HDF, DFACC_CREATE, 0);
00072       nc_byt = DFNT_UINT8;
00073       nc_sht = DFNT_INT16;
00074       nc_int = DFNT_INT32;
00075       nc_flt = DFNT_FLOAT32;
00076     }
00077 
00078 
00079     /*                                                                  */
00080     /* Create the pixel SDSes                                           */
00081     /* ---------------------------------------------------------------- */
00082     /*                                                                  */
00083     PTB( SetChrGA(*ds_id, "Title", title) );
00084     PTB( SetI32GA(*ds_id, "sensorID\0",(int32)calstr.sensorID) );
00085     PTB( SetChrGA(*ds_id, "Input Parameters", calstr.input_parms));
00086     
00087     PTB( createDS(
00088     *ds_id,                                          /* file id         */
00089     "fileID",                                        /* short name      */
00090     "ID of the File",                                /* long name       */
00091     NULL,                                            /* standard name   */
00092     "dimensionless",                                 /* units           */
00093     0, 0,                                            /* valid range     */
00094     0,0,                                             /* slope           */
00095     nc_sht,                                          /* HDF number type */
00096     1,                                               /* rank            */
00097     npixs, 1, 1,                                     /* dimension sizes */
00098     "Number of Pixels", NULL, NULL                   /* dimension names */
00099     ) );
00100 
00101     PTB( createDS(
00102     *ds_id,                                          /* file id         */
00103     "year",                                          /* short name      */
00104     "Pixel year",                                    /* long name       */
00105     NULL,                                            /* standard name   */
00106     "years",                                         /* units           */
00107     1996, 2038,                                      /* valid range     */
00108     0,0,                                             /* slope           */
00109     nc_sht,                                          /* HDF number type */
00110     1,                                               /* rank            */
00111     npixs, 1, 1,                                     /* dimension sizes */
00112     "Number of Pixels", NULL, NULL                   /* dimension names */
00113     ) );
00114 
00115     PTB( createDS(
00116     *ds_id,                                          /* file id         */
00117     "day",                                           /* short name      */
00118     "Pixel day of year",                             /* long name       */
00119     NULL,                                            /* standard name   */
00120      "days",                                         /* units           */
00121     0,366,                                           /* valid range     */
00122     0,0,                                             /* slope           */
00123     nc_sht,                                          /* HDF number type */
00124     1,                                               /* rank            */
00125     npixs, 1, 1,                                     /* dimension sizes */
00126     "Number of Pixels", NULL, NULL                   /* dimension names */
00127     ) );
00128 
00129     PTB( createDS(
00130     *ds_id,                                          /* file id         */
00131     "msec",                                          /* short name      */
00132     "Pixel time, milliseconds of day",               /* long name       */
00133     NULL,                                            /* standard name   */
00134     "milliseconds",                                  /* units           */
00135     0,0,                                             /* valid range     */
00136     0,0,                                             /* slope           */
00137     nc_int,                                          /* HDF number type */
00138     1,                                               /* rank            */
00139     npixs, 1, 1,                                     /* dimension sizes */
00140     "Number of Pixels", NULL, NULL                   /* dimension names */
00141     ) );
00142 
00143     PTB( createDS(
00144     *ds_id,                                          /* file id         */
00145     "iscan",                                         /* short name      */
00146     "Scan-line number for the pixel",                /* long name       */
00147     NULL,                                            /* standard name   */
00148     "numbers",                                       /* units           */
00149     0,0,                                             /* valid range     */
00150     0,0,                                             /* slope           */
00151     nc_sht,                                          /* HDF number type */
00152     1,                                               /* rank            */
00153     npixs, 1, 1,                                     /* dimension sizes */
00154     "Number of Pixels", NULL, NULL                   /* dimension names */
00155     ) );
00156 
00157     PTB( createDS(
00158     *ds_id,                                          /* file id         */
00159     "mside",                                         /* short name      */
00160     "Mirror side for the pixel",                     /* long name       */
00161     NULL,                                            /* standard name   */
00162     "digit",                                         /* units           */
00163     0,0,                                             /* valid range     */
00164     0,0,                                             /* slope           */
00165     nc_byt,                                          /* HDF number type */
00166     1,                                               /* rank            */
00167     npixs, 1, 1,                                     /* dimension sizes */
00168     "Number of Pixels", NULL, NULL                   /* dimension names */
00169     ) );
00170 
00171     PTB( createDS(
00172     *ds_id,                                          /* file id         */
00173     "detnum",                                        /* short name      */
00174     "Detector number for the pixel",                 /* long name       */
00175     NULL,                                            /* standard name   */
00176     "number",                                        /* units           */
00177     0,0,                                             /* valid range     */
00178     0,0,                                             /* slope           */
00179     nc_byt,                                          /* HDF number type */
00180     1,                                               /* rank            */
00181     npixs, 1, 1,                                     /* dimension sizes */
00182     "Number of Pixels", NULL, NULL                   /* dimension names */
00183     ) );
00184 
00185     PTB( createDS(
00186     *ds_id,                                          /* file id         */
00187     "pixnum",                                        /* short name      */
00188     "Pixel number within the scan-line",             /* long name       */
00189     NULL,                                            /* standard name   */
00190     "number",                                        /* units           */
00191     0,0,                                             /* valid range     */
00192     0,0,                                             /* slope           */
00193     nc_sht,                                          /* HDF number type */
00194     1,                                               /* rank            */
00195     npixs, 1, 1,                                     /* dimension sizes */
00196     "Number of Pixels", NULL, NULL                   /* dimension names */
00197     ) );
00198 
00199     PTB( createDS(
00200     *ds_id,                                          /* file id         */
00201     "lon",                                           /* short name      */
00202     "Pixel longitude",                               /* long name       */
00203     NULL,                                            /* standard name   */
00204     "degrees",                                       /* units           */
00205     -180.0, 180.0,                                   /* valid range     */
00206     0,0,                                             /* slope           */
00207     nc_flt,                                          /* HDF number type */
00208     1,                                               /* rank            */
00209     npixs, 1, 1,                                     /* dimension sizes */
00210     "Number of Pixels", NULL, NULL                   /* dimension names */
00211     ) );
00212 
00213     PTB( createDS(
00214     *ds_id,                                          /* file id         */
00215     "lat",                                           /* short name      */
00216     "Pixel latitude",                                /* long name       */
00217     NULL,                                            /* standard name   */
00218     "degrees",                                       /* units           */
00219     -90.0, 90.0,                                     /* valid range     */
00220     0,0,                                             /* slope           */
00221     nc_flt,                                          /* HDF number type */
00222     1,                                               /* rank            */
00223     npixs, 1, 1,                                     /* dimension sizes */
00224     "Number of Pixels", NULL, NULL                   /* dimension names */
00225     ) );
00226 
00227     
00228     /*                                                                  */
00229     /* Create the geophysical SDSes for the L2 xcalibration products    */
00230     /* ---------------------------------------------------------------- */
00231     /*                                                                  */
00232     ptr = &p;
00233     for (j=0; j<calstr.nprods; j++) {
00234     
00235     if (strcmp(calstr.l2prods[j], "l2_flags") == 0) ;
00236     else
00237         if (strcmp(calstr.l2prods[j], "mside") == 0) ;
00238     else
00239         if (strcmp(calstr.l2prods[j], "detnum") == 0) ;
00240     else
00241         if (strcmp(calstr.l2prods[j], "pixnum") == 0) ;
00242     else {
00243     
00244             if ((ptr = get_l2prod_index((char *)calstr.l2prods[j],(int32)calstr.sensorID,
00245                    (int32)calstr.nbands,0,1,calstr.Lambda)) == NULL) {
00246 
00247                 fprintf(stderr,
00248                 "-E- %s line %d: product index failure.\n",
00249                 __FILE__,__LINE__);
00250                 return(FATAL_ERROR);
00251             };
00252 
00253             PTB( createDS(
00254         *ds_id,                                      /* file id         */
00255             calstr.l2prods[j],                           /* short name      */
00256             ptr->title,                                  /* long name       */
00257             ptr->standard_name,                          /* standard name   */
00258             ptr->units,                                  /* units           */
00259             ptr->min, ptr->max,                          /* valid range     */
00260             0.0, 0.0,                                    /* slope, offset   */
00261             nc_flt,                                      /* HDF number type */
00262             1,                                           /* number of dims  */
00263             npixs, 1, 1,                                 /* dimension sizes */
00264             "Number of Pixels", NULL, NULL               /* dimension names */
00265             ) );
00266     }
00267     }
00268 
00269 
00270     return(LIFE_IS_GOOD);
00271     
00272 }
00273 
00274 
00275 int crosscal_append(char *xcalfile, mscalstr calstr)
00276 {
00277 
00278     idDS ds_id_old, ds_id;
00279     char  command[2*FILENAME_MAX], tempname[FILENAME_MAX];
00280     int   status, exists;
00281     int32_t  spix_old, spix, total_old, i;
00282     mscalstr calstr_old;
00283    
00284     nbands = NBANDS;   /* calstr.nbands; */
00285 
00286     spix_old = -1;
00287     total_old = 0;
00288     calstr_old.data = NULL;
00289     calstr_old.npixs = calstr.npixs;
00290     strcpy(calstr_old.fmtofile, calstr.fmtofile);
00291     if (crosscal_readblocks(xcalfile, &ds_id_old, &spix_old, &total_old, &calstr_old) != LIFE_IS_GOOD) {
00292         printf("-E- %s line %d: Cannot read already existing SDS data %s\n",__FILE__,__LINE__,xcalfile);
00293         return(HDF_FUNCTION_ERROR);
00294     }
00295 
00296     if (calstr_old.npixs == 0L) exists = 0; else {
00297         exists = 1;
00298         if (calstr_old.sensorID != calstr.sensorID) {
00299             printf("-E- %s line %d: Attempt to write into a file whose data come from a different sensor %s\n",__FILE__,__LINE__,sensorName[calstr_old.sensorID]);
00300         free_calstr(calstr_old, 1);
00301         status = endDS(ds_id_old);
00302             return(HDF_FUNCTION_ERROR);
00303         }
00304     }
00305             
00306     if (exists) { 
00307    
00308 /*
00309         p = (char *)name;
00310     strcpy(tempname, xcalfile);
00311     p = dirname(tempname);
00312     strcpy(tempname, p);
00313     strcat(tempname, "/temp.hdf");
00314 */
00315     strcpy(tempname, xcalfile);
00316         strcat(tempname, "_tmp");
00317     
00318     if (crosscal_create(tempname, &ds_id, calstr, total_old+calstr.npixs) != LIFE_IS_GOOD) {
00319             printf("-E- %s line %d: Cannot read already existing SDS data %s\n",__FILE__,__LINE__,tempname);
00320         free_calstr(calstr_old, 1);
00321         status = endDS(ds_id);
00322         status = endDS(ds_id_old);
00323             return(HDF_FUNCTION_ERROR);
00324         }
00325     
00326     spix = 0L;
00327         
00328     do {
00329         
00330         if (crosscal_writeblocks(tempname, ds_id, &spix, calstr_old, 0L) != LIFE_IS_GOOD) {
00331                 printf("-E- %s line %d: Cannot write existing SDS data into the temp file %s\n",__FILE__,__LINE__,tempname);
00332             free_calstr(calstr_old, 1);
00333             status = endDS(ds_id);
00334             status = endDS(ds_id_old);
00335                 return(HDF_FUNCTION_ERROR);
00336         }
00337         
00338         if (crosscal_readblocks(xcalfile, &ds_id_old, &spix_old, &total_old, &calstr_old) != LIFE_IS_GOOD) {
00339                 printf("-E- %s line %d: Cannot read already existing SDS data %s\n",__FILE__,__LINE__,xcalfile);
00340             free_calstr(calstr_old, 1);
00341             status = endDS(ds_id);
00342                 return(HDF_FUNCTION_ERROR);
00343         }
00344 
00345         } while (calstr_old.npixs > 0L);
00346 
00347 
00348     for (i=0; i<calstr.npixs; i++) calstr.fileID[i] += (int16)calstr_old.nfiles;
00349     
00350     if (crosscal_writeblocks(tempname, ds_id, &spix, calstr, calstr_old.nfiles) != LIFE_IS_GOOD) {
00351             printf("-E- %s line %d: Cannot write new SDS data into the temp file %s\n",__FILE__,__LINE__,tempname);
00352         status = endDS(ds_id);
00353             return(HDF_FUNCTION_ERROR);
00354     }
00355         
00356         if (endDS(ds_id) == FAIL) {
00357             printf("-E- %s line %d: Could not close HDF file, %s.\n",__FILE__,__LINE__,tempname);
00358             return(HDF_FUNCTION_ERROR);
00359         }
00360     
00361     sprintf(command, "mv %s %s", tempname, xcalfile);
00362     system(command);
00363 
00364     } else {
00365     
00366         if (crosscal_create(xcalfile, &ds_id, calstr, calstr.npixs) != LIFE_IS_GOOD) {
00367             printf("-E- %s line %d: Could not open HDF file, %s .\n",__FILE__,__LINE__,xcalfile);
00368         status = endDS(ds_id);
00369             return(HDF_FUNCTION_ERROR);
00370         }
00371     
00372     spix = 0L;
00373     
00374     if (crosscal_writeblocks(xcalfile, ds_id, &spix, calstr, 0L) != LIFE_IS_GOOD) {
00375             printf("-E- %s line %d: Cannot write new SDS data into the file %s\n",__FILE__,__LINE__,xcalfile);
00376         status = endDS(ds_id);
00377             return(HDF_FUNCTION_ERROR);
00378     }
00379         
00380         if (endDS(ds_id) == FAIL) {
00381             printf("-E- %s line %d: Could not close HDF file, %s.\n",__FILE__,__LINE__,xcalfile);
00382             return(HDF_FUNCTION_ERROR);
00383         }
00384     }
00385     
00386     
00387     return(LIFE_IS_GOOD);
00388     
00389 }    
00390 
00391 
00392 
00393 /* ------------------------------------------------------         */
00394 /* crosscal_read() - reads cross-calibration data and             */
00395 /*          subsamples if needed                          */
00396 /*          calptr comprises the actual data for npixs pixels     */
00397 /*          memory is allocated depending on the npixs in the file*/
00398 /* ------------------------------------------------------         */
00399 
00400 int crosscal_read(char *xcalfile, int32_t subsmpl, mscalstr *calstr)
00401 {
00402 
00403   idDS ds_id; 
00404   int32 dim_sizes[H4_MAX_VAR_DIMS], sds_id;
00405   int32 stride[2], n_datasets, n_file_attr, rank, num_type, attributes;
00406   intn  status;
00407   char  name[H4_MAX_NC_NAME];
00408   int32_t  nfiles=0, totalpix=0, i, length, l;
00409   char  input_parms[16384];
00410   int *varids;  
00411     
00412   if (subsmpl <= 1) subsmpl = 1;
00413     
00414   if ( strcmp(calstr->fmtofile, "NCDF") == 0) {
00415     ds_id = startDS(xcalfile, FMT_L2NCDF, NC_NOWRITE, 0);
00416   } else {
00417     ds_id = startDS(xcalfile, FMT_L2HDF, DFACC_RDONLY, 0);
00418   }
00419   if (ds_id.fid == FAIL) {
00420     printf("-E- %s line %d: Could not open HDF file, %s .\n",__FILE__,__LINE__,xcalfile);
00421     return(HDF_FUNCTION_ERROR);
00422   }
00423     
00424   if ( strcmp(calstr->fmtofile, "NCDF") == 0) {
00425     status = nc_inq_varids(ds_id.fid, &n_datasets, NULL);    
00426     varids = (int *) calloc(n_datasets, sizeof(int));
00427     status = nc_inq_varids(ds_id.fid, &n_datasets, varids);    
00428   } else {
00429     SDfileinfo(ds_id.fid, &n_datasets, &n_file_attr);
00430   }
00431 
00432   strcpy(name, "sensorID\0");
00433   read_glbl_attr(ds_id, name, (VOIDP) &(calstr->sensorID));
00434   strcpy(name, "Input Parameters\0");
00435   read_glbl_attr(ds_id, name, (VOIDP) input_parms);
00436   l = strlen(input_parms);
00437   if ((calstr->input_parms = (char *)malloc((l+1)*sizeof(char))) == NULL) {
00438     printf("-E- %s line %d: Error allocating memory to MScalmerge input parameter text.\n",__FILE__,__LINE__);
00439     return(HDF_FUNCTION_ERROR);
00440   }
00441   strncpy(calstr->input_parms, input_parms, l);
00442   calstr->input_parms[l] = '\x0';
00443     
00444   nfiles = 0L;
00445   do {
00446     sprintf(name, "filename%d", nfiles);
00447         
00448     if (findAttr(ds_id,name) == FAIL) break; else ++nfiles;
00449     
00450   } while (1);
00451   
00452   if (nfiles == 0L) {
00453     printf("-E- %s line %d: Could not find filename attributes, %s .\n",__FILE__,__LINE__,name);
00454     return(HDF_FUNCTION_ERROR);
00455   }
00456         
00457   strcpy(name, "fileID\0");
00458   if (getDimsDS(ds_id, name, dim_sizes) != 0) {
00459     printf("-E- %s line %d: Could not read HDF file dimensions, %s .\n",__FILE__,__LINE__,xcalfile);
00460     status = endDS(ds_id);
00461     return(HDF_FUNCTION_ERROR);
00462   }
00463   if (dim_sizes[0] < 0){
00464     printf("-E- %s line %d: The rank of the requested parameter (%s) is incorrect\n",__FILE__,__LINE__,name);
00465     status = endDS(ds_id);
00466     return(HDF_FUNCTION_ERROR);
00467   }
00468   if (dim_sizes[0] == SD_UNLIMITED) printf("  Dimension SD_UNLIMITED"); else totalpix = (int32_t)dim_sizes[0];
00469         
00470 
00471   for (i=0; i<nfiles; i++) {
00472     sprintf(name, "filename%d", i);
00473         
00474     if (read_glbl_attr(ds_id, name, (VOIDP) calstr->filenames[i]) != SUCCESS) {
00475       printf("-E- %s line %d: Error reading filename attributes (%s)\n",__FILE__,__LINE__,name);
00476       free_calstr(*calstr, 1);
00477       status = endDS(ds_id);
00478       return(HDF_FUNCTION_ERROR);
00479     }
00480   }
00481   
00482   calstr->nprods = 1000;
00483   if ((calstr->l2prods = (prname *)malloc(calstr->nprods*sizeof(prname))) == NULL) {
00484     printf("-E- %s line %d: Error allocating memory to l2 product names.\n",__FILE__,__LINE__);
00485     return(HDF_FUNCTION_ERROR);
00486   }
00487   calstr->nprods = 0;
00488 
00489   for (i=0; i<n_datasets; i++) {
00490 
00491     if ( strcmp(calstr->fmtofile, "NCDF") == 0) {
00492       status = nc_inq_varname (ds_id.fid, varids[i], name);
00493     } else {
00494       sds_id = SDselect(ds_id.sid, i);
00495       status = SDgetinfo(sds_id, name, &rank, dim_sizes, &num_type, &attributes);
00496     }
00497 
00498     if (strcmp(name, "fileID") == 0) ;
00499     else 
00500       if (strcmp(name, "l2_flags") == 0) ;
00501       else 
00502     if (strcmp(name, "year") == 0) ;
00503     else 
00504       if (strcmp(name, "day") == 0) ;
00505       else 
00506         if (strcmp(name, "msec") == 0) ;
00507         else 
00508           if (strcmp(name, "iscan") == 0) ;
00509           else 
00510         if (strcmp(name, "mside") == 0) ;
00511         else 
00512           if (strcmp(name, "detnum") == 0) ;
00513           else 
00514             if (strcmp(name, "pixnum") == 0) ;
00515             else 
00516               if (strcmp(name, "lon") == 0) ;
00517               else 
00518             if (strcmp(name, "lat") == 0) ;
00519             else {
00520         
00521               strcpy(calstr->l2prods[calstr->nprods], name);
00522               calstr->nprods++;
00523             }
00524   }
00525   free( varids);
00526 
00527   if ((calstr->l2prods = (prname *)realloc((void *)calstr->l2prods, calstr->nprods*sizeof(prname))) == NULL) {
00528     printf("-E- %s line %d: Error reallocating memory to l2 product names.\n",__FILE__,__LINE__);
00529     return(HDF_FUNCTION_ERROR);
00530   }
00531   calstr->Lambda = NULL;
00532             
00533   totalpix = (totalpix+subsmpl-1)/subsmpl;
00534     
00535   length = alloc_calstr(nfiles, totalpix, calstr);
00536 
00537   int32 start[3] = {0, 0, 0};
00538   int32 count[3] = {calstr->npixs, 0, 0};
00539   if (subsmpl <= 1) {
00540 
00541     PTB( readDS(ds_id,"fileID\0",start,NULL,count,(VOIDP)calstr->fileID) );
00542     PTB( readDS(ds_id,"year\0",start,NULL,count,(VOIDP)calstr->year) );
00543     PTB( readDS(ds_id,"day\0",start,NULL,count,(VOIDP)calstr->day) );
00544     PTB( readDS(ds_id,"msec\0",start,NULL,count,(VOIDP)calstr->msec) );
00545     PTB( readDS(ds_id,"iscan\0",start,NULL,count,(VOIDP)calstr->iscan) );
00546     PTB( readDS(ds_id,"mside\0",start,NULL,count,(VOIDP)calstr->mside) );
00547     PTB( readDS(ds_id,"detnum\0",start,NULL,count,(VOIDP)calstr->detnum) );
00548     PTB( readDS(ds_id,"pixnum\0",start,NULL,count,(VOIDP)calstr->pixnum) );
00549     PTB( readDS(ds_id,"lon\0",start,NULL,count,(VOIDP)calstr->lon) );
00550     PTB( readDS(ds_id,"lat\0",start,NULL,count,(VOIDP)calstr->lat) );
00551     
00552     l = 0;
00553     for (i=0; i<calstr->nprods; i++) {
00554       if (strcmp(calstr->l2prods[i], "l2_flags") == 0) ;
00555       else
00556     if (strcmp(calstr->l2prods[i], "mside") == 0) ;
00557     else
00558       if (strcmp(calstr->l2prods[i], "detnum") == 0) ;
00559       else
00560         if (strcmp(calstr->l2prods[i], "pixnum") == 0) ;
00561         else {
00562           PTB( readDS(ds_id,calstr->l2prods[i],start,NULL,count,(VOIDP)&(calstr->ddata[l*totalpix])) );
00563           ++l;
00564         }
00565     }
00566   } else {
00567     int32 stride[3] = {subsmpl, 1, 1};
00568     
00569     PTB( readDS(ds_id,"fileID\0",start,stride,count,(VOIDP)calstr->fileID) );
00570     PTB( readDS(ds_id,"year\0",start,stride,count,(VOIDP)calstr->year) );
00571     PTB( readDS(ds_id,"day\0",start,stride,count,(VOIDP)calstr->day) );
00572     PTB( readDS(ds_id,"msec\0",start,stride,count,(VOIDP)calstr->msec) );
00573     PTB( readDS(ds_id,"iscan\0",start,stride,count,(VOIDP)calstr->iscan) );
00574     PTB( readDS(ds_id,"mside\0",start,stride,count,(VOIDP)calstr->mside) );
00575     PTB( readDS(ds_id,"detnum\0",start,stride,count,(VOIDP)calstr->detnum) );
00576     PTB( readDS(ds_id,"pixnum\0",start,stride,count,(VOIDP)calstr->pixnum) );
00577     PTB( readDS(ds_id,"lon\0",start,stride,count,(VOIDP)calstr->lon) );
00578     PTB( readDS(ds_id,"lat\0",start,stride,count,(VOIDP)calstr->lat) );
00579        
00580     l = 0;
00581     for (i=0; i<calstr->nprods; i++) {
00582       if (strcmp(calstr->l2prods[i], "l2_flags") == 0) ;
00583       else
00584     if (strcmp(calstr->l2prods[i], "mside") == 0) ;
00585     else
00586       if (strcmp(calstr->l2prods[i], "detnum") == 0) ;
00587       else
00588         if (strcmp(calstr->l2prods[i], "pixnum") == 0) ;
00589         else {
00590           PTB( readDS(ds_id,calstr->l2prods[i],start,stride,count,(VOIDP)&(calstr->ddata[l*totalpix])) );
00591           ++l;
00592         }
00593     }
00594   }
00595     
00596   if (endDS(ds_id) == FAIL) {
00597     printf("-E- %s line %d: Could not close HDF file, %s .\n",__FILE__,__LINE__,xcalfile);
00598     return(HDF_FUNCTION_ERROR);
00599   }
00600   
00601   return(LIFE_IS_GOOD);
00602 }    
00603 
00604 
00605 
00606 /* ------------------------------------------------------         */
00607 /* crosscal_readblocks() - reads consecutive cross-calibration    */              
00608 /*          blocks of data of the size of 400,000 pixels          */                
00609 /*          calptr comprises the actual data for the 400,0000     */
00610 /*          pixels, memory is allocated with the first use        */
00611 /* ------------------------------------------------------         */
00612 
00613 int crosscal_readblocks(char *xcalfile, idDS *ds_id, int32_t *spix, int32_t *totalpixs, mscalstr *calstr)
00614 {
00615 
00616     int32 dim_sizes[H4_MAX_VAR_DIMS], sds_id;
00617     intn  status;
00618     char  name[H4_MAX_NC_NAME];
00619     int32_t  nfiles=0, i, length, l;
00620     int32 n_datasets, n_file_attr, rank, num_type, attributes;
00621     char  input_parms[16384];
00622     int   *varids;
00623     
00624     if (*spix >= *totalpixs) {
00625         if (endDS(*ds_id) == FAIL) {
00626             printf("-E- %s line %d: Could not close HDF file, %s .\n",__FILE__,__LINE__,xcalfile);
00627             return(HDF_FUNCTION_ERROR);
00628         }
00629         free_calstr(*calstr, 1);
00630         calstr->npixs = 0L;
00631     return(LIFE_IS_GOOD);
00632     }
00633     
00634     
00635     if (*spix < 0L) {
00636     
00637         calstr->npixs = 0L;
00638     calstr->nfiles = 0L;
00639 
00640     if ( strcmp(calstr->fmtofile, "NCDF") == 0) {
00641       *ds_id = startDS(xcalfile, FMT_L2NCDF, NC_NOWRITE, 0);
00642     } else {
00643       *ds_id = startDS(xcalfile, FMT_L2HDF, DFACC_RDONLY, 0);
00644     }
00645         if ((*ds_id).fid == FAIL) {
00646         return(LIFE_IS_GOOD);
00647         }
00648     
00649     if ( strcmp(calstr->fmtofile, "NCDF") == 0) {
00650       status = nc_inq_varids((*ds_id).fid, &n_datasets, NULL);    
00651       varids = (int *) calloc(n_datasets, sizeof(int));
00652       status = nc_inq_varids((*ds_id).fid, &n_datasets, varids);    
00653     } else {
00654       SDfileinfo((*ds_id).fid, &n_datasets, &n_file_attr);
00655     }
00656 
00657         strcpy(name, "sensorID\0");
00658         if (read_glbl_attr(*ds_id, name, (VOIDP) &(calstr->sensorID)) != LIFE_IS_GOOD) {
00659             printf("-E- %s line %d: Could not read HDF sensor attribute, %s .\n",__FILE__,__LINE__,xcalfile);
00660             status = endDS(*ds_id);
00661             return(HDF_FUNCTION_ERROR);
00662         }
00663     
00664         strcpy(name, "Input Parameters\0");
00665         read_glbl_attr(*ds_id, name, (VOIDP) input_parms);
00666         length = strlen(input_parms);
00667         if ((calstr->input_parms = (char *)malloc((length+1)*sizeof(char))) == NULL) {
00668             printf("-E- %s line %d: Error allocating memory to MScalmerge input parameter text.\n",__FILE__,__LINE__);
00669             status = endDS(*ds_id);
00670             return(HDF_FUNCTION_ERROR);
00671         }
00672         strncpy(calstr->input_parms, input_parms, length);
00673         calstr->input_parms[length] = '\x0';
00674         
00675         nfiles = 0L;
00676         do {
00677             sprintf(name, "filename%d", nfiles);
00678         
00679         if (findAttr( *ds_id, name) == FAIL) break; else ++nfiles;
00680     
00681         } while (1);
00682 
00683     
00684         strcpy(name, "fileID\0");
00685         if (getDimsDS(*ds_id, name, dim_sizes) != NC_NOERR) {
00686             printf("-E- %s line %d: Could not read file dimensions, %s .\n",__FILE__,__LINE__,xcalfile);
00687             status = endDS(*ds_id);
00688             return(HDF_FUNCTION_ERROR);
00689         }
00690         if (dim_sizes[0] < 0) {
00691             printf("-E- %s line %d: The rank of the requested parameter (%s) is incorrect\n",__FILE__,__LINE__,name);
00692             status = endDS(*ds_id);
00693             return(HDF_FUNCTION_ERROR);
00694         }
00695         *totalpixs = (int32_t)dim_sizes[0];
00696     
00697         if (nfiles == 0L || *totalpixs == 0L) {
00698             printf("-E- %s line %d: There are no data in the file, %s .\n",__FILE__,__LINE__,name);
00699         status = endDS(*ds_id);
00700             return(LIFE_IS_GOOD);
00701         }
00702 
00703         calstr->nprods = 1000;
00704         if ((calstr->l2prods = (prname *)malloc(calstr->nprods*sizeof(prname))) == NULL) {
00705             printf("-E- %s line %d: Error allocating memory to l2 product names.\n",__FILE__,__LINE__);
00706             exit(FATAL_ERROR);
00707         }
00708         calstr->nprods = 0;
00709     
00710     for (i=0; i<n_datasets; i++) {
00711 
00712       if ( strcmp(calstr->fmtofile, "NCDF") == 0) {
00713         status = nc_inq_varname ((*ds_id).fid, varids[i], name);
00714       } else {
00715         sds_id = SDselect((*ds_id).fid, i);
00716         status = SDgetinfo(sds_id, name, &rank, dim_sizes, &num_type, &attributes);
00717       }
00718     
00719       if (strcmp(name, "fileID") == 0) ;
00720       else 
00721         if (strcmp(name, "l2_flags") == 0) ;
00722         else 
00723           if (strcmp(name, "year") == 0) ;
00724           else 
00725         if (strcmp(name, "day") == 0) ;
00726         else 
00727           if (strcmp(name, "msec") == 0) ;
00728           else 
00729             if (strcmp(name, "iscan") == 0) ;
00730             else 
00731               if (strcmp(name, "mside") == 0) ;
00732               else 
00733             if (strcmp(name, "detnum") == 0) ;
00734             else 
00735               if (strcmp(name, "pixnum") == 0) ;
00736               else 
00737                 if (strcmp(name, "lon") == 0) ;
00738                 else 
00739                   if (strcmp(name, "lat") == 0) ;
00740                   else {
00741                 
00742                 strcpy(calstr->l2prods[calstr->nprods], name);
00743                 calstr->nprods++;
00744                   }
00745         }
00746     free( varids);
00747 
00748         if ((calstr->l2prods = (prname *)realloc((void *)calstr->l2prods, calstr->nprods*sizeof(prname))) == NULL) {
00749             printf("-E- %s line %d: Error reallocating memory to l2 product names.\n",__FILE__,__LINE__);
00750             return(HDF_FUNCTION_ERROR);
00751         }
00752         calstr->Lambda = NULL;
00753 
00754         if (*totalpixs > 1000000) 
00755             length = alloc_calstr(nfiles, 1000000L, calstr);
00756     else
00757             length = alloc_calstr(nfiles, *totalpixs, calstr);
00758         
00759 
00760         for (i=0; i<nfiles; i++) {
00761             sprintf(name, "filename%d", i);
00762         
00763         if (read_glbl_attr(*ds_id, name, (VOIDP) calstr->filenames[i]) != SUCCESS) {
00764             printf("-E- %s line %d: Error reading filename attributes (%s)\n",__FILE__,__LINE__,name);
00765                 status = endDS(*ds_id);
00766             free_calstr(*calstr, 1);
00767             calstr->npixs = 0L;
00768         calstr->nfiles = 0L;
00769                 return(HDF_FUNCTION_ERROR);
00770         }
00771         }
00772     
00773     *spix = 0L;
00774     
00775     } else {
00776         
00777     if (*spix+calstr->npixs > *totalpixs) calstr->npixs = *totalpixs - *spix;
00778     }   
00779     int32 start[3] = {*spix, 0, 0};
00780     int32 count[3] = {calstr->npixs, 0, 0};
00781     int32 stride[3] = {1, 1, 1};
00782 
00783     PTB( readDS(*ds_id,"fileID\0",start,stride,count,(VOIDP)calstr->fileID) );
00784     PTB( readDS(*ds_id,"year\0",start,stride,count,(VOIDP)calstr->year) );
00785     PTB( readDS(*ds_id,"day\0",start,stride,count,(VOIDP)calstr->day) );
00786     PTB( readDS(*ds_id,"msec\0",start,stride,count,(VOIDP)calstr->msec) );
00787     PTB( readDS(*ds_id,"iscan\0",start,stride,count,(VOIDP)calstr->iscan) );
00788     PTB( readDS(*ds_id,"mside\0",start,stride,count,(VOIDP)calstr->mside) );
00789     PTB( readDS(*ds_id,"detnum\0",start,stride,count,(VOIDP)calstr->detnum) );
00790     PTB( readDS(*ds_id,"pixnum\0",start,stride,count,(VOIDP)calstr->pixnum) );
00791     PTB( readDS(*ds_id,"lon\0",start,stride,count,(VOIDP)calstr->lon) );
00792     PTB( readDS(*ds_id,"lat\0",start,stride,count,(VOIDP)calstr->lat) );
00793        
00794     l = 0;
00795     for (i=0; i<calstr->nprods; i++) {
00796         if (strcmp(calstr->l2prods[i], "l2_flags") == 0) ;
00797         else
00798         if (strcmp(calstr->l2prods[i], "mside") == 0) ;
00799         else
00800         if (strcmp(calstr->l2prods[i], "detnum") == 0) ;
00801         else
00802         if (strcmp(calstr->l2prods[i], "pixnum") == 0) ;
00803         else {
00804         PTB( readDS(*ds_id,calstr->l2prods[i],start,stride,count,
00805             (VOIDP)&(calstr->ddata[l*calstr->npixs])) );
00806         ++l;
00807     }
00808     }   
00809 
00810     
00811     *spix += calstr->npixs;
00812         
00813     return(LIFE_IS_GOOD);
00814     
00815 }    
00816 
00817 
00818 /* ------------------------------------------------------         */
00819 /* crosscal_writeblocks() - writes consecutive cross-calibration  */              
00820 /*          blocks of data                                    */                
00821 /*          calptr comprises the actual data for the 400,0000     */
00822 /*          pixels, memory is allocated with the first use        */
00823 /* ------------------------------------------------------         */
00824 
00825 int crosscal_writeblocks(char *xcalfile, idDS ds_id, int32_t *spix, mscalstr calstr, int32_t nfiles)
00826 {
00827 
00828     char  name[H4_MAX_NC_NAME];
00829     int32_t  i, j, l;
00830 
00831     if (nfiles < 0) nfiles = 0L;    
00832     
00833     if (*spix <= 0 || nfiles > 0) {
00834       for (i=0; i<calstr.nfiles; i++) {
00835         
00836     j = i + nfiles;
00837     sprintf(name, "filename%d", j);
00838         
00839     PTB( SetChrGA(ds_id, name, (char *)calstr.filenames[i]) );
00840       }
00841     }
00842 
00843     PTB( writeDS(ds_id,"fileID\0",(VOIDP)calstr.fileID,(int32)*spix,0,0,(int32)calstr.npixs,1,1) );
00844     PTB( writeDS(ds_id,"year\0",(VOIDP)calstr.year,(int32)*spix,0,0,(int32)calstr.npixs,1,1) );
00845     PTB( writeDS(ds_id,"day\0",(VOIDP)calstr.day,(int32)*spix,0,0,(int32)calstr.npixs,1,1) );
00846     PTB( writeDS(ds_id,"msec\0",(VOIDP)calstr.msec,(int32)*spix,0,0,(int32)calstr.npixs,1,1) );
00847     PTB( writeDS(ds_id,"iscan\0",(VOIDP)calstr.iscan,(int32)*spix,0,0,(int32)calstr.npixs,1,1) );
00848     PTB( writeDS(ds_id,"mside\0",(VOIDP)calstr.mside,(int32)*spix,0,0,(int32)calstr.npixs,1,1) );
00849     PTB( writeDS(ds_id,"detnum\0",(VOIDP)calstr.detnum,(int32)*spix,0,0,(int32)calstr.npixs,1,1) );
00850     PTB( writeDS(ds_id,"pixnum\0",(VOIDP)calstr.pixnum,(int32)*spix,0,0,(int32)calstr.npixs,1,1) );
00851     PTB( writeDS(ds_id,"lon\0",(VOIDP)calstr.lon,(int32)*spix,0,0,(int32)calstr.npixs,1,1) );
00852     PTB( writeDS(ds_id,"lat\0",(VOIDP)calstr.lat,(int32)*spix,0,0,(int32)calstr.npixs,1,1) );
00853        
00854     l = 0;
00855     for (i=0; i<calstr.nprods; i++) {
00856         if (strcmp(calstr.l2prods[i], "l2_flags\0") == 0) ; 
00857     else
00858         if (strcmp(calstr.l2prods[i], "mside\0") == 0) ; 
00859     else
00860         if (strcmp(calstr.l2prods[i], "detnum\0") == 0) ;
00861     else
00862         if (strcmp(calstr.l2prods[i], "pixnum\0") == 0) ;
00863     else {
00864         PTB( writeDS(ds_id,calstr.l2prods[i],(VOIDP)(calstr.ddata+l*calstr.npixs),
00865              (int32)*spix,0,0,(int32)calstr.npixs,1,1) );
00866         ++l;
00867     }
00868     }
00869 
00870     
00871     *spix += calstr.npixs;
00872     
00873     return(LIFE_IS_GOOD);
00874     
00875 }    
00876 
00877 
00878 int read_glbl_attr(idDS ds_id, char *name, VOIDP ptr) 
00879 {                                           
00880   if (readAttr(ds_id,name,(VOIDP)ptr)){ 
00881     printf("-E- %s line %d: Could not get global attribute, %s.\n", __FILE__,__LINE__,(name));
00882     return(HDF_FUNCTION_ERROR);
00883   }
00884 
00885   return(LIFE_IS_GOOD);
00886 }
00887 
00888 
00889 
00890 int32_t alloc_calstr(int32_t nfiles, int32_t npixs, mscalstr *calstr)
00891 {
00892     
00893     int32_t  len, l;
00894     unsigned char  *p;
00895 
00896     
00897     l = 5*sizeof(int16) + sizeof(int32) + 2*sizeof(uint8) + 2*sizeof(float);
00898     len = nfiles*sizeof(stname) + npixs*l;
00899     
00900     for (l=0; l<calstr->nprods; l++) {
00901     
00902         if (strcmp(calstr->l2prods[l], "l2_flags") == 0) ;
00903     else
00904         if (strcmp(calstr->l2prods[l], "mside") == 0) ;
00905         else
00906         if (strcmp(calstr->l2prods[l], "detnum") == 0) ;
00907         else
00908         if (strcmp(calstr->l2prods[l], "pixnum") == 0) ;
00909         else
00910     len += npixs*sizeof(float32);
00911     }
00912     
00913     if ((p = (unsigned char *) malloc(len)) == NULL) {
00914     printf("%s -Error: Cannot allocate memory to cross-calibration data\n",__FILE__);
00915     exit(FATAL_ERROR);
00916     }
00917     calstr->nfiles = nfiles;
00918     calstr->npixs = npixs;
00919     calstr->data = p;
00920     calstr->filenames = (stname *) p; p += nfiles*sizeof(stname);
00921     calstr->fileID =    (int16  *) p; p += npixs*sizeof(int16);
00922     calstr->year =  (int16  *) p; p += npixs*sizeof(int16);
00923     calstr->day =   (int16  *) p; p += npixs*sizeof(int16);
00924     calstr->msec =  (int32  *) p; p += npixs*sizeof(int32);
00925     calstr->iscan =     (int16  *) p; p += npixs*sizeof(int16);
00926     calstr->mside =     (uint8  *) p; p += npixs*sizeof(uint8);
00927     calstr->detnum =    (uint8  *) p; p += npixs*sizeof(uint8);
00928     calstr->pixnum =    (int16  *) p; p += npixs*sizeof(int16);
00929     calstr->lon =   (float  *) p; p += npixs*sizeof(float);
00930     calstr->lat =   (float  *) p; p += npixs*sizeof(float);
00931     calstr->ddata =     (float32 *) p;
00932     
00933     return(len);
00934     
00935 }
00936    
00937 
00938 
00939 
00940 
00941 
00942 
00943 
00944 void free_calstr(mscalstr calstr, int all)
00945 {
00946      if (calstr.data != NULL) free(calstr.data);
00947      calstr.data = NULL;
00948      
00949      if (all) {
00950         if (calstr.Lambda != NULL) free(calstr.Lambda); calstr.Lambda = NULL;
00951     if (calstr.l2prods != NULL) free(calstr.l2prods); calstr.l2prods = NULL;
00952     if (calstr.input_parms != NULL) free(calstr.input_parms); calstr.input_parms = NULL;
00953      }
00954 }
00955 
00956