ocssw  1.0
/disk01/web/ocssw/build/src/libbin++/bin_util.cpp (r8087/r4879)
Go to the documentation of this file.
00001 #include "bin_util.h"
00002 #include "hdf4_bin.h"
00003 #include "seabin.h"
00004 
00005 using namespace std;
00006 
00007 namespace Hdf {
00008 
00009   int create_vdata( int32 fileid, int32 vgid, 
00010             int32 *vdata_id, const char *vdata_name, const char *class_name,
00011             int32 n_flds, char const * const fldname[], int32 type[],
00012             int32 noext, int32 *aid)
00013   {
00014     int32 status;
00015     char buffer[1000];
00016     static int32 prod_count=0;
00017 
00018     // Setup new vdata
00019     // ---------------
00020     *vdata_id = VSattach(fileid, -1, "w");
00021     //    printf("Setting Up: %s %ld\n", vdata_name, *vdata_id);
00022 
00023     for (int32 i=0; i<n_flds; i++) {
00024       status = VSfdefine(*vdata_id, fldname[i], type[i], 1);
00025       if (status != 0) {
00026     printf("Error defining \"%s\".\n", fldname[i]);
00027       }
00028     }
00029 
00030     /* Set fieldnames */
00031     /* -------------- */
00032     strcpy(buffer, fldname[0]);
00033     for (int32 i=1; i<n_flds; i++) {
00034       strcat(buffer, ",");
00035       strcat(buffer, fldname[i]);
00036     }
00037     status = VSsetfields(*vdata_id, buffer);
00038 
00039     status = Vinsert(vgid, *vdata_id);
00040     status = VSsetname(*vdata_id, vdata_name);
00041     status = VSsetclass(*vdata_id, class_name);
00042 
00043     VSsetblocksize(*vdata_id, 4096*6);
00044 
00045 
00046     // Setup External Data Vdatas
00047     // --------------------------
00048     if (strcmp(class_name, "DataSubordinate") == 0 && noext == 0) {
00049 
00050       static FILE *sfile;
00051 
00052       memset(buffer, 0, sizeof(buffer));
00053       status = VSwrite(*vdata_id, (uint8 *) buffer, 1, FULL_INTERLACE);
00054       VSdetach(*vdata_id);
00055       *vdata_id = VSattach(fileid, VSfind(fileid, vdata_name), "w");
00056 
00057       //  synthesize file name
00058       char *outname;
00059       intn access, attach;
00060       Hfidinquire( fileid, &outname, &access, &attach);
00061       strcpy(buffer, outname);
00062 
00063       // Remove trailing ".main" if it exists
00064       char *cptr = strstr( buffer, ".main");
00065       if ( strlen(buffer) + buffer - cptr == 5) *cptr = 0;
00066 
00067       sprintf(&buffer[strlen(buffer)], ".x%02d", prod_count);
00068 
00069       //  open file and write name of main file
00070       //  in first 512 bytes                  
00071       sfile = fopen(buffer, "w");
00072 
00073       if (strrchr(outname, '/') != NULL)
00074     strcpy(buffer, strrchr(outname, '/')+1);
00075       else
00076     strcpy(buffer, outname);
00077 
00078       cptr = strstr( buffer, ".main");
00079       if ( strlen(buffer) + buffer - cptr == 5) *cptr = 0;
00080 
00081       status = fwrite(buffer, 512, 1, sfile);
00082       fclose(sfile);
00083 
00084       //  convert to external element
00085       strcpy(buffer, outname);
00086 
00087       cptr = strstr( buffer, ".main");
00088       if ( strlen(buffer) + buffer - cptr == 5) *cptr = 0;
00089 
00090       sprintf(&buffer[strlen(buffer)], ".x%02d", prod_count);
00091       *aid = HXcreate(fileid, DFTAG_VS, (uint16) VSfind(fileid, vdata_name), 
00092               buffer, 512, 0);
00093 
00094       VSdetach(*vdata_id);
00095       *vdata_id = VSattach(fileid, VSfind(fileid, vdata_name), "w");
00096       VSseek(*vdata_id, 0);
00097 
00098       prod_count++;
00099     }
00100 
00101     return 0;
00102   }
00103 
00104 
00105   int32 write_vdata( int vdata_id, int32 n_recs_to_write, void *data)
00106   {
00107     int32 n_write = VSwrite(vdata_id, (const uint8*) data, 
00108                 n_recs_to_write, FULL_INTERLACE);
00109 
00110     if ( n_write != n_recs_to_write) {
00111       cout << "Error in VSwrite (write_vdata): " << 
00112     n_recs_to_write << " " << n_write << endl;
00113       exit(-1);
00114     }
00115 
00116     return n_write;
00117   }
00118 
00119 
00120   int read_binList( int n_elem, int32 vdata_id_binlist, binListStruct* binList)
00121   {
00122     if (n_elem == 0) {
00123       printf("The number of elements requested to be read is 0.\n");
00124     }
00125 
00126     // Offset within BinList memory struct
00127     int32 binlist_offset[] = {0,4,6,8,12,16,20};
00128 
00129     // Size of fields in BinList Vdata  
00130     int32 binlist_size[] = {4,2,2,2,4,1,4}; 
00131  
00132     uint8 *bytebuf;
00133     bytebuf = (uint8 *) malloc( n_elem*19);
00134 
00135     int records_read;
00136 
00137     records_read = VSread(vdata_id_binlist, bytebuf, n_elem, FULL_INTERLACE);
00138       
00139     // Loop through bins
00140     for (int32 j=0; j<n_elem; j++) {
00141       int binlist_idx = j * 19;
00142       for (size_t i=0; i<7; i++) {
00143 
00144     // Point to output location in BinList structure (memory)
00145     char *ptr = (char *) &binList[j] + binlist_offset[i]; 
00146     memcpy( ptr, &bytebuf[binlist_idx], binlist_size[i]);
00147 
00148     binlist_idx += binlist_size[i];
00149 
00150     if ( i == 0) {
00151       int32 bin;
00152       memcpy( &bin, &bytebuf[j*19], 4);
00153       float lat;
00154       float lon;
00155       bin2ll( bin, &lat, &lon);
00156       memcpy((char *) &binList[j] + 24, &lat, 4); 
00157       memcpy((char *) &binList[j] + 28, &lon, 4); 
00158     }
00159       }
00160     }
00161     free( bytebuf);
00162 
00163     return records_read;
00164   } // end read_binList
00165 
00166 
00167   int write_binList( int n_elem, int32 vdata_id_binlist, 
00168              binListStruct* binList)
00169   {
00170     if (n_elem == 0) {
00171       printf("No elements are requested to be written in \"write_binList\".\n");
00172     }
00173 
00174     // Offset within BinList memory struct
00175     int32 binlist_struct_offset[] = {0,4,6,8,12,16,20};
00176 
00177     // Offset within BinList Vdata
00178     int32 binlist_vdata_offset[] = {0,4,6,8,10,14,15};
00179 
00180     // Size of fields in BinList Vdata  
00181     int32 binlist_size[] = {4,2,2,2,4,1,4};
00182  
00183     uint8 *bytebuf;
00184     bytebuf = (uint8 *) malloc( n_elem*19);
00185 
00186     for (int32 j=0; j<n_elem; j++) {
00187       // Loop through BinList fields
00188       for (size_t i=0; i<7; i++) {
00189         char *ptr = (char *) &binList[j] + binlist_struct_offset[i]; 
00190     memcpy( &bytebuf[j*19 + binlist_vdata_offset[i]], ptr, binlist_size[i]);
00191       }
00192     }
00193     int records_written = 
00194       VSwrite(vdata_id_binlist, bytebuf, n_elem, FULL_INTERLACE);
00195 
00196     if ( records_written != n_elem) {
00197       cout << "Error in VSwrite (write_binList): " << 
00198     n_elem << " " << records_written << endl;
00199       exit(-1);
00200     }
00201 
00202     free( bytebuf);
00203 
00204     return records_written;
00205   } // end write_binList
00206 
00207 
00208   int write_prodData( int n_elem, int32 vdata_id_proddata, float32 *data, 
00209               binListStruct* binList)
00210   {
00211     float32 dta[2];
00212     binListStruct binListRec;
00213     int records_written;
00214 
00215     for (int32 j=0; j<n_elem; j++) {
00216       memcpy( (void *) &binListRec, &binList[j], sizeof(binListStruct));
00217       //      cout << binListRec.weights << endl;
00218       dta[0] = data[j] * binListRec.weights;
00219 
00220       // Can't really compute sum_2 for a single data value per bin.
00221       //      dta[1] = data[j] * data[j] * binListRec.weights;
00222       dta[1] = 0.0; 
00223       records_written = VSwrite(vdata_id_proddata, (const uint8*) dta, 1, 
00224                 FULL_INTERLACE);
00225 
00226       if ( records_written != 1) {
00227     cout << "Error in VSwrite (write_prodData): " << 
00228       1 << " " << records_written << endl;
00229     exit(-1);
00230       }
00231 
00232     }
00233     return 0;
00234   }
00235 
00236 
00237   int copy_prodData( int n_elem, int32 *binsToCopy, char const * const fldname3[],
00238              int32 in_vdata_id_proddata, int32 out_vdata_id_proddata)
00239   {
00240     float32 dta[2];
00241     char buffer[1000];
00242 
00243     strcpy( buffer, fldname3[0]);
00244     strcat( buffer, ",");
00245     strcat( buffer, fldname3[1]);
00246     intn status = VSsetfields(in_vdata_id_proddata, buffer);
00247     if ( status != 0) {
00248       printf("Error setting fields: %s\n", buffer);
00249       exit(1);
00250     }
00251 
00252     for (int32 j=0; j<n_elem; j++) {
00253       VSseek(in_vdata_id_proddata, binsToCopy[j]);
00254       int records_read = VSread(in_vdata_id_proddata, 
00255                 (uint8 *) &dta[0], 1, FULL_INTERLACE);
00256 
00257       int records_written = VSwrite(out_vdata_id_proddata, (const uint8*) dta, 
00258                     1, FULL_INTERLACE);
00259 
00260       if ( records_read != records_written) {
00261     cout << "Error in copy: " << records_read << " " << records_written
00262          << endl;
00263     exit(-1);
00264       }
00265     }
00266     return 0;
00267   }
00268 
00269   int create_compound( hid_t group_id, const char *dataset_name,
00270                hid_t *dataset_id, hid_t *type_id, size_t typesize, 
00271                int32_t n_flds, char const * const fldname[], size_t offset[],
00272                hid_t type[], hid_t *filespace, hid_t dataspace)
00273   { 
00274     herr_t status;
00275 
00276     *type_id = H5Tcreate( H5T_COMPOUND, typesize);
00277     for (int32 i=0; i<n_flds; i++) {
00278       status = H5Tinsert( *type_id, fldname[i], offset[i], type[i]);
00279       if ( status < 0) {
00280     cout << "H5Tinsert error for: " << dataset_name << 
00281       " (field: " << fldname[i] << ")." << endl;
00282     exit(1);
00283       }
00284     }
00285 
00286     hid_t cparms = H5Pcreate( H5P_DATASET_CREATE);
00287 
00288     hsize_t chuck_dims[1] = {1};
00289     status = H5Pset_chunk( cparms, 1, chuck_dims);
00290     *dataset_id = H5Dcreate1( group_id, dataset_name, *type_id, dataspace, 
00291                  cparms);
00292     if ( *dataset_id < 0) {
00293       cout << "Cannot create dataset for: " << dataset_name << "." << endl;
00294       exit(1);
00295     }
00296 
00297     status = H5Pclose( cparms);
00298 
00299     *filespace = H5Dget_space( *dataset_id);
00300     if ( *filespace < 0) {
00301       cout << "Cannot get filespace for: " << dataset_name << "." << endl;
00302       exit(1);
00303     }
00304 
00305     cout << "\"" << dataset_name << "\"" << " successfully created." << endl;
00306     cout << "Dataset id:   " << *dataset_id << endl;
00307     cout << "Datatype id:  " << *type_id << endl;
00308     cout << "Filespace id: " << *filespace << endl << endl;
00309     return 0;
00310   }
00311 }