/*************************************************************************** * 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. * ***************************************************************************/ #include "parasolleader.h" PARASOLLeader::PARASOLLeader(const string leader_filename) : PARASOLFileReader(leader_filename) { leader_file_descriptor = NULL; header = NULL; spatio_temp_char = NULL; instrument_setting_param = NULL; techno_param = NULL; data_processing_param = NULL; scaling_factors = NULL; annotations = NULL; if (product != UNDEFINED) leader_file_format = new PARASOLLeaderFormat(product); } PARASOLLeader::~PARASOLLeader() { free_records(); delete leader_file_format, leader_file_format = NULL; } void PARASOLLeader::free_records() { for (Record rec_id = LEADER_FILE_DESCRIPTOR ; rec_id < ANNOTATIONS + 1 ; rec_id = (Record)(rec_id + 1)) free_record(rec_id); } PARASOLFileRecord * PARASOLLeader::init_record( const Record & record_code ) { if (record_code==LEADER_FILE_DESCRIPTOR) { leader_file_descriptor=new LeaderFileDescriptorRecord(); return leader_file_descriptor; } else if (record_code==HEADER) { header=new HeaderRecord(); return header; } else if (record_code==SPATIO_TEMPORAL_CHARACTERISTICS) { spatio_temp_char=new SpatioTemporalCharacteristicsRecord(); return spatio_temp_char; } else if (record_code==INSTRUMENT_SETTING_PARAMETERS) { instrument_setting_param=new InstrumentSettingParametersRecord(); return instrument_setting_param; } else if (record_code==TECHNOLOGICAL_PARAMETERS) { techno_param=new TechnologicalParametersRecord(); return techno_param; } else if (record_code==DATA_PROCESSING_PARAMETERS) { data_processing_param=new DataProcessingParametersRecord(); return data_processing_param; } else if (record_code==SCALING_FACTORS) { scaling_factors=new ScalingFactorsRecord(); return scaling_factors; } else if (record_code==ANNOTATIONS) { annotations=new AnnotationsRecord(); return annotations; } else { cerr<<"In "<<__FILE__<<" at "<<__LINE__<<" : this record code "<(file_format->get_leader_file_descriptor_format()); LeaderFileDescriptorRecord *rec = leader_file_descriptor; RecordFormat::iterator entry = rec_format->begin(); if (rec!=NULL) { cout<<"****************** LEADER FILE DESCRIPTOR *******************"<name<<" "<rec_nb<name<<" "<rec_len<name<<" "<ref_doc_id<name<<" "<ref_doc_version<name<<" "<soft_version<name<<" "<file_nb<name<<" "<filename<name<<" "<nb_header_rec<name<<" "<header_rec_len<name<<" "<nb_spatio_temp_char_rec<name<<" "<spatio_temp_char_rec_len<name<<" "<nb_instr_setting_param_rec<name<<" "<instr_setting_param_rec_len<name<<" "<nb_tech_param_rec<name<<" "<tech_param_rec_len<name<<" "<nb_data_proc_param_rec<name<<" "<data_proc_param_rec_len<name<<" "<nb_scaling_factor_rec<name<<" "<scaling_factor_rec_len<name<<" "<nb_annot_rec<name<<" "<annot_rec_len<(file_format->get_spatio_temporal_characteristics_format()); RecordFormat::iterator entry = rec_format->begin(); cout<<"************** SPATIO-TEMPORAL CHARACTERISTICS **************"<name<<" "<rec_nb<name<<" "<rec_len<name<<" "<cycle_nb<name<<" "<orbit_nb<name<<" "<subsat_track_nb<name<<" "<desc_node_lon<name<<" "<desc_node_date<name<<" "<first_acq_date<name<<" "<last_acq_date<name<<" "<nb_seq<name<<" "<line_nb_northern_pix<name<<" "<line_nb_southern_pix<(file_format->get_header_format()); RecordFormat::iterator entry = rec_format->begin(); cout<<"************************** HEADER ***************************"<name<<" "<rec_nb<name<<" "<rec_len<name<<" "<phone_nb<name<<" "<product_id<name<<" "<sat_id<name<<" "<instr_id<name<<" "<spatial_cover<name<<" "<pix_size<name<<" "<ellips_name<name<<" "<ellips_minor_axis_len<name<<" "<ellips_major_axis_len<name<<" "<DEM_name<name<<" "<DEM_spatial_res_lat<name<<" "<DEM_spatial_res_lon<(file_format->get_scaling_factors_format()); RecordFormat::iterator entry = rec_format->begin(); cout<<"************************** SCALING FACTORS ***************************"<name<<" "<rec_nb<name<<" "<rec_len<name<<" "<interleave_id<name<<" "<byte_order<name<<" "<nb_pix_param<name<<" "<nb_pix_bytes<nb_pix_param); for (uint i=0;i nb_bytes *"<nb_bytes[i]<<"*\t slope *"<slope[i]<<"*\t offset *"<offset[i]<<"*"<(file_format->get_technological_parameters_format()); RecordFormat::iterator entry = rec_format->begin(); cout<<"************************** TECHNOLOGICAL PARAMETERS ***************************"<name<<" "<rec_nb<name<<" "<rec_len<name<<" "<seq_nb<name<<" "<intern_lens_temp<name<<" "<extern_lens_temp<name<<" "<short_acq_time_duration<name<<" "<long_acq_time_duration<name<<" "<<(rec->img_nb)[i_seq][i_img]<name<<" "<<(rec->time_acq)[i_seq][i_img]<name<<" "<<(rec->x_sat)[i_seq][i_img]<name<<" "<<(rec->y_sat)[i_seq][i_img]<name<<" "<<(rec->z_sat)[i_seq][i_img]<name<<" "<<(rec->vx_sat)[i_seq][i_img]<name<<" "<<(rec->vy_sat)[i_seq][i_img]<name<<" "<<(rec->vz_sat)[i_seq][i_img]<name<<" "<<(rec->yaw_sat)[i_seq][i_img]<name<<" "<<(rec->pitch_sat)[i_seq][i_img]<name<<" "<<(rec->roll_sat)[i_seq][i_img]<rec_len; int i=HEADER; //int i=LEADER_FILE_DESCRIPTOR; while ( i!=ANNOTATIONS && i!=record_code ) { offset+=leader_file_descriptor->get_record_size(static_cast(i)); ++i; } if (i==ANNOTATIONS && record_code!=ANNOTATIONS) return -1; return offset; } } const RecordFormat* PARASOLLeader::get_record_format( const Record & record_code ) { // get the leader file format depending of the product level PARASOLLeaderFormat* leader_file_format=(PARASOLLeaderFormat*)(get_leader_file_format()); if (record_code==LEADER_FILE_DESCRIPTOR) return leader_file_format->get_leader_file_descriptor_format(); else if (record_code==HEADER) return leader_file_format->get_header_format(); else if (record_code==SPATIO_TEMPORAL_CHARACTERISTICS) return leader_file_format->get_spatio_temporal_characteristics_format(); else if (record_code==INSTRUMENT_SETTING_PARAMETERS) return leader_file_format->get_instrument_setting_parameters_format(); else if (record_code==TECHNOLOGICAL_PARAMETERS) return leader_file_format->get_technological_parameters_format(); else if (record_code==DATA_PROCESSING_PARAMETERS) return leader_file_format->get_data_processing_parameters_format(); else if (record_code==SCALING_FACTORS) return leader_file_format->get_scaling_factors_format(); else if (record_code==ANNOTATIONS) return leader_file_format->get_annotations_format(); else { string msg ( "Record code " + MyTools::to_string(record_code) + " hasn't been implemented yet" ) ; g_exception e( __FILE__ , __LINE__ , msg ); throw e; return NULL; } } PARASOLFileRecord* PARASOLLeader::get_record( const Record & record_code ) { if (record_code==LEADER_FILE_DESCRIPTOR) return leader_file_descriptor; else if (record_code==HEADER) return header; else if (record_code==SPATIO_TEMPORAL_CHARACTERISTICS) return spatio_temp_char; else if (record_code==INSTRUMENT_SETTING_PARAMETERS) return instrument_setting_param; else if (record_code==TECHNOLOGICAL_PARAMETERS) return techno_param; else if (record_code==DATA_PROCESSING_PARAMETERS) return data_processing_param; else if (record_code==SCALING_FACTORS) return scaling_factors; else if (record_code==ANNOTATIONS) return annotations; else { string msg ( "Record code " + MyTools::to_string(record_code) + " hasn't been implemented yet" ) ; g_exception e( __FILE__ , __LINE__ , msg ); throw e; return NULL; } } void PARASOLLeader::free_record(const Record & rec_id) { switch (rec_id) { case LEADER_FILE_DESCRIPTOR: delete leader_file_descriptor, leader_file_descriptor = NULL; break; case HEADER: delete header, header = NULL; break; case SPATIO_TEMPORAL_CHARACTERISTICS: delete spatio_temp_char, spatio_temp_char = NULL; break; case INSTRUMENT_SETTING_PARAMETERS: delete instrument_setting_param, instrument_setting_param = NULL; break; case TECHNOLOGICAL_PARAMETERS: delete techno_param, techno_param = NULL; break; case DATA_PROCESSING_PARAMETERS: delete data_processing_param, data_processing_param = NULL; break; case SCALING_FACTORS: delete scaling_factors, scaling_factors = NULL; break; case ANNOTATIONS: delete annotations, annotations = NULL; break; default : string msg ( "Invalid Record ID " + MyTools::to_string(rec_id)) ; g_exception e( __FILE__ , __LINE__ , msg ); throw e; break; } } // const int PARASOLLeader::get_entry_offset( const Record rec, const int entry_idx, const int group_idx, const int subgroup_idx, const int val_index ) { // assert(entry_idx>=0); // // // the offset of the entry from the current record start // EntryFormat format = (*get_record_format(rec))[entry_idx]; // int entry_offset=format.pos-1; // -1 because start position are given from 1 in the DPC (and so on in the format) and in this code offsets are treated from 0 // int grp_size=get_entry_group_size(rec,entry_idx); // if (grp_size>1) { // // the entry is in a group // entry_offset+=group_idx*grp_size; // } // /* // If the entry is in a group that is repeated many times in a record (directionnal parameters), we need to know the size of this group. // If the entry isn't in a group, the get_entry_group_size method will return 0, and this additional group offset will be ignored // */ // return entry_offset; // } vector< EntryBlock > PARASOLLeader::get_entry_block(const Record rec, const int entry_idx) const { int level = PARASOLFileFormat::get_level(product); // level of the loaded file if (level < 1 || level > 3) { string msg ( "Unexpected Product Level " + MyTools::to_string(level) ) ; g_exception e( __FILE__ , __LINE__ , msg ); throw e; } int ntime; vector< EntryBlock > v_out (0); if (rec == LEADER_FILE_DESCRIPTOR || rec == HEADER || rec == INSTRUMENT_SETTING_PARAMETERS || rec == DATA_PROCESSING_PARAMETERS ) return v_out; // no entry group for those records /*********** SPATIO_TEMPORAL_CHARACTERISTICS **************/ if (rec == SPATIO_TEMPORAL_CHARACTERISTICS) { switch (level) { case 1 : if (entry_idx >= 17 && entry_idx <= 18) // entries #17 and 18 (nadir line and col numbers) 130 repetations (sequences) of 8 bytes v_out.push_back (EntryBlock (130, 8)); break; case 2 : // no group for level 2 values break; case 3 : g_exception e( __FILE__ , __LINE__ , "Method not implemented for L3 products" ); throw e; break; } } /*********** TECHNOLOGICAL_PARAMETERS **************/ if (rec == TECHNOLOGICAL_PARAMETERS) { switch (level) { case 1 : if (entry_idx >= 2 && entry_idx <= 6) // sequences block : 130 repeatitions of 1278 bytes v_out.push_back (EntryBlock (130, 1278)); else if (entry_idx >= 7 && entry_idx <= 17) //--- made of 2 repeated block : 130 sequences of 8 images // sequences block : 130 repeatitions of 1278 bytes v_out.push_back (EntryBlock (130, 1278)); // images block : 9 repeatitions of 138 bytes v_out.push_back (EntryBlock (9, 138)); break; case 2 : // no techno params for L2 and L3 case 3 : break; } } /*********** SCALING_FACTORS **************/ if (rec == SCALING_FACTORS) { switch (level) { case 1 : case 2 : if (entry_idx>=6 && entry_idx<=8) // entries 6, 7, 8 (nbytes, slope, offset) : nb_param repetations (sequences) of 26 bytes v_out.push_back (EntryBlock (MyTools::string2int(this->scaling_factors->nb_pix_param), 26)); break; case 3 : g_exception e( __FILE__ , __LINE__ , "Method not implemented for L3 products" ); throw e; break; } } /*********** ANNOTATIONS **************/ if (rec == ANNOTATIONS) { switch (level) { case 1 : case 2 : if (entry_idx == 7) // percent of cloudy pixels by 10 degrees latitude band : 18 repetations (sequences) of 4 bytes v_out.push_back (EntryBlock (18, 4)); else if (entry_idx == 9) { // number of pixels by line : nlines repetations (sequences) of 4 bytes. nlines depends of the product if (product == BASIC_1 || product == LS_SURF_DIR_2 || product == OC_SURF_DIR_2 || product == OC_SURF_NON_DIR_2 ) ntime = 3240; // full resolution products else if (product == LS_SURF_DIR_2 || product == LS_AEROSOL_2 || product == OC_AEROSOL_2 ) ntime = 1080; // medium resolution products v_out.push_back (EntryBlock (ntime, 4)); } break; case 3 : g_exception e( __FILE__ , __LINE__ , "Method not implemented for L3 products" ); throw e; break; } } return v_out; } // const int PARASOLLeader::get_entry_group_size( const Record rec, const int entry_idx ) { // int level = PARASOLFileFormat::get_level(product); // level of the loaded file // if (level < 1 || level > 3) { // string msg ( "Unexpected Product Level " + MyTools::to_string(level) ) ; // g_exception e( __FILE__ , __LINE__ , msg ); // throw e; // } // // if (rec == LEADER_FILE_DESCRIPTOR || // rec == HEADER || // rec == INSTRUMENT_SETTING_PARAMETERS || // rec == DATA_PROCESSING_PARAMETERS ) // return 0; // no entry group for those records // // /*********** SPATIO_TEMPORAL_CHARACTERISTICS **************/ // if (rec == SPATIO_TEMPORAL_CHARACTERISTICS) { // switch (level) { // case 1 : // if (entry_idx < 17) // return 0; // else if (entry_idx >= 17 && entry_idx <= 18) // return 8; // else { // shouldn't be the case : the last entry is the 3rd Component Stokes Vector for channel 865P at index 33 // bad_parametre_idx e(entry_idx); // throw e; // } // break; // case 2 : // return 0; // no group for level 2 values // break; // case 3 : // string msg ( "Method not implemented for L3 products" ) ; // g_exception e( __FILE__ , __LINE__ , msg ); // throw e; // break; // } // } // // /*********** TECHNOLOGICAL_PARAMETERS **************/ // if (rec == TECHNOLOGICAL_PARAMETERS) { // switch (level) { // case 1 : // if (entry_idx < 7) // return 1; // else if (entry_idx >= 7 && entry_idx <= 95) // // all images data considered as separate variables (138 bytes per image ; 8 images -> 138 * 8 = 1104) // return 1104; // else { // shouldn't be the case : the last entry is the 3rd Component Stokes Vector for channel 865P at index 33 // bad_parametre_idx e(entry_idx); // throw e; // } // break; // case 2 : // no group for level 2 values // return 1; // break; // case 3 : // no group for level 2 values // string msg ( "Method not implemented for L3 products" ) ; // g_exception e( __FILE__ , __LINE__ , msg ); // throw e; // break; // } // } // // /*********** SCALING_FACTORS **************/ // if (rec==SCALING_FACTORS) { // //----- L1 OR L2 PRODUCTS -----// // if (level==1 || level==2) { // if (entry_idx<6) return 0; // else if (entry_idx>=6 && entry_idx<=8) return 26; // else { // shouldn't be the case : the last entry is the 3rd Component Stokes Vector for channel 865P at index 33 // bad_parametre_idx e(entry_idx); // throw e; // } // } // //----- L3 PRODUCTS -----// // else if (level==3) { // string msg ( "Method not implemented for L3 products" ) ; // g_exception e( __FILE__ , __LINE__ , msg ); // throw e; // } // } // // /*********** ANNOTATIONS **************/ // if (rec==ANNOTATIONS) { // //----- L1 OR L2 PRODUCTS -----// // if (level==1 || level==2) { // if (entry_idx<7) return 0; // else if (entry_idx==7) return 4; // else if (entry_idx==9) return 4; // else { // shouldn't be the case : the last entry is the 3rd Component Stokes Vector for channel 865P at index 33 // bad_parametre_idx e(entry_idx); // throw e; // } // } // //----- L3 PRODUCTS -----// // else if (level==3) { // string msg ( "Method not implemented for L3 products" ) ; // g_exception e( __FILE__ , __LINE__ , msg ); // throw e; // } // } // return 0; // } // // const int PARASOLLeader::get_entry_group_nb_val( const Record rec, const int entry_idx ) const { // int level=PARASOLFileFormat::get_level(product); // level of the loaded file // if (level < 1 || level > 3) { // string msg ( "Unexpected Product Level " + MyTools::to_string(level) ) ; // g_exception e( __FILE__ , __LINE__ , msg ); // throw e; // } // // if (rec == LEADER_FILE_DESCRIPTOR || // rec == HEADER || // rec == INSTRUMENT_SETTING_PARAMETERS || // rec == DATA_PROCESSING_PARAMETERS) // return 1; // no entry group for those records // // /*********** SPATIO_TEMPORAL_CHARACTERISTICS **************/ // if (rec == SPATIO_TEMPORAL_CHARACTERISTICS) { // switch (level) { // case 1 : // if (entry_idx < 17) // return 1; // else if (entry_idx >= 17 && entry_idx <= 18) // return 129; // else { // shouldn't be the case : the last entry is the 3rd Component Stokes Vector for channel 865P at index 33 // bad_parametre_idx e(entry_idx); // throw e; // } // break; // case 2 : // no group for level 2 values // return 1; // break; // case 3 : // no group for level 2 values // string msg ( "Method not implemented for L3 products" ) ; // g_exception e( __FILE__ , __LINE__ , msg ); // throw e; // break; // } // } // // /*********** TECHNOLOGICAL_PARAMETERS **************/ // if (rec == TECHNOLOGICAL_PARAMETERS) { // switch (level) { // case 1 : // if (entry_idx < 7) // return 1; // else if (entry_idx >= 7 && entry_idx <= 95) // return 129; // else { // shouldn't be the case : the last entry is the 3rd Component Stokes Vector for channel 865P at index 33 // bad_parametre_idx e(entry_idx); // throw e; // } // break; // case 2 : // no group for level 2 values // return 1; // break; // case 3 : // no group for level 2 values // string msg ( "Method not implemented for L3 products" ) ; // g_exception e( __FILE__ , __LINE__ , msg ); // throw e; // break; // } // } // // /*********** SCALING_FACTORS **************/ // if (rec == SCALING_FACTORS) { // //----- L1 OR L2 PRODUCTS -----// // if (level==1 || level==2) { // if (entry_idx<6) // return 1; // else if (entry_idx>=6 && entry_idx<=8) { // return MyTools::string2int(this->scaling_factors->nb_pix_param); // } else { // shouldn't be the case : the last entry is the 3rd Component Stokes Vector for channel 865P at index 33 // bad_parametre_idx e(entry_idx); // throw e; // } // } // //----- L3 PRODUCTS -----// // else if (level==3) { // string msg ( "Method not implemented for L3 products" ) ; // g_exception e( __FILE__ , __LINE__ , msg ); // throw e; // } // } // // /*********** ANNOTATIONS **************/ // if (rec == ANNOTATIONS) { // if (level==1) { // if (entry_idx < 7) // return 1; // else if (entry_idx == 7) // return 18; // else if (entry_idx == 9) // return 3240; // else { // shouldn't be the case : the last entry is the 3rd Component Stokes Vector for channel 865P at index 33 // bad_parametre_idx e(entry_idx); // throw e; // } // } else if (level==2) { // if (entry_idx<7) // return 1; // else if (entry_idx==7) // return 18; // else if (entry_idx==9) { // if (product == LS_SURF_DIR_2 || // product==OC_SURF_DIR_2 || // product==OC_SURF_NON_DIR_2 ) // return 3240; // full resolution products // else if (product==LS_SURF_DIR_2 || // product==LS_AEROSOL_2 || // product==OC_AEROSOL_2 ) // return 1080; // medium resolution products // else { // shouldn't be the case : the last entry is the 3rd Component Stokes Vector for channel 865P at index 33 // bad_parametre_idx e(entry_idx); // throw e; // } // } else { // shouldn't be the case : the last entry is the 3rd Component Stokes Vector for channel 865P at index 33 // bad_parametre_idx e(entry_idx); // throw e; // } // } else if (level==3) { // string msg ( "Method not implemented for L3 products" ) ; // g_exception e( __FILE__ , __LINE__ , msg ); // throw e; // } // } // // return 1; // }