/*************************************************************************** * 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 nc_file program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "ecmwffiledata.h" #include "hdffiledata.h" #include "meteofiledata.h" #include "tools.h" #include "file_tools.h" const double ECMWFFileData::a_hybrid_91[] = {0.000000, 2.000040, 3.980832, 7.387186, 12.908319, 21.413612, 33.952858, 51.746601, 76.167656, 108.715561, 150.986023, 204.637451, 271.356506, 352.824493, 450.685791, 566.519226, 701.813354, 857.945801, 1036.166504, 1237.585449, 1463.163940, 1713.709595, 1989.874390, 2292.155518, 2620.898438, 2976.302246, 3358.425781, 3767.196045, 4202.416504, 4663.776367, 5150.859863, 5663.156250, 6199.839355, 6759.727051, 7341.469727, 7942.926270, 8564.624023, 9208.305664, 9873.560547, 10558.881836, 11262.484375, 11982.662109, 12713.897461, 13453.225586, 14192.009766, 14922.685547, 15638.053711, 16329.560547, 16990.623047, 17613.281250, 18191.029297, 18716.968750, 19184.544922, 19587.513672, 19919.796875, 20175.394531, 20348.916016, 20434.158203, 20426.218750, 20319.011719, 20107.031250, 19785.357422, 19348.775391, 18798.822266, 18141.296875, 17385.595703, 16544.585938, 15633.566406, 14665.645508, 13653.219727, 12608.383789, 11543.166992, 10471.310547, 9405.222656, 8356.252930, 7335.164551, 6353.920898, 5422.802734, 4550.215820, 3743.464355, 3010.146973, 2356.202637, 1784.854614, 1297.656128, 895.193542, 576.314148, 336.772369, 162.043427, 54.208336, 6.575628, 0.003160, 0.000000}; const double ECMWFFileData::b_hybrid_91[] = {0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000014, 0.000055, 0.000131, 0.000279, 0.000548, 0.001000, 0.001701, 0.002765, 0.004267, 0.006322, 0.009035, 0.012508, 0.016860, 0.022189, 0.028610, 0.036227, 0.045146, 0.055474, 0.067316, 0.080777, 0.095964, 0.112979, 0.131935, 0.152934, 0.176091, 0.201520, 0.229315, 0.259554, 0.291993, 0.326329, 0.362203, 0.399205, 0.436906, 0.475016, 0.513280, 0.551458, 0.589317, 0.626559, 0.662934, 0.698224, 0.732224, 0.764679, 0.795385, 0.824185, 0.850950, 0.875518, 0.897767, 0.917651, 0.935157, 0.950274, 0.963007, 0.973466, 0.982238, 0.989153, 0.994204, 0.997630, 1.000000}; const int ECMWFFileData::nb_level_hybrid_91 = 91; const unsigned short ECMWFFileData::isobaric_level_pressures[] = { 1000, 950, 925, 900, 850, 800, 700, 600, 500, 400, 300, 250, 200, 150, 100, 70, 50, 30, 20, 10, 7, 5, 3, 2, 1, 0 }; const int ECMWFFileData::nb_max_isobaric_level = 26; ECMWFFileData::ECMWFFileData(const string &name /*= ""*/, const string &mode/*= "r"*/) :FileData(name, mode), MeteoFileData(name, mode), GribFileData(name, mode, true), FileDataReader(name, mode) { product_id = UNDEFINED; version = ""; delta_lat = 0.; delta_lon = 0.; delta_time = 0.; // only one time level is used in ECMWF GRIB file => not applicable time_coverage = 0.; // parse the file name to extract some informations parse_filename(get_tail(name)); // read grid characteristics init_grid(); close_data_file(); } ECMWFFileData::~ECMWFFileData() { } const vector ECMWFFileData::get_pressure_levels(const string & var_name) { const t_grib_var_desc var_desc = get_dataset_desc (var_name); return var_desc.v_lvl; } const int ECMWFFileData::get_nb_pressure_levels(const string & var_name) { const t_grib_var_desc var_desc = get_dataset_desc (var_name); return var_desc.v_lvl.size(); } void ECMWFFileData::init_grid() { // first message should contain all requested keys sz_y = MyTools::to_num (get_msg_key (0, "Nj")); sz_x = MyTools::to_num (get_msg_key (0, "Ni")); lat0 = MyTools::to_num (get_msg_key (0, "latitudeOfFirstGridPointInDegrees")); lon0 = MyTools::to_num (get_msg_key (0, "longitudeOfFirstGridPointInDegrees")); delta_lat = MyTools::to_num (get_msg_key (0, "jDirectionIncrementInDegrees")); delta_lon = MyTools::to_num (get_msg_key (0, "iDirectionIncrementInDegrees")); } const string ECMWFFileData::get_grid_desc() { string s (""); s += "Size : [" + MyTools::to_string (sz_y) + "," + MyTools::to_string (sz_x) + "]\n"; s += "Origin : [" + MyTools::to_string (lat0) + "," + MyTools::to_string (lon0) + "]\n"; s += "Resolution : [" + MyTools::to_string (delta_lat) + "," + MyTools::to_string (delta_lon) + "]\n"; return s; } void ECMWFFileData::parse_filename( const string& fname ) { check_filename(fname); // set acquisition start time string s_date = fname.substr(6, 12)+"00"; date->set_date_str(s_date.c_str(),"%Y%m%d%H%M%S"); // acquisition duration : 6 hours time_coverage = 6 * 3600; // product version version = fname.substr(20, 5); // Product type size_t p = fname.find_first_of("_", 25); p = fname.find_first_of("_", p + 1); string s_prod = fname.substr(p + 1, 2); if (s_prod == "AN") product_id = ANALYSIS; else if (s_prod == "FC") product_id = FORECAST; else { g_exception e(__FILE__ , __LINE__ , "Invalid product type ID " + s_prod); throw e; } // Forecast production date should be parsed here } bool ECMWFFileData::check_filename( const string & filename ) const { if (filename.substr(0, 6) != "ECMWF_") { invalid_filename e(__FILE__, __LINE__, filename, "ECMWF"); throw e; } int pos = 6; for (pos = 6 ; pos < 18 ; ++pos) { if (!isdigit (filename[pos])) { invalid_filename e(__FILE__, __LINE__, filename, "ECMWF"); throw e; } } if (filename.substr(pos, 2) != "_v") { invalid_filename e(__FILE__, __LINE__, filename, "ECMWF"); throw e; } pos += 2; if (!isdigit (filename[pos])) { invalid_filename e(__FILE__, __LINE__, filename, "ECMWF"); throw e; } ++pos; if (filename[pos] != '.') { invalid_filename e(__FILE__, __LINE__, filename, "ECMWF"); throw e; } ++pos; if (!isdigit (filename[pos])) { invalid_filename e(__FILE__, __LINE__, filename, "ECMWF"); throw e; } ++pos; if (filename[pos] != '.') { invalid_filename e(__FILE__, __LINE__, filename, "ECMWF"); throw e; } ++pos; if (!isdigit (filename[pos])) { invalid_filename e(__FILE__, __LINE__, filename, "ECMWF"); throw e; } ++pos; if (filename.substr(pos, 6) != "_1deg_") { invalid_filename e(__FILE__, __LINE__, filename, "ECMWF"); throw e; } pos += 6; if (filename.substr(pos, 2) != "AN" && filename.substr(pos, 2) != "FC") { invalid_filename e(__FILE__, __LINE__, filename, "ECMWF"); throw e; } return true; } void ECMWFFileData::close_data_file() { GribFileData::close_data_file(); } void ECMWFFileData::open_data_file() { GribFileData::open_data_file(); } // vector ECMWFFileData::get_dataset_dimension(const string & sds_name) { // throw UnimplementedMethod (__FILE__,__LINE__,__PRETTY_FUNCTION__); // } // void ECMWFFileData::get_dataset_fill_value(const string & name, void * fillvalue) { // throw UnimplementedMethod (__FILE__,__LINE__,__PRETTY_FUNCTION__); // } int ECMWFFileData::get_n_dataset() { return GribFileData::get_n_dataset(); } string ECMWFFileData::get_dataset_name(int i) { return GribFileData::get_dataset_name(i); } int ECMWFFileData::get_dataset_data_type(string sds_name) { throw UnimplementedMethod (__FILE__,__LINE__,__PRETTY_FUNCTION__); } string ECMWFFileData::get_values_attr_dataset(string sds_name, string attr) { throw UnimplementedMethod (__FILE__,__LINE__,__PRETTY_FUNCTION__); } bool ECMWFFileData::has_attr_dataset(string sds_name, string attr) { throw UnimplementedMethod (__FILE__,__LINE__,__PRETTY_FUNCTION__); }