• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

/home/pascal/depot/filedata/src/hdffiledata.h

00001 /***************************************************************************
00002  *   Copyright (C) 2005 by Nicolas PASCAL                                  *
00003  *   nicolas.pascal@icare.univ-lille1.fr                                   *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 
00021 /***************************************************************************
00022  *  History :                                                              *
00023  *  25/07/05 : start                                                       *
00024  ***************************************************************************/
00025 
00026 #ifndef HDFFILEDATA_H
00027 #define HDFFILEDATA_H
00028 
00029 #define HDFFILEDATA_TRACE 0
00030 
00031 #include "filedatareader.h"
00032 #include "Hdf_file.hpp"
00033 #include "hdffilemetadata.h"
00034 #include "netcdf.h"
00035 
00036 #include <cmath>
00037 #include <cfloat>
00038 
00039 static const float32 VAR_FILL_VALUE=-DBL_MAX;
00040 
00073 class HDFFileData : public FileDataReader {
00077     template <class T>
00078     T* get_value( const char * sds_name = "Height", int *start = NULL, int *stride = NULL, int *edges = NULL, int rank = -1);
00084     const int32 get_sds_type_code( const string & sds_name );
00085 protected:
00090     Hdf_file *hdf_file;
00095     HDFFileMetaData *metadata;
00102     template <class T>
00103     const vector<int> get_nearest_index(const vector<T>& v_data, const T &val = T(0));
00110     template <class T>
00111     const int get_nearest_index(const vector <T> *data, const T val);
00119     template <class T>
00120     const int get_nearest_index(const T* data = NULL, const int data_size = 0, const T val = T(0));
00121 
00128     void init_read_write_null_input_param(const char* sds_name, int *&start, int *&stride, int *&edges, int &rank, bool * initialized_values);
00132     void free_read_write_allocations( const bool *are_limits_initialized, int *start, int *stride, int *edges );
00133     const bool check_read_write_limits(const char* sds_name, int *start, int *stride, int *edges, const int rank);
00134 public:
00135     /*********************
00136     **   CONSTRUCTORS   **
00137     *********************/
00144     HDFFileData(const string &name="",const string &mode="r", const bool open_file = false);
00149     HDFFileData(const HDFFileData &hfd);
00153     virtual ~HDFFileData();
00158     HDFFileData &operator= (const HDFFileData &hfd);
00163     Hdf_file * get_hdf_file();
00168     void load_hdf_file();
00172     void free_hdf_file();
00176     const bool is_hdf_file_loaded();
00181     HDFFileMetaData* get_metadata();
00185     void load_hdf_metadata();
00190     void free_hdf_metadata();
00196     const bool is_hdf_metadata_loaded();
00202     virtual void get_dataset_fill_value(const string &sds_name, void* fill_value);
00208     vector<int> get_sds_dimension(const string &sds_name);
00214     virtual vector<int> get_dataset_dimension(const string &sds_name) {
00215         return get_sds_dimension (sds_name);
00216     };
00223     vector<int> get_vdata_dimension(const string &vdata_name);
00224 
00225     int get_n_dataset(){return this->get_hdf_file()->get_n_sds();};
00226 
00227     string get_dataset_name(int i){return this->get_hdf_file()->get_sds_name(i);};
00228 
00229     Hdf_sds get_dataset(string sds_name){return this->get_hdf_file()->get_sds(sds_name.c_str());};
00230 
00231     int get_dataset_data_type(string sds_name)
00232     {return this->get_hdf_file()->get_sds_data_type(sds_name.c_str());};
00233 
00234 string get_values_attr_dataset(string sds_name,string attr_name);
00235 
00236     bool has_attr_dataset(string sds_name,string attr_name);
00237 
00241     void close_data_file(){free_hdf_file();};
00242 
00246     void open_data_file(){load_hdf_file();};
00247 
00248     string get_values_attr(string attr_name);
00249 
00250     string get_file_attr(string attr_name);
00251 
00252     bool has_attr(string attr_name);
00253 
00254     bool has_file_attr(string attr_name);
00255     /************************
00256     ** DATA ACCESS METHODS **
00257     ************************/
00265     template <class T>
00266     T get_var_value(const string sds_name, const int &y_index,const int &x_index);
00286     template <class T>
00287     T get_value_0D( const char * sds_name = "Height", int *start = NULL, int *stride = NULL, int *edges = NULL, int &rank = -1);
00330     template <class T>
00331     vector <T> *get_value_1D( const char * sds_name = "Height", int *start = NULL, int *stride = NULL, int *edges = NULL, int &rank= -1);
00376     template <class T>
00377     vector< vector <T> >* get_value_2D( const char * sds_name = "Height", int *start = NULL, int *stride = NULL, int *edges = NULL, int &rank=-1);
00431     virtual void * read_data(void * data, const char * sds_name, int * start = NULL, int * stride = NULL, int * edges = NULL, int rank = -1);
00432 
00445     template<typename DataType>
00446     DataType * read_data(DataType * data, const char * sds_name, int * start = NULL, int * stride = NULL, int * edges = NULL, int rank = -1);
00447 
00473     void* read_vdata(void* data,const char* vdata_name="", const char* vdata_field="", int start=0, int edges=-1);
00474 
00480     void get_fillValue(const string &sds_name, void *fillValue);
00481 
00482     void get_scaling(const string &sds_name, float64 &scale, float64 &offset);
00483 };
00484 
00485 /*************************************************/
00486 /************ TEMPLATES DEFINITION ***************/
00487 /*************************************************/
00488 template <class T>
00489 T* HDFFileData::get_value( const char * sds_name, int *start, int *stride, int *edges, int rank) {
00490     bool are_limits_initialized[3]; // check if start, stride or edges had been initialized in this method
00491     bool hdf_file_already_loaded = is_hdf_file_loaded();
00492     try {
00493         if (!hdf_file_already_loaded)
00494             load_hdf_file();
00495         // --- initialize NULL input parametres ---
00496         init_read_write_null_input_param(sds_name, start, stride, edges,rank, are_limits_initialized);
00497         // check the selection limits
00498         check_read_write_limits(sds_name, start,stride,edges,rank); // throw bad_index in case of problem
00499         // check if there is a conflict between the template type and the sds type
00500         if ( typeid(T).name() != Hdf_common::hdf_type_info(hdf_file->get_sds_data_type(sds_name)) ) {
00501             bad_type e(Hdf_common::hdf_type_info(hdf_file->get_sds_data_type(sds_name)),typeid(T).name(),sds_name);
00502             throw e;
00503         }
00504         // allocate a buffer to read the data
00505         int data_size = 1;
00506         for (int i = 0 ; i<rank ; ++i)
00507             data_size*=edges[i];
00508         T* hdf_data = new T[data_size];
00509         // read it
00510         hdf_file->read_sds(sds_name,hdf_data,(int32*)start,(int32*)stride,(int32*)edges);
00511         // free the ressources allocated by this method
00512         free_read_write_allocations(are_limits_initialized, start, stride, edges);
00513         if (!hdf_file_already_loaded)
00514             free_hdf_file();
00515         return (hdf_data);
00516     } catch(...) {
00517         // free the ressources allocated in this method
00518         free_read_write_allocations(are_limits_initialized , start, stride,edges);
00519         throw;
00520     }
00521 };
00522 template <class T>
00523 T HDFFileData::get_value_0D( const char * sds_name, int *start, int *stride, int *edges, int &rank ) {
00524     T* data = get_value<T>(sds_name,start,stride,edges,rank);
00525     T ret=(*data);
00526     delete[] data;
00527     return ret;
00528 }
00529 template <class T>
00530 vector <T> *HDFFileData::get_value_1D( const char * sds_name, int *start, int *stride, int *edges, int &rank) {
00531     // specific to the method
00532     int method_rank = 1;
00533 
00534     // read the values in a linear buffer
00535     T* data = get_value<T>(sds_name,start,stride,edges,rank);
00536 
00537     // initialize the return vector size
00538     int significant_edges_index[method_rank]; // the index of the edges > 1
00539     int dim_size[method_rank]; // size of the edges > 1
00540 
00541     int dim_size_to_init_index = 0;
00542     for (int i=0 ; i<rank ; ++i) {
00543         if  (edges[i]>1) {
00544             dim_size[dim_size_to_init_index]=edges[i];
00545             significant_edges_index[dim_size_to_init_index]=i;
00546             ++dim_size_to_init_index;
00547         }
00548     }
00549     // allocate the vector
00550     vector <T> *v_data = new vector <T>; // format to return : easier and faster to process
00551     v_data->reserve(dim_size[0]);
00552     // put the data in the vector : easier and faster to process
00553     for ( int i = 0 ; i < dim_size[0] ; ++i ) {
00554         v_data->push_back(data[i]);
00555     }
00556 
00557     delete[] data;
00558     return v_data;
00559 }
00560 template <class T>
00561 vector< vector <T> >* HDFFileData::get_value_2D( const char * sds_name , int *start, int *stride, int *edges, int &rank) {
00562     // rank specific to the method
00563     int method_rank = 2;
00564     // read the values in a linear buffer
00565     T* data = get_value<T>(sds_name,start,stride,edges,rank);
00566     // initialize the return vector size
00567     int significant_edges_index[method_rank]; // the index of the edges > 1
00568     int dim_size[method_rank]; // size of the edges > 1
00569     int dim_size_to_init_index = 0;
00570     for (int i=0 ; i<rank ; ++i) {
00571         if  (edges[i]>1) {
00572             dim_size[dim_size_to_init_index]=edges[i];
00573             significant_edges_index[dim_size_to_init_index]=i;
00574             ++dim_size_to_init_index;
00575         }
00576     }
00577     // allocate the vector
00578     vector< vector <T> > *v_data = new vector< vector <T> >; // format to return : easier and faster to process
00579     v_data->reserve(dim_size[0]);
00580     // put the data in the vector : easier and faster to process
00581     for ( int i = 0 ; i < dim_size[0] ; ++i ) {
00582         vector <T> tmp;
00583         for ( int j = 0 ; j < dim_size[1] ; ++j )
00584             tmp.push_back(data[i*dim_size[1]+j]);
00585         v_data->push_back(tmp);
00586     }
00587     delete[] data;
00588     return v_data;
00589 }
00590 template <class T>
00591 T HDFFileData::get_var_value(const string var_name, const int &y_index,const int &x_index) {
00592     int start[]={y_index,x_index};
00593     int edges[]={1,1};
00594     int rank=2;
00595     return get_value_0D<T>(var_name.c_str(),start,NULL,edges,rank);
00596 }
00597 template <class T>
00598 const vector<int> HDFFileData::get_nearest_index(const vector<T> &v_data, const T &val) {
00599     vector<int> ret;
00600     if (!v_data.empty()) {
00601         T diff = abs((v_data[0])-val);
00602         T current_diff; // temporary difference -> faster
00603         int end = v_data.size();
00604         for (int i = 0; i<end ; ++i) {
00605             current_diff=abs((v_data[i])-val);
00606             if (current_diff<diff) { // found a nearest value
00607                 diff=current_diff;
00608                 ret.clear();
00609                 ret.push_back(i);
00610             } else if (current_diff==diff) { // found one more nearest value
00611                 ret.push_back(i);
00612             }
00613         }
00614     }
00615     return ret;
00616 }
00617 template <class T>
00618 const int HDFFileData::get_nearest_index(const vector <T> *data, const T val) {
00619     int nearest_val_index=-1;
00620     T nearest_value;
00621     T delta;
00622     if (!data->empty()) {
00623         int length = data->size();
00624         nearest_val_index=0;
00625         nearest_value=(*data)[nearest_val_index];
00626         delta=abs(val-nearest_value);
00627         for (int i = 1 ; i<length ; ++i) {
00628             if ( abs(val-(*data)[i])<delta ) {
00629                 nearest_val_index=i;
00630                 nearest_value=(*data)[nearest_val_index];
00631                 delta=abs(val-nearest_value);
00632             }
00633         }
00634     }
00635     return nearest_val_index;
00636 }
00637 template <class T>
00638 const int HDFFileData::get_nearest_index(const T *data, const int data_size, const T val) {
00639     int nearest_val_index=-1;
00640     T nearest_value;
00641     T delta;
00642     if (data!=NULL && data_size!=0) {
00643         nearest_val_index=0;
00644         nearest_value=*(data+nearest_val_index);
00645         delta=abs(val-nearest_value);
00646         for (int i = 1 ; i<data_size ; ++i) {
00647             if ( abs(val-*(data+i))<delta ) {
00648                 nearest_val_index=i;
00649                 nearest_value=*(data+nearest_val_index);
00650                 delta=abs(val-nearest_value);
00651             }
00652         }
00653     }
00654     return nearest_val_index;
00655 }
00656 
00657 // ostream& operator << (ostream& o, const HDFFileData& _hdf);
00658 
00659 template <typename T>
00660 T * HDFFileData::read_data(T * data, const char * sds_name, int * start, int * stride, int * edges, int rank ) {
00661     bool are_limits_initialized[3]; // check if start, stride or edges had been initialized in this method
00662     bool hdf_file_already_loaded = is_hdf_file_loaded();
00663     try {
00664         if (!hdf_file_already_loaded)
00665             load_hdf_file();
00666         // --- initialize NULL input parametres ---
00667         init_read_write_null_input_param(sds_name,start,stride,edges,rank,are_limits_initialized);
00668         // check the selection limits
00669         check_read_write_limits(sds_name,start,stride,edges,rank); // throw bad_index in case of problem
00670         // check if DataType has the same type than the sds values
00671         if ( typeid(T).name() != Hdf_common::hdf_type_info(hdf_file->get_sds_data_type(sds_name)) ) {
00672             bad_type e(Hdf_common::hdf_type_info(hdf_file->get_sds_data_type(sds_name)),typeid(T).name(),sds_name);
00673             throw e;
00674         }
00675         // read the desired value, in the good format
00676         int data_size = 1;
00677         for (int i = 0 ; i<rank ; ++i)
00678             data_size*=edges[i];
00679         // data allocation hasn't been done by the caller
00680         if (data==NULL)
00681             // allocate data
00682             data=new T[data_size];
00683         hdf_file->read_sds(sds_name,data,(int32*)start,(int32*)stride,(int32*)edges);
00684         // free the ressources allocated by this method
00685         free_read_write_allocations(are_limits_initialized,start,stride,edges);
00686         if (!hdf_file_already_loaded)
00687             free_hdf_file();
00688         return data;
00689 
00690     } catch(...) {
00691         free_read_write_allocations(are_limits_initialized,start,stride,edges);
00692         throw;
00693     }
00694 }
00695 
00696 #endif

Generated on Thu Feb 14 2013 17:59:03 for filedata.kdevelop by  doxygen 1.7.1