00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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
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
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];
00491 bool hdf_file_already_loaded = is_hdf_file_loaded();
00492 try {
00493 if (!hdf_file_already_loaded)
00494 load_hdf_file();
00495
00496 init_read_write_null_input_param(sds_name, start, stride, edges,rank, are_limits_initialized);
00497
00498 check_read_write_limits(sds_name, start,stride,edges,rank);
00499
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
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
00510 hdf_file->read_sds(sds_name,hdf_data,(int32*)start,(int32*)stride,(int32*)edges);
00511
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
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
00532 int method_rank = 1;
00533
00534
00535 T* data = get_value<T>(sds_name,start,stride,edges,rank);
00536
00537
00538 int significant_edges_index[method_rank];
00539 int dim_size[method_rank];
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
00550 vector <T> *v_data = new vector <T>;
00551 v_data->reserve(dim_size[0]);
00552
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
00563 int method_rank = 2;
00564
00565 T* data = get_value<T>(sds_name,start,stride,edges,rank);
00566
00567 int significant_edges_index[method_rank];
00568 int dim_size[method_rank];
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
00578 vector< vector <T> > *v_data = new vector< vector <T> >;
00579 v_data->reserve(dim_size[0]);
00580
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;
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) {
00607 diff=current_diff;
00608 ret.clear();
00609 ret.push_back(i);
00610 } else if (current_diff==diff) {
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
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];
00662 bool hdf_file_already_loaded = is_hdf_file_loaded();
00663 try {
00664 if (!hdf_file_already_loaded)
00665 load_hdf_file();
00666
00667 init_read_write_null_input_param(sds_name,start,stride,edges,rank,are_limits_initialized);
00668
00669 check_read_write_limits(sds_name,start,stride,edges,rank);
00670
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
00676 int data_size = 1;
00677 for (int i = 0 ; i<rank ; ++i)
00678 data_size*=edges[i];
00679
00680 if (data==NULL)
00681
00682 data=new T[data_size];
00683 hdf_file->read_sds(sds_name,data,(int32*)start,(int32*)stride,(int32*)edges);
00684
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