/*************************************************************************** * Copyright (C) 2005 by Nicolas PASCAL * * nicolas.pascal@icare.univ-lille1.fr * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifndef PARASOLFILEFORMAT_H #define PARASOLFILEFORMAT_H #include #include "file_tools.h" #include "tools.h" #include "file_exceptions.h" #include "filedataexception.h" #include "parasolfilerecord.h" #include /** * Code of the differents allowed data types for PARASOL entries */ enum PARASOLDataType{ CHAR8, UCHAR8, UINT8, INT8, INT16, UINT16, INT32, UINT32, B2, // 2 Bytes bitfield entry B4, // 4 Bytes bitfield entry B8, // 8 Bytes bitfield entry B16, // 16 Bytes bitfield entry FLOAT12_4, // this type is a string representing a double EXP12_5, // this type is a string representing a double FLOAT8_3, // this type is a string representing a double FLOAT16_7, // this type is a string representing a double }; /** * Defines all PARASOL product. The number after the underscore is the product * @warning at this time, only the level2 RB product is implemented */ enum PARASOLProduct{ UNDEFINED=-1, BASIC_1, RB_2, OC_SURF_DIR_2, OC_SURF_NON_DIR_2, OC_AEROSOL_2, LS_SURF_DIR_2, LS_AEROSOL_2, RB_3, OC_MARINE_3, OC_AEROSOL_3, LS_DIR_SIGN_3, LS_ALBEDO_3, LS_ATMO_3, }; /** * Describe one record entry type : * \< position, length, typecode, > * with : * - name : it's name * - desc : a description of this entry * - position : the offset position in the file * - length : the entry data length * - typecode : the typecode of the data : */ class EntryFormat{ public: string name; unsigned short pos; unsigned short len; PARASOLDataType type; string desc; EntryFormat(const char* name="", unsigned short pos=0,unsigned short len=0,PARASOLDataType type=CHAR8, const char* desc="") : name(name),pos(pos),len(len),type(type),desc(desc){;}; EntryFormat(const EntryFormat& my_entry){ name=my_entry.name; pos=my_entry.pos; len=my_entry.len; type=my_entry.type; desc=my_entry.desc; }; EntryFormat &operator=(const EntryFormat &my_entry) { if (&my_entry == this) return *this; // protection against self assignation name=my_entry.name; pos=my_entry.pos; len=my_entry.len; type=my_entry.type; desc=my_entry.desc; return *this; }; ~EntryFormat(){}; } ; /** * The format of a record, designed like this : */ typedef std::vector< EntryFormat > RecordFormat; /** * @class PARASOLFileFormat generic interface that describes one PARASOL file format, wether leader or data */ class PARASOLFileFormat{ PARASOLProduct product; public: PARASOLFileFormat(const PARASOLProduct &product=UNDEFINED) : product(product){}; virtual ~PARASOLFileFormat(){}; /** * Number of PARASOL grid cells along the longitudes */ static const int full_res_grid_col_max = 6480; /** * Number of PARASOL grid cells along the latitudes */ static const int full_res_grid_line_max = 3240; /** * @brief access the memory size needed to read one variable of the given PARASOL data type * @param code the data type * @return the size needed in bytes */ static const size_t get_size_of(PARASOLDataType code); /** * @brief return the level for a given product * @param product the product code * @return the level or -1 if unknown */ static const int get_level(const PARASOLProduct &product); /** * @brief return the number of grid lines for the given product * @return the number of grid lines */ static const int get_nb_grid_line(const PARASOLProduct &product); /** * @brief the product grid resolution relative to full resolution grid division factor * @param product the product * @return 1 if full resolution, 3 if medium */ static const int get_grid_factor(const PARASOLProduct &product); /** * @brief defines the value that represents the missing values in PARASOL files, using their type. * This value is set this way : * @return the missing value used in the read file. Returns 1 if no missing values for this type */ template static const T get_missing_value(const int level) ; /** * @brief defines the value that represents the out of range values in PARASOL files, using their type. * @return the unsignificant value used in the read file. Returns 1 if no missing values for this type */ template static const T get_out_of_range_value(const int level) ; }; /** @class PARASOLLeaderFormat manages the description of the PARASOL leader files format (parametres name, position, size and type) for each level. */ class PARASOLLeaderFormat:public PARASOLFileFormat{ RecordFormat leader_file_descriptor_format; RecordFormat header_format; RecordFormat spatio_temporal_characteristics_format; RecordFormat instrument_setting_parameters_format; RecordFormat technological_parameters_format; RecordFormat data_processing_parameters_format; RecordFormat scaling_factors_format; RecordFormat annotations_format; /** * @brief set the record format entries common to all products */ void build_common_record_format(); /** * @brief set the record format entries for L1 products */ void build_level_1_record_format(); /** * @brief set the record format entries for L2 products */ void build_level_2_record_format(); /** * @brief set the record format entries for L3 products */ void build_level_3_record_format(); public: /************************************* *** CONSTRUCTORS/DESTRUCTORS *** *************************************/ PARASOLLeaderFormat( const PARASOLProduct product=UNDEFINED); ~PARASOLLeaderFormat(){}; const RecordFormat* get_leader_file_descriptor_format() const { return &leader_file_descriptor_format; }; const RecordFormat* get_header_format() const { return &header_format; }; const RecordFormat* get_spatio_temporal_characteristics_format() const { return &spatio_temporal_characteristics_format; }; const RecordFormat* get_instrument_setting_parameters_format() const { return &instrument_setting_parameters_format; }; const RecordFormat* get_technological_parameters_format() const { return &technological_parameters_format; }; const RecordFormat* get_data_processing_parameters_format() const { return &data_processing_parameters_format; }; const RecordFormat* get_scaling_factors_format() const { return &scaling_factors_format; }; const RecordFormat* get_annotations_format() const { return &annotations_format; }; }; /** @class PARASOLDataFormat manages the description of the PARASOL data files format (parametres name, position, size and type) for each level. @author Nicolas PASCAL */ class PARASOLDataFormat: public PARASOLFileFormat{ RecordFormat data_file_descriptor_format; RecordFormat data_format; void build_data_descriptor_record_format(); // common to all products void build_data_format(); // should be determined // product specific methods void build_BASIC_1_record_format(); void build_RB_2_record_format(); void build_OC_SURF_DIR_2_record_format(); void build_OC_SURF_NON_DIR_2_record_format(); void build_OC_AEROSOL_2_record_format(); void build_LS_SURF_DIR_2_record_format(); void build_LS_AEROSOL_2_record_format(); void build_RB_3_record_format(); void build_OC_MARINE_3_record_format(); void build_OC_AEROSOL_3_record_format(); void build_LS_DIR_SIGN_3_record_format(); void build_LS_ALBEDO_3_record_format(); void build_LS_ATMO_3_record_format(); public: /************************************* *** CONSTRUCTORS/DESTRUCTORS *** *************************************/ PARASOLDataFormat( const PARASOLProduct product=UNDEFINED) ; ~PARASOLDataFormat(){}; const RecordFormat* get_data_file_descriptor_format() const { return &data_file_descriptor_format; }; const RecordFormat* get_data_format() const { return &data_format; }; /** * @brief access to the parameter number using the variable name * Will throw a bad_parametre exception if no parametre with this name can be found. * @warning What is called here the parametre index is different than the parametre number in the PARASOL DPC : it runs from 0, and the record number is considered as the first parametre : * For example, in the level 1B products data (see DPC page 18), the Pixel Quality Index is the parametre #1 using the DPC nomenclatura, but using this method it will have an index of 6 * @param var_name the name of the variable * @return the parameter index (or -1 if no found) */ const int get_entry_index(const string& var_name) const; }; template const T PARASOLFileFormat::get_missing_value( const int level) { if (level<1 || level>3) { bad_level e(level); throw e; } if (level==1) { if ( typeid(T)==typeid(unsigned char) ) { return (T)(255); } else if ( typeid(T)==typeid(signed char) ) { return (T)(-127); } else if ( typeid(T)==typeid(unsigned short) ) { return (T)(0); } else if ( typeid(T)==typeid(signed short) ) { return (T)(-32767); } } else if (level==2 || level==3) { if ( typeid(T)==typeid(unsigned char) ) { return (T)(255); } else if ( typeid(T)==typeid(unsigned short) ) { return (T)(65535); } } return T(1); // no missing value } template const T PARASOLFileFormat::get_out_of_range_value( const int level) { if (level<1 || level>3) { bad_level e(level); throw e; } if (level==1) { if ( typeid(T)==typeid(unsigned char) ) { return (T)(254); } else if ( typeid(T)==typeid(signed short) ) { return (T)(32767); } } else if (level==2 || level==3) { if ( typeid(T)==typeid(unsigned char) ) { return (T)(254); } else if ( typeid(T)==typeid(unsigned short) ) { return (T)(65534); } } return T(1); // no missing value } #endif