LCOV - code coverage report
Current view: directory - frmts/grib/degrib18/degrib - metaname.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 432 77 17.8 %
Date: 2011-12-18 Functions: 14 7 50.0 %

       1                 : /*****************************************************************************
       2                 :  * metaname.c
       3                 :  *
       4                 :  * DESCRIPTION
       5                 :  *    This file contains the code necessary to parse the GRIB2 product
       6                 :  * definition information into human readable text.  In addition to the
       7                 :  * tables in the GRIB2 specs, it also attempts to handle local table
       8                 :  * definitions that NCEP and NDFD have developed.
       9                 :  *
      10                 :  * HISTORY
      11                 :  *    1/2004 Arthur Taylor (MDL / RSIS): Created.
      12                 :  *
      13                 :  * NOTES
      14                 :  *****************************************************************************
      15                 :  */
      16                 : #include <string.h>
      17                 : #include <stdlib.h>
      18                 : #include "meta.h"
      19                 : #include "metaname.h"
      20                 : #include "myerror.h"
      21                 : #include "myassert.h"
      22                 : #include "myutil.h"
      23                 : 
      24               0 : const char *centerLookup (unsigned short int center)
      25                 : {
      26                 :    /* see:
      27                 :     * http://www.wmo.ch/web/www/WMOCodes/Operational/CommonTables/BUFRCommon-2005feb.pdf
      28                 :     * http://www.wmo.int/web/www/WMOCodes/Operational/CommonTables/BUFRCommon-2005nov.pdf
      29                 :     * also see:
      30                 :     * http://www.nco.ncep.noaa.gov/pmb/docs/on388/table0.html 
      31                 :     * I typed this in on 11/2/2006 */
      32                 : /* *INDENT-OFF* */
      33                 :    static struct {
      34                 :       unsigned short int num;
      35                 :       const char *name;
      36                 :    } Center[] = {
      37                 :       {0, "WMO Secretariat"},
      38                 :       {1, "Melbourne"},
      39                 :       {2, "Melbourne"},
      40                 :       {3, ") Melbourne"},
      41                 :       {4, "Moscow"},
      42                 :       {5, "Moscow"},
      43                 :       {6, ") Moscow"},
      44                 :       {7, "US-NCEP"},
      45                 :       {8, "US-NWSTG"},
      46                 :       {9, "US-Other"},
      47                 :       {10, "Cairo"},
      48                 :       {11, ") Cairo"},
      49                 :       {12, "Dakar"},
      50                 :       {13, ") Dakar"},
      51                 :       {14, "Nairobi"},
      52                 :       {15, ") Nairobi"},
      53                 :       {16, "Casablanca"},
      54                 :       {17, "Tunis"},
      55                 :       {18, "Tunis Casablanca"},
      56                 :       {19, ") Tunis Casablanca"},
      57                 :       {20, "Las Palmas"},
      58                 :       {21, "Algiers"},
      59                 :       {22, "ACMAD"},
      60                 :       {23, "Mozambique"},
      61                 :       {24, "Pretoria"},
      62                 :       {25, "La Réunion"},
      63                 :       {26, "Khabarovsk"},
      64                 :       {27, ") Khabarovsk"},
      65                 :       {28, "New Delhi"},
      66                 :       {29, ") New Delhi"},
      67                 :       {30, "Novosibirsk"},
      68                 :       {31, ") Novosibirsk"},
      69                 :       {32, "Tashkent"},
      70                 :       {33, "Jeddah"},
      71                 :       {34, "Tokyo"},
      72                 :       {35, ") Tokyo"},
      73                 :       {36, "Bangkok"},
      74                 :       {37, "Ulan Bator"},
      75                 :       {38, "Beijing"},
      76                 :       {39, ") Beijing"},
      77                 :       {40, "Seoul"},
      78                 :       {41, "Buenos Aires"},
      79                 :       {42, ") Buenos Aires"},
      80                 :       {43, "Brasilia"},
      81                 :       {44, ") Brasilia"},
      82                 :       {45, "Santiago"},
      83                 :       {46, "Brazilian Space Agency"},
      84                 :       {47, "Colombia"},
      85                 :       {48, "Ecuador"},
      86                 :       {49, "Peru"},
      87                 :       {50, "Venezuela"},
      88                 :       {51, "Miami"},
      89                 :       {52, "Miami-NHC"},
      90                 :       {53, "Montreal"},
      91                 :       {54, ") Montreal"},
      92                 :       {55, "San Francisco"},
      93                 :       {56, "ARINC Centre"},
      94                 :       {57, "US-Air Force Weather"},
      95                 :       {58, "US-Fleet Meteorology and Oceanography"},
      96                 :       {59, "US-FSL"},
      97                 :       {60, "US-NCAR"},
      98                 :       {61, "US-Service ARGOS"},
      99                 :       {62, "US-Naval Oceanographic Office"},
     100                 : /*      {63, "Reserved for another centre in Region IV"},*/
     101                 :       {64, "Honolulu"},
     102                 :       {65, "Darwin"},
     103                 :       {66, ") Darwin"},
     104                 :       {67, "Melbourne"},
     105                 : /*      {68, "Reserved"},*/
     106                 :       {69, "Wellington"},
     107                 :       {70, ") Wellington"},
     108                 :       {71, "Nadi"},
     109                 :       {72, "Singapore"},
     110                 :       {73, "Malaysia"},
     111                 :       {74, "UK-Met-Exeter"},
     112                 :       {75, ") UK-Met-Exeter"},
     113                 :       {76, "Moscow"},
     114                 : /*      {77, "Reserved"},*/
     115                 :       {78, "Offenbach"},
     116                 :       {79, ") Offenbach"},
     117                 :       {80, "Rome"},
     118                 :       {81, ") Rome"},
     119                 :       {82, "Norrköping"},
     120                 :       {83, ") Norrköping"},
     121                 :       {84, "Toulouse"},
     122                 :       {85, "Toulouse"},
     123                 :       {86, "Helsinki"},
     124                 :       {87, "Belgrade"},
     125                 :       {88, "Oslo"},
     126                 :       {89, "Prague"},
     127                 :       {90, "Episkopi"},
     128                 :       {91, "Ankara"},
     129                 :       {92, "Frankfurt/Main"},
     130                 :       {93, "London"},
     131                 :       {94, "Copenhagen"},
     132                 :       {95, "Rota"},
     133                 :       {96, "Athens"},
     134                 :       {97, "ESA-European Space Agency"},
     135                 :       {98, "ECMWF"},
     136                 :       {99, "DeBilt"},
     137                 :       {100, "Brazzaville"},
     138                 :       {101, "Abidjan"},
     139                 :       {102, "Libyan Arab Jamahiriya"},
     140                 :       {103, "Madagascar"},
     141                 :       {104, "Mauritius"},
     142                 :       {105, "Niger"},
     143                 :       {106, "Seychelles"},
     144                 :       {107, "Uganda"},
     145                 :       {108, "Tanzania"},
     146                 :       {109, "Zimbabwe"},
     147                 :       {110, "Hong-Kong, China"},
     148                 :       {111, "Afghanistan"},
     149                 :       {112, "Bahrain"},
     150                 :       {113, "Bangladesh"},
     151                 :       {114, "Bhutan"},
     152                 :       {115, "Cambodia"},
     153                 :       {116, "Democratic People's Republic of Korea"},
     154                 :       {117, "Islamic Republic of Iran"},
     155                 :       {118, "Iraq"},
     156                 :       {119, "Kazakhstan"},
     157                 :       {120, "Kuwait"},
     158                 :       {121, "Kyrgyz Republic"},
     159                 :       {122, "Lao People's Democratic Republic"},
     160                 :       {123, "Macao, China"},
     161                 :       {124, "Maldives"},
     162                 :       {125, "Myanmar"},
     163                 :       {126, "Nepal"},
     164                 :       {127, "Oman"},
     165                 :       {128, "Pakistan"},
     166                 :       {129, "Qatar"},
     167                 :       {130, "Republic of Yemen"},
     168                 :       {131, "Sri Lanka"},
     169                 :       {132, "Tajikistan"},
     170                 :       {133, "Turkmenistan"},
     171                 :       {134, "United Arab Emirates"},
     172                 :       {135, "Uzbekistan"},
     173                 :       {136, "Socialist Republic of Viet Nam"},
     174                 : /*      {137, "Reserved"},*/
     175                 : /*      {138, "Reserved"},*/
     176                 : /*      {139, "Reserved"},*/
     177                 :       {140, "Bolivia"},
     178                 :       {141, "Guyana"},
     179                 :       {142, "Paraguay"},
     180                 :       {143, "Suriname"},
     181                 :       {144, "Uruguay"},
     182                 :       {145, "French Guyana"},
     183                 :       {146, "Brazilian Navy Hydrographic Centre"},
     184                 : /*      {147, "Reserved"},*/
     185                 : /*      {148, "Reserved"},*/
     186                 : /*      {149, "Reserved"},*/
     187                 :       {150, "Antigua and Barbuda"},
     188                 :       {151, "Bahamas"},
     189                 :       {152, "Barbados"},
     190                 :       {153, "Belize"},
     191                 :       {154, "British Caribbean Territories"},
     192                 :       {155, "San Jose"},
     193                 :       {156, "Cuba"},
     194                 :       {157, "Dominica"},
     195                 :       {158, "Dominican Republic"},
     196                 :       {159, "El Salvador"},
     197                 :       {160, "US-NESDIS"},
     198                 :       {161, "US-OAR"},
     199                 :       {162, "Guatemala"},
     200                 :       {163, "Haiti"},
     201                 :       {164, "Honduras"},
     202                 :       {165, "Jamaica"},
     203                 :       {166, "Mexico"},
     204                 :       {167, "Netherlands Antilles and Aruba"},
     205                 :       {168, "Nicaragua"},
     206                 :       {169, "Panama"},
     207                 :       {170, "Saint Lucia NMC"},
     208                 :       {171, "Trinidad and Tobago"},
     209                 :       {172, "French Departments"},
     210                 : /*      {173, "Reserved"},*/
     211                 : /*      {174, "Reserved"},*/
     212                 : /*      {175, "Reserved"},*/
     213                 : /*      {176, "Reserved"},*/
     214                 : /*      {177, "Reserved"},*/
     215                 : /*      {178, "Reserved"},*/
     216                 : /*      {179, "Reserved"},*/
     217                 : /*      {180, "Reserved"},*/
     218                 : /*      {181, "Reserved"},*/
     219                 : /*      {182, "Reserved"},*/
     220                 : /*      {183, "Reserved"},*/
     221                 : /*      {184, "Reserved"},*/
     222                 : /*      {185, "Reserved"},*/
     223                 : /*      {186, "Reserved"},*/
     224                 : /*      {187, "Reserved"},*/
     225                 : /*      {188, "Reserved"},*/
     226                 : /*      {189, "Reserved"},*/
     227                 :       {190, "Cook Islands"},
     228                 :       {191, "French Polynesia"},
     229                 :       {192, "Tonga"},
     230                 :       {193, "Vanuatu"},
     231                 :       {194, "Brunei"},
     232                 :       {195, "Indonesia"},
     233                 :       {196, "Kiribati"},
     234                 :       {197, "Federated States of Micronesia"},
     235                 :       {198, "New Caledonia"},
     236                 :       {199, "Niue"},
     237                 :       {200, "Papua New Guinea"},
     238                 :       {201, "Philippines"},
     239                 :       {202, "Samoa"},
     240                 :       {203, "Solomon Islands"},
     241                 : /*      {204, "Reserved"},*/
     242                 : /*      {205, "Reserved"},*/
     243                 : /*      {206, "Reserved"},*/
     244                 : /*      {207, "Reserved"},*/
     245                 : /*      {208, "Reserved"},*/
     246                 : /*      {209, "Reserved"},*/
     247                 :       {210, "Frascati (ESA/ESRIN)"},
     248                 :       {211, "Lanion"},
     249                 :       {212, "Lisboa"},
     250                 :       {213, "Reykiavik"},
     251                 :       {214, "Madrid"},
     252                 :       {215, "Zürich"},
     253                 :       {216, "Service ARGOS Toulouse"},
     254                 :       {217, "Bratislava"},
     255                 :       {218, "Budapest"},
     256                 :       {219, "Ljubljana"},
     257                 :       {220, "Warsaw"},
     258                 :       {221, "Zagreb"},
     259                 :       {222, "Albania"},
     260                 :       {223, "Armenia"},
     261                 :       {224, "Austria"},
     262                 :       {225, "Azerbaijan"},
     263                 :       {226, "Belarus"},
     264                 :       {227, "Belgium"},
     265                 :       {228, "Bosnia and Herzegovina"},
     266                 :       {229, "Bulgaria"},
     267                 :       {230, "Cyprus"},
     268                 :       {231, "Estonia"},
     269                 :       {232, "Georgia"},
     270                 :       {233, "Dublin"},
     271                 :       {234, "Israel"},
     272                 :       {235, "Jordan"},
     273                 :       {236, "Latvia"},
     274                 :       {237, "Lebanon"},
     275                 :       {238, "Lithuania"},
     276                 :       {239, "Luxembourg"},
     277                 :       {240, "Malta"},
     278                 :       {241, "Monaco"},
     279                 :       {242, "Romania"},
     280                 :       {243, "Syrian Arab Republic"},
     281                 :       {244, "The former Yugoslav Republic of Macedonia"},
     282                 :       {245, "Ukraine"},
     283                 :       {246, "Republic of Moldova"},
     284                 : /*      {247, "Reserved"},*/
     285                 : /*      {248, "Reserved"},*/
     286                 : /*      {249, "Reserved"},*/
     287                 : /*      {250, "Reserved"},*/
     288                 : /*      {251, "Reserved"},*/
     289                 : /*      {252, "Reserved"},*/
     290                 : /*      {253, "Reserved"},*/
     291                 :       {254, "EUMETSAT Operation Centre"},
     292                 : /*      {255, "Reserved"},*/
     293                 :       {256, "Angola"},
     294                 :       {257, "Benin"},
     295                 :       {258, "Botswana"},
     296                 :       {259, "Burkina Faso"},
     297                 :       {260, "Burundi"},
     298                 :       {261, "Cameroon"},
     299                 :       {262, "Cape Verde"},
     300                 :       {263, "Central African republic"},
     301                 :       {264, "Chad"},
     302                 :       {265, "Comoros"},
     303                 :       {266, "Democratic Republic of the Congo"},
     304                 :       {267, "Djibouti"},
     305                 :       {268, "Eritrea"},
     306                 :       {269, "Ethiopia"},
     307                 :       {270, "Gabon"},
     308                 :       {271, "Gambia"},
     309                 :       {272, "Ghana"},
     310                 :       {273, "Guinea"},
     311                 :       {274, "Guinea Bissau"},
     312                 :       {275, "Lesotho"},
     313                 :       {276, "Liberia"},
     314                 :       {277, "Malawi"},
     315                 :       {278, "Mali"},
     316                 :       {279, "Mauritania"},
     317                 :       {280, "Namibia"},
     318                 :       {281, "Nigeria"},
     319                 :       {282, "Rwanda"},
     320                 :       {283, "Sao Tome and Principe"},
     321                 :       {284, "Sierra Leone"},
     322                 :       {285, "Somalia"},
     323                 :       {286, "Sudan"},
     324                 :       {287, "Swaziland"},
     325                 :       {288, "Togo"},
     326                 :       {289, "Zambia"}
     327                 :    };
     328                 : /* *INDENT-ON* */
     329               0 :    int numCenter = sizeof (Center) / sizeof (Center[0]);
     330                 :    int i;
     331                 : 
     332               0 :    for (i = 0; i < numCenter; i++) {
     333               0 :       if (Center[i].num == center) {
     334               0 :          return Center[i].name;
     335                 :       }
     336                 :    }
     337               0 :    return NULL;
     338                 : }
     339                 : 
     340               0 : const char *subCenterLookup(unsigned short int center,
     341                 :                             unsigned short int subcenter)
     342                 : {
     343                 : /* *INDENT-OFF* */
     344                 : /* see:
     345                 :  * http://www.wmo.ch/web/www/WMOCodes/Operational/CommonTables/
     346                 :  *        BUFRCommon-2005feb.pdf as of 10/12/2005
     347                 :  * http://www.nco.ncep.noaa.gov/pmb/docs/on388/tablec.html as of 11/9/2005
     348                 :  * http://www.ecmwf.int/publications/manuals/libraries/gribex/
     349                 :  *        localGRIBUsage.html as of 4/5/2006
     350                 :  */
     351                 :    static struct {
     352                 :       unsigned short int center, subcenter;
     353                 :       const char *name;
     354                 :    } SubCenter[] = {
     355                 :       {7, 1, "NCEP Re-Analysis Project"}, {7, 2, "NCEP Ensemble Products"},
     356                 :       {7, 3, "NCEP Central Operations"},
     357                 :       {7, 4, "Environmental Modeling Center"},
     358                 :       {7, 5, "Hydrometeorological Prediction Center"},
     359                 :       {7, 6, "Ocean Prediction Center"}, {7, 7, "Climate Prediction Center"},
     360                 :       {7, 8, "Aviation Weather Center"}, {7, 9, "Storm Prediction Center"},
     361                 :       {7, 10, "Tropical Prediction Center"},
     362                 :       {7, 11, "Techniques Development Laboratory"},
     363                 :       {7, 12, "NESDIS Office of Research and Applications"},
     364                 :       {7, 13, "FAA"},
     365                 :       {7, 14, "Meteorological Development Laboratory (MDL)"},
     366                 :       {7, 15, "North American Regional Reanalysis (NARR) Project"},
     367                 :       {7, 16, "Space Environment Center"},
     368                 :       {8, 0, "National Digital Forecast Database"},
     369                 : /*      {8, GRIB2MISSING_2, "National Digital Forecast Database"},*/
     370                 :       {161, 1, "Great Lakes Environmental Research Laboratory"},
     371                 :       {161, 2, "Forecast Systems Laboratory"},
     372                 :       {74, 1, "Shanwick Oceanic Area Control Centre"},
     373                 :       {74, 2, "Fucino"}, {74, 3, "Gatineau"}, {74, 4, "Maspalomas"},
     374                 :       {74, 5, "ESA ERS Central Facility"}, {74, 6, "Prince Albert"},
     375                 :       {74, 7, "West Freugh"}, {74, 13, "Tromso"},
     376                 :       {74, 21, "Agenzia Spaziale Italiana (Italy)"},
     377                 :       {74, 22, "Centre National de la Recherche Scientifique (France)"},
     378                 :       {74, 23, "GeoForschungsZentrum (Germany)"},
     379                 :       {74, 24, "Geodetic Observatory Pecny (Czech Republic)"},
     380                 :       {74, 25, "Institut d'Estudis Espacials de Catalunya (Spain)"},
     381                 :       {74, 26, "Swiss Federal Office of Topography"},
     382                 :       {74, 27, "Nordic Commission of Geodesy (Norway)"},
     383                 :       {74, 28, "Nordic Commission of Geodesy (Sweden)"},
     384                 :       {74, 29, "Institute de Geodesie National (France)"},
     385                 :       {74, 30, "Bundesamt für Kartographie und Geodäsie (Germany)"},
     386                 :       {74, 31, "Institute of Engineering Satellite Surveying and Geodesy (U.K.)"},
     387                 :       {254, 10, "Tromso (Norway)"}, {254, 10, "Maspalomas (Spain)"},
     388                 :       {254, 30, "Kangerlussuaq (Greenland)"}, {254, 40, "Edmonton (Canada)"},
     389                 :       {254, 50, "Bedford (Canada)"}, {254, 60, "Gander (Canada)"},
     390                 :       {254, 70, "Monterey (USA)"}, {254, 80, "Wallops Island (USA)"},
     391                 :       {254, 90, "Gilmor Creek (USA)"}, {254, 100, "Athens (Greece)"},
     392                 :       {98, 231, "CNRM, Meteo France Climate Centre (HIRETYCS)"},
     393                 :       {98, 232, "MPI, Max Planck Institute Climate Centre (HIRETYCS)"},
     394                 :       {98, 233, "UKMO Climate Centre (HIRETYCS)"},
     395                 :       {98, 234, "ECMWF (DEMETER)"},
     396                 :       {98, 235, "INGV-CNR (Bologna, Italy)(DEMETER)"},
     397                 :       {98, 236, "LODYC (Paris, France)(DEMETER)"},
     398                 :       {98, 237, "DMI (Copenhagen, Denmark)(DEMETER)"},
     399                 :       {98, 238, "INM (Madrid, Spain)(DEMETER)"},
     400                 :       {98, 239, "CERFACS (Toulouse, France)(DEMETER)"},
     401                 :       {98, 240, "ECMWF (PROVOST)"},
     402                 :       {98, 241, "Meteo France (PROVOST)"},
     403                 :       {98, 242, "EDF (PROVOST)"},
     404                 :       {98, 243, "UKMO (PROVOST)"},
     405                 :       {98, 244, "Biometeorology group, University of Veterinary Medicine, Vienna (ELDAS)"},
     406                 :    };
     407                 : /* *INDENT-ON* */
     408               0 :    int numSubCenter = sizeof (SubCenter) / sizeof (SubCenter[0]);
     409                 :    int i;
     410                 : 
     411               0 :    for (i = 0; i < numSubCenter; i++) {
     412               0 :       if ((SubCenter[i].center == center) &&
     413                 :           (SubCenter[i].subcenter == subcenter)) {
     414               0 :          return SubCenter[i].name;
     415                 :       }
     416                 :    }
     417               0 :    return NULL;
     418                 : }
     419                 : 
     420               0 : const char *processLookup (unsigned short int center, unsigned char process)
     421                 : {
     422                 :    /* see: http://www.nco.ncep.noaa.gov/pmb/docs/on388/tablea.html I typed
     423                 :     * this in on 10/12/2005 */
     424                 : /* *INDENT-OFF* */
     425                 :    static struct {
     426                 :       unsigned short int center;
     427                 :       unsigned char process;
     428                 :       const char *name;
     429                 :    } Process[] = {
     430                 :       {7, 2, "Ultra Violet Index Model"},
     431                 :       {7, 3, "NCEP/ARL Transport and Dispersion Model"},
     432                 :       {7, 4, "NCEP/ARL Smoke Model"},
     433                 :       {7, 5, "Satellite Derived Precipitation and temperatures, from IR"},
     434                 :       {7, 10, "Global Wind-Wave Forecast Model"},
     435                 :       {7, 19, "Limited-area Fine Mesh (LFM) analysis"},
     436                 :       {7, 25, "Snow Cover Analysis"},
     437                 :       {7, 30, "Forecaster generated field"},
     438                 :       {7, 31, "Value added post processed field"},
     439                 :       {7, 39, "Nested Grid forecast Model (NGM)"},
     440                 :       {7, 42, "Global Optimum Interpolation Analysis (GOI) from GFS model"},
     441                 :       {7, 43, "Global Optimum Interpolation Analysis (GOI) from 'Final' run"},
     442                 :       {7, 44, "Sea Surface Temperature Analysis"},
     443                 :       {7, 45, "Coastal Ocean Circulation Model"},
     444                 :       {7, 46, "HYCOM - Global"},
     445                 :       {7, 47, "HYCOM - North Pacific basin"},
     446                 :       {7, 48, "HYCOM - North Atlantic basin"},
     447                 :       {7, 49, "Ozone Analysis from TIROS Observations"},
     448                 :       {7, 52, "Ozone Analysis from Nimbus 7 Observations"},
     449                 :       {7, 53, "LFM-Fourth Order Forecast Model"},
     450                 :       {7, 64, "Regional Optimum Interpolation Analysis (ROI)"},
     451                 :       {7, 68, "80 wave triangular, 18-layer Spectral model from GFS model"},
     452                 :       {7, 69, "80 wave triangular, 18 layer Spectral model from 'Medium Range Forecast' run"},
     453                 :       {7, 70, "Quasi-Lagrangian Hurricane Model (QLM)"},
     454                 :       {7, 73, "Fog Forecast model - Ocean Prod. Center"},
     455                 :       {7, 74, "Gulf of Mexico Wind/Wave"},
     456                 :       {7, 75, "Gulf of Alaska Wind/Wave"},
     457                 :       {7, 76, "Bias corrected Medium Range Forecast"},
     458                 :       {7, 77, "126 wave triangular, 28 layer Spectral model from GFS model"},
     459                 :       {7, 78, "126 wave triangular, 28 layer Spectral model from 'Medium Range Forecast' run"},
     460                 :       {7, 79, "Backup from the previous run"},
     461                 :       {7, 80, "62 wave triangular, 28 layer Spectral model from 'Medium Range Forecast' run"},
     462                 :       {7, 81, "Spectral Statistical Interpolation (SSI) analysis from GFS model"},
     463                 :       {7, 82, "Spectral Statistical Interpolation (SSI) analysis from 'Final' run."},
     464                 :       {7, 84, "MESO ETA Model (currently 12 km)"},
     465                 :       {7, 86, "RUC Model from FSL (isentropic; scale: 60km at 40N)"},
     466                 :       {7, 87, "CAC Ensemble Forecasts from Spectral (ENSMB)"},
     467                 :       {7, 88, "NOAA Wave Watch III (NWW3) Ocean Wave Model"},
     468                 :       {7, 89, "Non-hydrostatic Meso Model (NMM) Currently 8 km)"},
     469                 :       {7, 90, "62 wave triangular, 28 layer spectral model extension of the 'Medium Range Forecast' run"},
     470                 :       {7, 91, "62 wave triangular, 28 layer spectral model extension of the GFS model"},
     471                 :       {7, 92, "62 wave triangular, 28 layer spectral model run from the 'Medium Range Forecast' final analysis"},
     472                 :       {7, 93, "62 wave triangular, 28 layer spectral model run from the T62 GDAS analysis of the 'Medium Range Forecast' run"},
     473                 :       {7, 94, "T170/L42 Global Spectral Model from MRF run"},
     474                 :       {7, 95, "T126/L42 Global Spectral Model from MRF run"},
     475                 :       {7, 96, "Global Forecast System Model"},
     476                 :       {7, 98, "Climate Forecast System Model"},
     477                 :       {7, 100, "RUC Surface Analysis (scale: 60km at 40N)"},
     478                 :       {7, 101, "RUC Surface Analysis (scale: 40km at 40N)"},
     479                 :       {7, 105, "RUC Model from FSL (isentropic; scale: 20km at 40N)"},
     480                 :       {7, 110, "ETA Model - 15km version"},
     481                 :       {7, 111, "Eta model, generic resolution"},
     482                 :       {7, 112, "WRF-NMM (Nondydrostatic Mesoscale Model) model, generic resolution"},
     483                 :       {7, 113, "Products from NCEP SREF processing"},
     484                 :       {7, 115, "Downscaled GFS from Eta eXtension"},
     485                 :       {7, 116, "WRF-EM (Eulerian Mass-core) model, generic resolution "},
     486                 :       {7, 120, "Ice Concentration Analysis"},
     487                 :       {7, 121, "Western North Atlantic Regional Wave Model"},
     488                 :       {7, 122, "Alaska Waters Regional Wave Model"},
     489                 :       {7, 123, "North Atlantic Hurricane Wave Model"},
     490                 :       {7, 124, "Eastern North Pacific Regional Wave Model"},
     491                 :       {7, 125, "North Pacific Hurricane Wave Model"},
     492                 :       {7, 126, "Sea Ice Forecast Model"},
     493                 :       {7, 127, "Lake Ice Forecast Model"},
     494                 :       {7, 128, "Global Ocean Forecast Model"},
     495                 :       {7, 129, "Global Ocean Data Analysis System (GODAS)"},
     496                 :       {7, 130, "Merge of fields from the RUC, Eta, and Spectral Model"},
     497                 :       {7, 131, "Great Lakes Wave Model"},
     498                 :       {7, 140, "North American Regional Reanalysis (NARR)"},
     499                 :       {7, 141, "Land Data Assimilation and Forecast System"},
     500                 :       {7, 150, "NWS River Forecast System (NWSRFS)"},
     501                 :       {7, 151, "NWS Flash Flood Guidance System (NWSFFGS)"},
     502                 :       {7, 152, "WSR-88D Stage II Precipitation Analysis"},
     503                 :       {7, 153, "WSR-88D Stage III Precipitation Analysis"},
     504                 :       {7, 180, "Quantitative Precipitation Forecast"},
     505                 :       {7, 181, "River Forecast Center Quantitative Precipitation Forecast mosaic"},
     506                 :       {7, 182, "River Forecast Center Quantitative Precipitation estimate mosaic"},
     507                 :       {7, 183, "NDFD product generated by NCEP/HPC"},
     508                 :       {7, 190, "National Convective Weather Diagnostic"},
     509                 :       {7, 191, "Current Icing Potential automated product"},
     510                 :       {7, 192, "Analysis product from NCEP/AWC"},
     511                 :       {7, 193, "Forecast product from NCEP/AWC"},
     512                 :       {7, 195, "Climate Data Assimilation System 2 (CDAS2)"},
     513                 :       {7, 196, "Climate Data Assimilation System 2 (CDAS2)"},
     514                 :       {7, 197, "Climate Data Assimilation System (CDAS)"},
     515                 :       {7, 198, "Climate Data Assimilation System (CDAS)"},
     516                 :       {7, 200, "CPC Manual Forecast Product"},
     517                 :       {7, 201, "CPC Automated Product"},
     518                 :       {7, 210, "EPA Air Quality Forecast"},
     519                 :       {7, 211, "EPA Air Quality Forecast"},
     520                 :       {7, 220, "NCEP/OPC automated product"}
     521                 :    };
     522                 : /* *INDENT-ON* */
     523               0 :    int numProcess = sizeof (Process) / sizeof (Process[0]);
     524                 :    int i;
     525                 : 
     526               0 :    for (i = 0; i < numProcess; i++) {
     527               0 :       if ((Process[i].center == center) && (Process[i].process == process)) {
     528               0 :          return Process[i].name;
     529                 :       }
     530                 :    }
     531               0 :    return NULL;
     532                 : }
     533                 : 
     534                 : typedef struct {
     535                 :    const char *name, *comment, *unit;
     536                 :    unit_convert convert;
     537                 : } GRIB2ParmTable;
     538                 : 
     539                 : typedef struct {
     540                 :    int prodType, cat, subcat;
     541                 :    const char *name, *comment, *unit;
     542                 :    unit_convert convert;
     543                 : } GRIB2LocalTable;
     544                 : 
     545                 : typedef struct {
     546                 :     const char *GRIB2name, *NDFDname;
     547                 : } NDFD_AbrevOverideTable;
     548                 : 
     549                 : /* *INDENT-OFF* */
     550                 : /* Updated based on:
     551                 :  * http://www.wmo.ch/web/www/WMOCodes/Operational/GRIB2/FM92-GRIB2-2005nov.pdf
     552                 :  * 1/3/2006
     553                 :  */
     554                 : /* GRIB2 Code table 4.2 : 0.0 */
     555                 : GRIB2ParmTable MeteoTemp[] = {
     556                 :    /* 0 */ {"TMP", "Temperature", "K", UC_K2F},  /* Need NDFD override. T */
     557                 :    /* 1 */ {"VTMP", "Virtual temperature", "K", UC_K2F},
     558                 :    /* 2 */ {"POT", "Potential temperature", "K", UC_K2F},
     559                 :    /* 3 */ {"EPOT", "Pseudo-adiabatic potential temperature", "K", UC_K2F},
     560                 :    /* 4 */ {"TMAX", "Maximum Temperature", "K", UC_K2F}, /* Need NDFD override MaxT */
     561                 :    /* 5 */ {"TMIN", "Minimum Temperature", "K", UC_K2F}, /* Need NDFD override MinT */
     562                 :    /* 6 */ {"DPT", "Dew point temperature", "K", UC_K2F}, /* Need NDFD override Td */
     563                 :    /* 7 */ {"DEPR", "Dew point depression", "K", UC_K2F},
     564                 :    /* 8 */ {"LAPR", "Lapse rate", "K/m", UC_NONE},
     565                 :    /* 9 */ {"TMPA", "Temperature anomaly", "K", UC_K2F},
     566                 :    /* 10 */ {"LHTFL", "Latent heat net flux", "W/(m^2)", UC_NONE},
     567                 :    /* 11 */ {"SHTFL", "Sensible heat net flux", "W/(m^2)", UC_NONE},
     568                 :             /* NDFD */
     569                 :    /* 12 */ {"HeatIndex", "Heat index", "K", UC_K2F},
     570                 :             /* NDFD */
     571                 :    /* 13 */ {"WCI", "Wind chill factor", "K", UC_K2F},
     572                 :    /* 14 */ {"", "Minimum dew point depression", "K", UC_K2F},
     573                 :    /* 15 */ {"VPTMP", "Virtual potential temperature", "K", UC_K2F},
     574                 : /* 16 */    {"SNOHF", "Snow phase change heat flux", "W/m^2", UC_NONE},
     575                 : };
     576                 : 
     577                 : /* GRIB2 Code table 4.2 : 0.1 */
     578                 : /* NCEP added "Water" to items 22, 24, 25 */
     579                 : GRIB2ParmTable MeteoMoist[] = {
     580                 :    /* 0 */ {"SPFH", "Specific humidity", "kg/kg", UC_NONE},
     581                 :    /* 1 */ {"RH", "Relative Humidity", "%", UC_NONE},
     582                 :    /* 2 */ {"MIXR", "Humidity mixing ratio", "kg/kg", UC_NONE},
     583                 :    /* 3 */ {"PWAT", "Precipitable water", "kg/(m^2)", UC_NONE},
     584                 :    /* 4 */ {"VAPP", "Vapor Pressure", "Pa", UC_NONE},
     585                 :    /* 5 */ {"SATD", "Saturation deficit", "Pa", UC_NONE},
     586                 :    /* 6 */ {"EVP", "Evaporation", "kg/(m^2)", UC_NONE},
     587                 :    /* 7 */ {"PRATE", "Precipitation rate", "kg/(m^2 s)", UC_NONE},
     588                 :    /* 8 */ {"APCP", "Total precipitation", "kg/(m^2)", UC_InchWater}, /* Need NDFD override QPF */
     589                 :    /* 9 */ {"NCPCP", "Large scale precipitation", "kg/(m^2)", UC_NONE},
     590                 :    /* 10 */ {"ACPCP", "Convective precipitation", "kg/(m^2)", UC_NONE},
     591                 :    /* 11 */ {"SNOD", "Snow depth", "m", UC_M2Inch}, /* Need NDFD override SnowDepth ? */
     592                 :    /* 12 */ {"SRWEQ", "Snowfall rate water equivalent", "kg/(m^2 s)", UC_NONE},
     593                 :    /* 13 */ {"WEASD", "Water equivalent of accumulated snow depth",
     594                 :              "kg/(m^2)", UC_NONE},
     595                 :    /* 14 */ {"SNOC", "Convective snow", "kg/(m^2)", UC_NONE},
     596                 :    /* 15 */ {"SNOL", "Large scale snow", "kg/(m^2)", UC_NONE},
     597                 :    /* 16 */ {"SNOM", "Snow melt", "kg/(m^2)", UC_NONE},
     598                 :    /* 17 */ {"SNOAG", "Snow age", "day", UC_NONE},
     599                 :    /* 18 */ {"", "Absolute humidity", "kg/(m^3)", UC_NONE},
     600                 :    /* 19 */ {"", "Precipitation type", "(1 Rain, 2 Thunderstorm, "
     601                 :              "3 Freezing Rain, 4 Mixed/ice, 5 snow, 255 missing)", UC_NONE},
     602                 :    /* 20 */ {"", "Integrated liquid water", "kg/(m^2)", UC_NONE},
     603                 :    /* 21 */ {"TCOND", "Condensate", "kg/kg", UC_NONE},
     604                 : /* CLWMR Did not make it to tables yet should be "-" */
     605                 :    /* 22 */ {"CLWMR", "Cloud Water Mixing Ratio", "kg/kg", UC_NONE},
     606                 :    /* 23 */ {"ICMR", "Ice water mixing ratio", "kg/kg", UC_NONE},   /* ICMR? */
     607                 :    /* 24 */ {"RWMR", "Rain Water Mixing Ratio", "kg/kg", UC_NONE},
     608                 :    /* 25 */ {"SNMR", "Snow Water Mixing Ratio", "kg/kg", UC_NONE},
     609                 :    /* 26 */ {"MCONV", "Horizontal moisture convergence", "kg/(kg s)", UC_NONE},
     610                 :    /* 27 */ {"", "Maximum relative humidity", "%", UC_NONE},
     611                 :    /* 28 */ {"", "Maximum absolute humidity", "kg/(m^3)", UC_NONE},
     612                 :             /* NDFD */
     613                 :    /* 29 */ {"ASNOW", "Total snowfall", "m", UC_M2Inch},
     614                 :    /* 30 */ {"", "Precipitable water category", "(undefined)", UC_NONE},
     615                 :    /* 31 */ {"", "Hail", "m", UC_NONE},
     616                 :    /* 32 */ {"", "Graupel (snow pellets)", "kg/kg", UC_NONE},
     617                 : /* 33 */    {"CRAIN", "Categorical rain", "0=no, 1=yes", UC_NONE},
     618                 : /* 34 */    {"CFRZR", "Categorical freezing rain", "0=no, 1=yes", UC_NONE},
     619                 : /* 35 */    {"CICEP", "Categorical ice pellets", "0=no, 1=yes", UC_NONE},
     620                 : /* 36 */    {"CSNOW", "Categorical snow", "0=no, 1=yes", UC_NONE},
     621                 : /* 37 */    {"CPRAT", "Convective precipitation rate", "kg/(m^2*s)", UC_NONE},
     622                 : /* 38 */    {"MCONV", "Horizontal moisture divergence", "kg/(kg*s)", UC_NONE},
     623                 : /* 39 */    {"CPOFP", "Percent frozen precipitation", "%", UC_NONE},
     624                 : /* 40 */    {"PEVAP", "Potential evaporation", "kg/m^2", UC_NONE},
     625                 : /* 41 */    {"PEVPR", "Potential evaporation rate", "W/m^2", UC_NONE},
     626                 : /* 42 */    {"SNOWC", "Snow Cover", "%", UC_NONE},
     627                 : /* 43 */    {"FRAIN", "Rain fraction of total cloud water", "-", UC_NONE},
     628                 : /* 44 */    {"RIME", "Rime factor", "-", UC_NONE},
     629                 : /* 45 */    {"TCOLR", "Total column integrated rain", "kg/m^2", UC_NONE},
     630                 : /* 46 */    {"TCOLS", "Total column integrated snow", "kg/m^2", UC_NONE},
     631                 : };
     632                 : 
     633                 : /* GRIB2 Code table 4.2 : 0.2 */
     634                 : GRIB2ParmTable MeteoMoment[] = {
     635                 :    /* 0 */ {"WDIR", "Wind direction (from which blowing)", "deg true",
     636                 :             UC_NONE}, /* Need NDFD override WindDir */
     637                 :    /* 1 */ {"WIND", "Wind speed", "m/s", UC_MS2Knots}, /* Need NDFD override WindSpd */
     638                 :    /* 2 */ {"UGRD", "u-component of wind", "m/s", UC_NONE},
     639                 :    /* 3 */ {"VGRD", "v-component of wind", "m/s", UC_NONE},
     640                 :    /* 4 */ {"STRM", "Stream function", "(m^2)/s", UC_NONE},
     641                 :    /* 5 */ {"VPOT", "Velocity potential", "(m^2)/s", UC_NONE},
     642                 :    /* 6 */ {"MNTSF", "Montgomery stream function", "(m^2)/(s^2)", UC_NONE},
     643                 :    /* 7 */ {"SGCVV", "Sigma coordinate vertical velocity", "1/s", UC_NONE},
     644                 :    /* 8 */ {"VVEL", "Vertical velocity (pressure)", "Pa/s", UC_NONE}, /* NCEP override WEL?  */
     645                 :    /* 9 */ {"DZDT", "Verical velocity (geometric)", "m/s", UC_NONE},
     646                 :    /* 10 */ {"ABSV", "Absolute vorticity", "1/s", UC_NONE},
     647                 :    /* 11 */ {"ABSD", "Absolute divergence", "1/s", UC_NONE},
     648                 :    /* 12 */ {"RELV", "Relative vorticity", "1/s", UC_NONE},
     649                 :    /* 13 */ {"RELD", "Relative divergence", "1/s", UC_NONE},
     650                 :    /* 14 */ {"PV", "Potential vorticity", "K(m^2)/(kg s)", UC_NONE},
     651                 :    /* 15 */ {"VUCSH", "Vertical u-component shear", "1/s", UC_NONE},
     652                 :    /* 16 */ {"VVCSH", "Vertical v-component shear", "1/s", UC_NONE},
     653                 :    /* 17 */ {"UFLX", "Momentum flux; u component", "N/(m^2)", UC_NONE},
     654                 :    /* 18 */ {"VFLX", "Momentum flux; v component", "N/(m^2)", UC_NONE},
     655                 :    /* 19 */ {"WMIXE", "Wind mixing energy", "J", UC_NONE},
     656                 :    /* 20 */ {"BLYDP", "Boundary layer dissipation", "W/(m^2)", UC_NONE},
     657                 :    /* 21 */ {"", "Maximum wind speed", "m/s", UC_NONE},
     658                 :    /* 22 */ {"GUST", "Wind speed (gust)", "m/s", UC_MS2Knots},  /* GUST? */
     659                 :    /* 23 */ {"", "u-component of wind (gust)", "m/s", UC_NONE},
     660                 :    /* 24 */ {"", "v-component of wind (gust)", "m/s", UC_NONE},
     661                 : /* 25 */    {"VWSH", "Vertical speed shear", "1/s", UC_NONE},
     662                 : /* 26 */    {"MFLX", "Horizontal momentum flux", "N/(m^2)", UC_NONE},
     663                 : /* 27 */    {"USTM", "U-component storm motion", "m/s", UC_NONE},
     664                 : /* 28 */    {"VSTM", "V-component storm motion", "m/s", UC_NONE},
     665                 : /* 29 */    {"CD", "Drag coefficient", "-", UC_NONE},
     666                 : /* 30 */    {"FRICV", "Frictional velocity", "m/s", UC_NONE},
     667                 : };
     668                 : 
     669                 : /* GRIB2 Code table 4.2 : 0.3 */
     670                 : GRIB2ParmTable MeteoMass[] = {
     671                 :    /* 0 */ {"PRES", "Pressure", "Pa", UC_NONE},
     672                 :    /* 1 */ {"PRMSL", "Pressure reduced to MSL", "Pa", UC_NONE},
     673                 :    /* 2 */ {"PTEND", "Pressure tendency", "Pa/s", UC_NONE},
     674                 :    /* 3 */ {"ICAHT", "ICAO Standard Atmosphere Reference Height", "m", UC_NONE},
     675                 :    /* 4 */ {"GP", "Geopotential", "(m^2)/(s^2)", UC_NONE},
     676                 :    /* 5 */ {"HGT", "Geopotential height", "gpm", UC_NONE},
     677                 :    /* 6 */ {"DIST", "Geometric Height", "m", UC_NONE},
     678                 :    /* 7 */ {"HSTDV", "Standard deviation of height", "m", UC_NONE},
     679                 :    /* 8 */ {"PRESA", "Pressure anomaly", "Pa", UC_NONE},
     680                 :    /* 9 */ {"GPA", "Geopotential height anomally", "gpm", UC_NONE},
     681                 :    /* 10 */ {"DEN", "Density", "kg/(m^3)", UC_NONE},
     682                 :    /* 11 */ {"", "Altimeter setting", "Pa", UC_NONE},
     683                 :    /* 12 */ {"", "Thickness", "m", UC_NONE},
     684                 :    /* 13 */ {"", "Pressure altitude", "m", UC_NONE},
     685                 :    /* 14 */ {"", "Density altitude", "m", UC_NONE},
     686                 : /* 15 */    {"5WAVH", "5-wave geopotential height", "gpm", UC_NONE},
     687                 : /* 16 */    {"U-GWD", "Zonal flux of gravity wave stress", "N/(m^2)", UC_NONE},
     688                 : /* 17 */    {"V-GWD", "Meridional flux of gravity wave stress", "N/(m^2)", UC_NONE},
     689                 : /* 18 */    {"HPBL", "Planetary boundary layer height", "m", UC_NONE},
     690                 : /* 19 */    {"5WAVA", "5-Wave geopotential height anomaly", "gpm", UC_NONE},
     691                 : };
     692                 : 
     693                 : /* GRIB2 Code table 4.2 : 0.4 */
     694                 : GRIB2ParmTable MeteoShortRadiate[] = {
     695                 :    /* 0 */ {"NSWRS", "Net short-wave radiation flux (surface)", "W/(m^2)", UC_NONE},
     696                 :    /* 1 */ {"NSWRT", "Net short-wave radiation flux (top of atmosphere)",
     697                 :             "W/(m^2)", UC_NONE},
     698                 :    /* 2 */ {"SWAVR", "Short wave radiation flux", "W/(m^2)", UC_NONE},
     699                 :    /* 3 */ {"GRAD", "Global radiation flux", "W/(m^2)", UC_NONE},
     700                 :    /* 4 */ {"BRTMP", "Brightness temperature", "K", UC_NONE},
     701                 :    /* 5 */ {"LWRAD", "Radiance (with respect to wave number)", "W/(m sr)", UC_NONE},
     702                 :    /* 6 */ {"SWRAD", "Radiance (with respect to wave length)", "W/(m^3 sr)", UC_NONE},
     703                 : /* 7 */    {"DSWRF", "Downward short-wave radiation flux", "W/(m^2)", UC_NONE},
     704                 : /* 8 */    {"USWRF", "Upward short-wave radiation flux", "W/(m^2)", UC_NONE},
     705                 : };
     706                 : 
     707                 : /* GRIB2 Code table 4.2 : 0.5 */
     708                 : GRIB2ParmTable MeteoLongRadiate[] = {
     709                 :    /* 0 */ {"NLWRS", "Net long wave radiation flux (surface)", "W/(m^2)", UC_NONE},
     710                 :    /* 1 */ {"NLWRT", "Net long wave radiation flux (top of atmosphere)",
     711                 :             "W/(m^2)", UC_NONE},
     712                 :    /* 2 */ {"LWAVR", "Long wave radiation flux", "W/(m^2)", UC_NONE},
     713                 : /* 3 */    {"DLWRF", "Downward Long-Wave Rad. Flux", "W/(m^2)", UC_NONE},
     714                 : /* 4 */    {"ULWRF", "Upward Long-Wave Rad. Flux", "W/(m^2)", UC_NONE},
     715                 : };
     716                 : 
     717                 : /* GRIB2 Code table 4.2 : 0.6 */
     718                 : GRIB2ParmTable MeteoCloud[] = {
     719                 :    /* 0 */ {"CICE", "Cloud Ice", "kg/(m^2)", UC_NONE},
     720                 :    /* 1 */ {"TCDC", "Total cloud cover", "%", UC_NONE}, /* Need NDFD override Sky */
     721                 :    /* 2 */ {"CDCON", "Convective cloud cover", "%", UC_NONE},
     722                 :    /* 3 */ {"LCDC", "Low cloud cover", "%", UC_NONE},
     723                 :    /* 4 */ {"MCDC", "Medium cloud cover", "%", UC_NONE},
     724                 :    /* 5 */ {"HCDC", "High cloud cover", "%", UC_NONE},
     725                 :    /* 6 */ {"CWAT", "Cloud water", "kg/(m^2)", UC_NONE},
     726                 :    /* 7 */ {"", "Cloud amount", "%", UC_NONE},
     727                 :    /* 8 */ {"", "Cloud type", "(0 clear, 1 Cumulonimbus, 2 Stratus, "
     728                 :             "3 Stratocumulus, 4 Cumulus, 5 Altostratus, 6 Nimbostratus, "
     729                 :             "7 Altocumulus, 8 Cirrostratus, 9 Cirrocumulus, 10 Cirrus, "
     730                 :             "11 Cumulonimbus (fog), 12 Stratus (fog), 13 Stratocumulus (fog),"
     731                 :             " 14 Cumulus (fog), 15 Altostratus (fog), 16 Nimbostratus (fog), "
     732                 :             "17 Altocumulus (fog), 18 Cirrostratus (fog), "
     733                 :             "19 Cirrocumulus (fog), 20 Cirrus (fog), 191 unknown, "
     734                 :             "255 missing)", UC_NONE},
     735                 :    /* 9 */ {"", "Thunderstorm maximum tops", "m", UC_NONE},
     736                 :    /* 10 */ {"", "Thunderstorm coverage", "(0 none, 1 isolated (1%-2%), "
     737                 :              "2 few (3%-15%), 3 scattered (16%-45%), 4 numerous (> 45%), "
     738                 :              "255 missing)", UC_NONE},
     739                 :    /* 11 */ {"", "Cloud base", "m", UC_NONE},
     740                 :    /* 12 */ {"", "Cloud top", "m", UC_NONE},
     741                 :    /* 13 */ {"", "Ceiling", "m", UC_NONE},
     742                 : /* 14 */    {"CDLYR", "Non-convective cloud cover", "%", UC_NONE},
     743                 : /* 15 */    {"CWORK", "Cloud work function", "J/kg", UC_NONE},
     744                 : /* 16 */    {"CUEFI", "Convective cloud efficiency", "-", UC_NONE},
     745                 : /* 17 */    {"TCOND", "Total condensate", "kg/kg", UC_NONE},
     746                 : /* 18 */    {"TCOLW", "Total column-integrated cloud water", "kg/(m^2)", UC_NONE},
     747                 : /* 19 */    {"TCOLI", "Total column-integrated cloud ice", "kg/(m^2)", UC_NONE},
     748                 : /* 20 */    {"TCOLC", "Total column-integrated condensate", "kg/(m^2)", UC_NONE},
     749                 : /* 21 */    {"FICE", "Ice fraction of total condensate", "-", UC_NONE},
     750                 : };
     751                 : 
     752                 : /* GRIB2 Code table 4.2 : 0.7 */
     753                 : /* NCEP capitalized items 6, 7, 8 */
     754                 : GRIB2ParmTable MeteoStability[] = {
     755                 :    /* 0 */ {"PLI", "Parcel lifted index (to 500 hPa)", "K", UC_NONE},
     756                 :    /* 1 */ {"BLI", "Best lifted index (to 500 hPa)", "K", UC_NONE},
     757                 :    /* 2 */ {"KX", "K index", "K", UC_NONE},
     758                 :    /* 3 */ {"", "KO index", "K", UC_NONE},
     759                 :    /* 4 */ {"", "Total totals index", "K", UC_NONE},
     760                 :    /* 5 */ {"SX", "Sweat index", "numeric", UC_NONE},
     761                 :    /* 6 */ {"CAPE", "Convective available potential energy", "J/kg", UC_NONE},
     762                 :    /* 7 */ {"CIN", "Convective inhibition", "J/kg", UC_NONE},
     763                 :    /* 8 */ {"HLCY", "Storm relative helicity", "J/kg", UC_NONE},
     764                 :    /* 9 */ {"", "Energy helicity index", "numeric", UC_NONE},
     765                 : /* 10 */   {"LFTX", "Surface fifted index", "K", UC_NONE},
     766                 : /* 11 */   {"4LFTX", "Best (4-layer) lifted index", "K", UC_NONE},
     767                 : /* 12 */   {"RI", "Richardson number", "-", UC_NONE},
     768                 : };
     769                 : 
     770                 : /* GRIB2 Code table 4.2 : 0.13 */
     771                 : GRIB2ParmTable MeteoAerosols[] = {
     772                 :    /* 0 */ {"", "Aerosol type", "(0 Aerosol not present, 1 Aerosol present, "
     773                 :             "255 missing)", UC_NONE},
     774                 : };
     775                 : 
     776                 : /* GRIB2 Code table 4.2 : 0.14 */
     777                 : GRIB2ParmTable MeteoGases[] = {
     778                 :    /* 0 */ {"TOZNE", "Total ozone", "Dobson", UC_NONE},
     779                 : /* 1 */    {"O3MR", "Ozone Mixing Ratio", "kg/kg", UC_NONE},
     780                 : };
     781                 : 
     782                 : /* GRIB2 Code table 4.2 : 0.15 */
     783                 : GRIB2ParmTable MeteoRadar[] = {
     784                 :    /* 0 */ {"", "Base spectrum width", "m/s", UC_NONE},
     785                 :    /* 1 */ {"", "Base reflectivity", "dB", UC_NONE},
     786                 :    /* 2 */ {"", "Base radial velocity", "m/s", UC_NONE},
     787                 :    /* 3 */ {"", "Vertically-integrated liquid", "kg/m", UC_NONE},
     788                 :    /* 4 */ {"", "Layer-maximum base reflectivity", "dB", UC_NONE},
     789                 :    /* 5 */ {"", "Precipitation", "kg/(m^2)", UC_NONE},
     790                 :    /* 6 */ {"RDSP1", "Radar spectra (1)", "-", UC_NONE},
     791                 :    /* 7 */ {"RDSP2", "Radar spectra (2)", "-", UC_NONE},
     792                 :    /* 8 */ {"RDSP3", "Radar spectra (3)", "-", UC_NONE},
     793                 : };
     794                 : 
     795                 : /* GRIB2 Code table 4.2 : 0.18 */
     796                 : GRIB2ParmTable MeteoNuclear[] = {
     797                 :    /* 0 */ {"", "Air concentration of Caesium 137", "Bq/(m^3)", UC_NONE},
     798                 :    /* 1 */ {"", "Air concentration of Iodine 131", "Bq/(m^3)", UC_NONE},
     799                 :    /* 2 */ {"", "Air concentration of radioactive pollutant", "Bq/(m^3)", UC_NONE},
     800                 :    /* 3 */ {"", "Ground deposition of Caesium 137", "Bq/(m^2)", UC_NONE},
     801                 :    /* 4 */ {"", "Ground deposition of Iodine 131", "Bq/(m^2)", UC_NONE},
     802                 :    /* 5 */ {"", "Ground deposition of radioactive pollutant", "Bq/(m^2)", UC_NONE},
     803                 :    /* 6 */ {"", "Time-integrated air concentration of caesium pollutant",
     804                 :             "(Bq s)/(m^3)", UC_NONE},
     805                 :    /* 7 */ {"", "Time-integrated air concentration of iodine pollutant",
     806                 :             "(Bq s)/(m^3)", UC_NONE},
     807                 :    /* 8 */ {"", "Time-integrated air concentration of radioactive pollutant",
     808                 :             "(Bq s)/(m^3)", UC_NONE},
     809                 : };
     810                 : 
     811                 : /* GRIB2 Code table 4.2 : 0.19 */
     812                 : /* NCEP capitalized items 11 */
     813                 : GRIB2ParmTable MeteoAtmos[] = {
     814                 :    /* 0 */ {"VIS", "Visibility", "m", UC_NONE},
     815                 :    /* 1 */ {"ALBDO", "Albedo", "%", UC_NONE},
     816                 :    /* 2 */ {"TSTM", "Thunderstorm probability", "%", UC_NONE},
     817                 :    /* 3 */ {"MIXHT", "mixed layer depth", "m", UC_NONE},
     818                 :    /* 4 */ {"", "Volcanic ash", "(0 not present, 1 present, 255 missing)", UC_NONE},
     819                 :    /* 5 */ {"", "Icing top", "m", UC_NONE},
     820                 :    /* 6 */ {"", "Icing base", "m", UC_NONE},
     821                 :    /* 7 */ {"", "Icing", "(0 None, 1 Light, 2 Moderate, 3 Severe, "
     822                 :             "255 missing)", UC_NONE},
     823                 :    /* 8 */ {"", "Turbulance top", "m", UC_NONE},
     824                 :    /* 9 */ {"", "Turbulence base", "m", UC_NONE},
     825                 :    /* 10 */ {"", "Turbulance", "(0 None(smooth), 1 Light, 2 Moderate, "
     826                 :              "3 Severe, 4 Extreme, 255 missing)", UC_NONE},
     827                 :    /* 11 */ {"TKE", "Turbulent Kinetic Energy", "J/kg", UC_NONE},
     828                 :    /* 12 */ {"", "Planetary boundary layer regime", "(0 Reserved, 1 Stable, "
     829                 :              "2 Mechanically driven turbulence, 3 Forced convection, "
     830                 :              "4 Free convection, 255 missing)", UC_NONE},
     831                 :    /* 13 */ {"", "Contrail intensity", "(0 Contrail not present, "
     832                 :              "1 Contrail present, 255 missing)", UC_NONE},
     833                 :    /* 14 */ {"", "Contrail engine type", "(0 Low bypass, 1 High bypass, "
     834                 :              "2 Non bypass, 255 missing)", UC_NONE},
     835                 :    /* 15 */ {"", "Contrail top", "m", UC_NONE},
     836                 :    /* 16 */ {"", "Contrail base", "m", UC_NONE},
     837                 : /* 17 */    {"MXSALB", "Maximum snow albedo", "%", UC_NONE},
     838                 : /* 18 */    {"SNFALB", "Snow free albedo", "%", UC_NONE},
     839                 : };
     840                 : 
     841                 : /* GRIB2 Code table 4.2 : 0.253 or 0.190 (Document is inconsistant.) */
     842                 : GRIB2ParmTable MeteoText[] = {
     843                 :    /* 0 */ {"", "Arbitrary text string", "CCITTIA5", UC_NONE},
     844                 : };
     845                 : 
     846                 : GRIB2ParmTable MeteoMisc[] = {
     847                 :    /* 0 */ {"TSEC", "Seconds prior to initial reference time (defined in Section"
     848                 :             " 1)", "s", UC_NONE},
     849                 : };
     850                 : 
     851                 : /* GRIB2 Code table 4.2 : 1.0 */
     852                 : GRIB2ParmTable HydroBasic[] = {
     853                 :    /* 0 */ {"", "Flash flood guidance", "kg/(m^2)", UC_NONE},
     854                 :    /* 1 */ {"", "Flash flood runoff", "kg/(m^2)", UC_NONE},
     855                 :    /* 2 */ {"", "Remotely sensed snow cover", "(50 no-snow/no-cloud, "
     856                 :             "100 Clouds, 250 Snow, 255 missing)", UC_NONE},
     857                 :    /* 3 */ {"", "Elevation of snow covered terrain", "(0-90 elevation in "
     858                 :             "increments of 100m, 254 clouds, 255 missing)", UC_NONE},
     859                 :    /* 4 */ {"", "Snow water equivalent percent of normal", "%", UC_NONE},
     860                 : /* 5 */    {"BGRUN", "Baseflow-groundwater runoff", "kg/(m^2)", UC_NONE},
     861                 : /* 6 */    {"SSRUN", "Storm surface runoff", "kg/(m^2)", UC_NONE},
     862                 : };
     863                 : 
     864                 : /* GRIB2 Code table 4.2 : 1.1 */
     865                 : GRIB2ParmTable HydroProb[] = {
     866                 :    /* 0 */ {"", "Conditional percent precipitation amount fractile for an "
     867                 :             "overall period", "kg/(m^2)", UC_NONE},
     868                 :    /* 1 */ {"", "Percent precipitation in a sub-period of an overall period",
     869                 :             "%", UC_NONE},
     870                 :    /* 2 */ {"PoP", "Probability of 0.01 inch of precipitation", "%", UC_NONE},
     871                 : };
     872                 : 
     873                 : /* GRIB2 Code table 4.2 : 2.0 */
     874                 : GRIB2ParmTable LandVeg[] = {
     875                 :    /* 0 */ {"LAND", "Land cover (1=land; 2=sea)", "Proportion", UC_NONE},
     876                 :    /* 1 */ {"SFCR", "Surface roughness", "m", UC_NONE}, /*NCEP override SFRC? */
     877                 :    /* 2 */ {"TSOIL", "Soil temperature", "K", UC_NONE},
     878                 :    /* 3 */ {"SOILM", "Soil moisture content", "kg/(m^2)", UC_NONE},
     879                 :    /* 4 */ {"VEG", "Vegetation", "%", UC_NONE},
     880                 :    /* 5 */ {"WATR", "Water runoff", "kg/(m^2)", UC_NONE},
     881                 :    /* 6 */ {"", "Evapotranspiration", "1/(kg^2 s)", UC_NONE},
     882                 :    /* 7 */ {"", "Model terrain height", "m", UC_NONE},
     883                 :    /* 8 */ {"", "Land use", "(1 Urban land, 2 agriculture, 3 Range Land, "
     884                 :             "4 Deciduous forest, 5 Coniferous forest, 6 Forest/wetland, "
     885                 :             "7 Water, 8 Wetlands, 9 Desert, 10 Tundra, 11 Ice, "
     886                 :             "12 Tropical forest, 13 Savannah)", UC_NONE},
     887                 : /* 9 */    {"SOILW", "Volumetric soil moisture content", "fraction", UC_NONE},
     888                 : /* 10 */   {"GFLUX", "Ground heat flux", "W/(m^2)", UC_NONE},
     889                 : /* 11 */   {"MSTAV", "Moisture availability", "%", UC_NONE},
     890                 : /* 12 */   {"SFEXC", "Exchange coefficient", "(kg/(m^3))(m/s)", UC_NONE},
     891                 : /* 13 */   {"CNWAT", "Plant canopy surface water", "kg/(m^2)", UC_NONE},
     892                 : /* 14 */   {"BMIXL", "Blackadar's mixing length scale", "m", UC_NONE},
     893                 : /* 15 */   {"CCOND", "Canopy conductance", "m/s", UC_NONE},
     894                 : /* 16 */   {"RSMIN", "Minimal stomatal resistance", "s/m", UC_NONE},
     895                 : /* 17 */   {"WILT", "Wilting point", "fraction", UC_NONE},
     896                 : /* 18 */   {"RCS", "Solar parameter in canopy conductance", "fraction", UC_NONE},
     897                 : /* 19 */   {"RCT", "Temperature parameter in canopy conductance", "fraction", UC_NONE},
     898                 : /* 20 */   {"RCSOL", "Soil moisture parameter in canopy conductance", "fraction", UC_NONE},
     899                 : /* 21 */   {"RCQ", "Humidity parameter in canopy conductance", "fraction", UC_NONE},
     900                 : };
     901                 : 
     902                 : /* GRIB2 Code table 4.2 : 2.3 */
     903                 : /* NCEP changed 0 to be "Soil type (as in Zobler)" I ignored them */
     904                 : GRIB2ParmTable LandSoil[] = {
     905                 :    /* 0 */ {"SOTYP", "Soil type", "(1 Sand, 2 Loamy sand, 3 Sandy loam, "
     906                 :             "4 Silt loam, 5 Organic (redefined), 6 Sandy clay loam, "
     907                 :             "7 Silt clay loam, 8 Clay loam, 9 Sandy clay, 10 Silty clay, "
     908                 :             "11 Clay)", UC_NONE},
     909                 :    /* 1 */ {"", "Upper layer soil temperature", "K", UC_NONE},
     910                 :    /* 2 */ {"", "Upper layer soil moisture", "kg/(m^3)", UC_NONE},
     911                 :    /* 3 */ {"", "Lower layer soil moisture", "kg/(m^3)", UC_NONE},
     912                 :    /* 4 */ {"", "Bottom layer soil temperature", "K", UC_NONE},
     913                 : /* 5 */ {"SOILL", "Liquid volumetric soil moisture (non-frozen)", "fraction", UC_NONE},
     914                 : /* 6 */ {"RLYRS", "Number of soil layers in root zone", "-", UC_NONE},
     915                 : /* 7 */ {"SMREF", "Transpiration stress-onset (soil moisture)", "fraction", UC_NONE},
     916                 : /* 8 */ {"SMDRY", "Direct evaporation cease (soil moisture)", "fraction", UC_NONE},
     917                 : /* 9 */ {"POROS", "Soil porosity", "fraction", UC_NONE},
     918                 : };
     919                 : 
     920                 : /* GRIB2 Code table 4.2 : 3.0 */
     921                 : GRIB2ParmTable SpaceImage[] = {
     922                 :    /* 0 */ {"", "Scaled radiance", "numeric", UC_NONE},
     923                 :    /* 1 */ {"", "Scaled albedo", "numeric", UC_NONE},
     924                 :    /* 2 */ {"", "Scaled brightness temperature", "numeric", UC_NONE},
     925                 :    /* 3 */ {"", "Scaled precipitable water", "numeric", UC_NONE},
     926                 :    /* 4 */ {"", "Scaled lifted index", "numeric", UC_NONE},
     927                 :    /* 5 */ {"", "Scaled cloud top pressure", "numeric", UC_NONE},
     928                 :    /* 6 */ {"", "Scaled skin temperature", "numeric", UC_NONE},
     929                 :    /* 7 */ {"", "Cloud mask", "(0 clear over water, 1 clear over land, "
     930                 :             "2 cloud)", UC_NONE},
     931                 : /* 8 */ {"", "Pixel scene type", "(0 No scene, 1 needle, 2 broad-leafed, "
     932                 :          "3 Deciduous needle, 4 Deciduous broad-leafed, 5 Deciduous mixed, "
     933                 :          "6 Closed shrub, 7 Open shrub, 8 Woody savannah, 9 Savannah, "
     934                 :          "10 Grassland, 11 wetland, 12 Cropland, 13 Urban, 14 crops, "
     935                 :          "15 snow, 16 Desert, 17 Water, 18 Tundra, 97 Snow on land, "
     936                 :          "98 Snow on water, 99 Sun-glint, 100 General cloud, "
     937                 :          "101 (fog, Stratus), 102 Stratocumulus, 103 Low cloud, "
     938                 :          "104 Nimbotratus, 105 Altostratus, 106 Medium cloud, 107 Cumulus, "
     939                 :          "108 Cirrus, 109 High cloud, 110 Unknown cloud)", UC_NONE},
     940                 : };
     941                 : 
     942                 : /* GRIB2 Code table 4.2 : 3.1 */
     943                 : GRIB2ParmTable SpaceQuantitative[] = {
     944                 :    /* 0 */ {"", "Estimated precipitation", "kg/(m^2)", UC_NONE},
     945                 : /* 1 */ {"", "Instantaneous rain rate", "kg/(m^2*s)", UC_NONE},
     946                 : /* 2 */ {"", "Cloud top height", "kg/(m^2*s)", UC_NONE},
     947                 : /* 3 */ {"", "Cloud top height quality indicator", "(0 Nominal cloud top "
     948                 :          "height quality, 1 Fog in segment, 2 Poor quality height estimation "
     949                 :          "3 Fog in segment and poor quality height estimation)", UC_NONE},
     950                 : /* 4 */ {"", "Estimated u component of wind", "m/s", UC_NONE},
     951                 : /* 5 */ {"", "Estimated v component of wind", "m/s", UC_NONE},
     952                 : };
     953                 : 
     954                 : /* GRIB2 Code table 4.2 : 10.0 */
     955                 : GRIB2ParmTable OceanWaves[] = {
     956                 :    /* 0 */ {"WVSP1", "Wave spectra (1)", "-", UC_NONE},
     957                 :    /* 1 */ {"WVSP2", "Wave spectra (2)", "-", UC_NONE},
     958                 :    /* 2 */ {"WVSP3", "Wave spectra (3)", "-", UC_NONE},
     959                 :    /* 3 */ {"HTSGW", "Significant height of combined wind waves and swell", "m", UC_NONE},
     960                 :    /* 4 */ {"WVDIR", "Direction of wind waves", "Degree true", UC_NONE},
     961                 :    /* 5 */ {"WVHGT", "Significant height of wind waves", "m", UC_M2Feet}, /* NDFD override needed WaveHeight */
     962                 :    /* 6 */ {"WVPER", "Mean period of wind waves", "s", UC_NONE},
     963                 :    /* 7 */ {"SWDIR", "Direction of swell waves", "Degree true", UC_NONE},
     964                 :    /* 8 */ {"SWELL", "Significant height of swell waves", "m", UC_NONE},
     965                 :    /* 9 */ {"SWPER", "Mean period of swell waves", "s", UC_NONE},
     966                 :    /* 10 */ {"DIRPW", "Primary wave direction", "Degree true", UC_NONE},
     967                 :    /* 11 */ {"PERPW", "Primary wave mean period", "s", UC_NONE},
     968                 :    /* 12 */ {"DIRSW", "Secondary wave direction", "Degree true", UC_NONE},
     969                 :    /* 13 */ {"PERSW", "Secondary wave mean period", "s", UC_NONE},
     970                 : };
     971                 : 
     972                 : /* GRIB2 Code table 4.2 : 10.1 */
     973                 : GRIB2ParmTable OceanCurrents[] = {
     974                 :    /* 0 */ {"DIRC", "Current direction", "Degree true", UC_NONE},
     975                 :    /* 1 */ {"SPC", "Current speed", "m/s", UC_NONE},
     976                 :    /* 2 */ {"UOGRD", "u-component of current", "m/s", UC_NONE},
     977                 :    /* 3 */ {"VOGRD", "v-component of current", "m/s", UC_NONE},
     978                 : };
     979                 : 
     980                 : /* GRIB2 Code table 4.2 : 10.2 */
     981                 : GRIB2ParmTable OceanIce[] = {
     982                 :    /* 0 */ {"ICEC", "Ice cover", "Proportion", UC_NONE},
     983                 :    /* 1 */ {"ICETK", "Ice thinkness", "m", UC_NONE},
     984                 :    /* 2 */ {"DICED", "Direction of ice drift", "Degree true", UC_NONE},
     985                 :    /* 3 */ {"SICED", "Speed of ice drift", "m/s", UC_NONE},
     986                 :    /* 4 */ {"UICE", "u-component of ice drift", "m/s", UC_NONE},
     987                 :    /* 5 */ {"VICE", "v-component of ice drift", "m/s", UC_NONE},
     988                 :    /* 6 */ {"ICEG", "Ice growth rate", "m/s", UC_NONE},
     989                 :    /* 7 */ {"ICED", "Ice divergence", "1/s", UC_NONE},
     990                 : };
     991                 : 
     992                 : /* GRIB2 Code table 4.2 : 10.3 */
     993                 : GRIB2ParmTable OceanSurface[] = {
     994                 :    /* 0 */ {"WTMP", "Water temperature", "K", UC_NONE},
     995                 :    /* 1 */ {"DSLM", "Deviation of sea level from mean", "m", UC_NONE},
     996                 : };
     997                 : 
     998                 : /* GRIB2 Code table 4.2 : 10.4 */
     999                 : GRIB2ParmTable OceanSubSurface[] = {
    1000                 :    /* 0 */ {"MTHD", "Main thermocline depth", "m", UC_NONE},
    1001                 :    /* 1 */ {"MTHA", "Main thermocline anomaly", "m", UC_NONE},
    1002                 :    /* 2 */ {"TTHDP", "Transient thermocline depth", "m", UC_NONE},
    1003                 :    /* 3 */ {"SALTY", "Salinity", "kg/kg", UC_NONE},
    1004                 : };
    1005                 : 
    1006                 : /* *INDENT-ON* */
    1007                 : 
    1008                 : /*****************************************************************************
    1009                 :  * Choose_GRIB2ParmTable() --
    1010                 :  *
    1011                 :  * Arthur Taylor / MDL
    1012                 :  *
    1013                 :  * PURPOSE
    1014                 :  *   Chooses the correct Parameter table depending on what is in the GRIB2
    1015                 :  * message's "Product Definition Section".
    1016                 :  *
    1017                 :  * ARGUMENTS
    1018                 :  * prodType = The product type (meteo, hydro, land, space, ocean, etc) (In)
    1019                 :  *      cat = The category inside the product (Input)
    1020                 :  * tableLen = The length of the returned table (Output)
    1021                 :  *
    1022                 :  * FILES/DATABASES: None
    1023                 :  *
    1024                 :  * RETURNS: ParmTable (appropriate parameter table.)
    1025                 :  *
    1026                 :  * HISTORY
    1027                 :  *   1/2004 Arthur Taylor (MDL/RSIS): Created
    1028                 :  *
    1029                 :  * NOTES
    1030                 :  *****************************************************************************
    1031                 :  */
    1032               4 : static GRIB2ParmTable *Choose_GRIB2ParmTable (int prodType, int cat,
    1033                 :                                               size_t *tableLen)
    1034                 : {
    1035                 :    enum { METEO_TEMP = 0, METEO_MOIST = 1, METEO_MOMENT = 2, METEO_MASS = 3,
    1036                 :       METEO_SW_RAD = 4, METEO_LW_RAD = 5, METEO_CLOUD = 6,
    1037                 :       METEO_THERMO_INDEX = 7, METEO_KINEMATIC_INDEX = 8, METEO_TEMP_PROB = 9,
    1038                 :       METEO_MOISTURE_PROB = 10, METEO_MOMENT_PROB = 11, METEO_MASS_PROB = 12,
    1039                 :       METEO_AEROSOL = 13, METEO_GAS = 14, METEO_RADAR = 15,
    1040                 :       METEO_RADAR_IMAGERY = 16, METEO_ELECTRO = 17, METEO_NUCLEAR = 18,
    1041                 :       METEO_ATMOS = 19, METEO_CCITT = 190, METEO_MISC = 191,
    1042                 :       METEO_CCITT2 = 253
    1043                 :    };
    1044                 :    enum { HYDRO_BASIC = 0, HYDRO_PROB = 1 };
    1045                 :    enum { LAND_VEG = 0, LAND_SOIL = 3 };
    1046                 :    enum { SPACE_IMAGE = 0, SPACE_QUANTIT = 1 };
    1047                 :    enum { OCEAN_WAVES = 0, OCEAN_CURRENTS = 1, OCEAN_ICE = 2, OCEAN_SURF = 3,
    1048                 :       OCEAN_SUBSURF = 4
    1049                 :    };
    1050                 : 
    1051               4 :    switch (prodType) {
    1052                 :       case 0:          /* Meteo type. */
    1053               4 :          switch (cat) {
    1054                 :             case METEO_TEMP:
    1055               4 :                *tableLen = sizeof (MeteoTemp) / sizeof (GRIB2ParmTable);
    1056               4 :                return &MeteoTemp[0];
    1057                 :             case METEO_MOIST:
    1058               0 :                *tableLen = sizeof (MeteoMoist) / sizeof (GRIB2ParmTable);
    1059               0 :                return &MeteoMoist[0];
    1060                 :             case METEO_MOMENT:
    1061               0 :                *tableLen = sizeof (MeteoMoment) / sizeof (GRIB2ParmTable);
    1062               0 :                return &MeteoMoment[0];
    1063                 :             case METEO_MASS:
    1064               0 :                *tableLen = sizeof (MeteoMass) / sizeof (GRIB2ParmTable);
    1065               0 :                return &MeteoMass[0];
    1066                 :             case METEO_SW_RAD:
    1067                 :                *tableLen = (sizeof (MeteoShortRadiate) /
    1068               0 :                             sizeof (GRIB2ParmTable));
    1069               0 :                return &MeteoShortRadiate[0];
    1070                 :             case METEO_LW_RAD:
    1071                 :                *tableLen = (sizeof (MeteoLongRadiate) /
    1072               0 :                             sizeof (GRIB2ParmTable));
    1073               0 :                return &MeteoLongRadiate[0];
    1074                 :             case METEO_CLOUD:
    1075               0 :                *tableLen = sizeof (MeteoCloud) / sizeof (GRIB2ParmTable);
    1076               0 :                return &MeteoCloud[0];
    1077                 :             case METEO_THERMO_INDEX:
    1078               0 :                *tableLen = sizeof (MeteoStability) / sizeof (GRIB2ParmTable);
    1079               0 :                return &MeteoStability[0];
    1080                 :             case METEO_KINEMATIC_INDEX:
    1081                 :             case METEO_TEMP_PROB:
    1082                 :             case METEO_MOISTURE_PROB:
    1083                 :             case METEO_MOMENT_PROB:
    1084                 :             case METEO_MASS_PROB:
    1085               0 :                *tableLen = 0;
    1086               0 :                return NULL;
    1087                 :             case METEO_AEROSOL:
    1088               0 :                *tableLen = sizeof (MeteoAerosols) / sizeof (GRIB2ParmTable);
    1089               0 :                return &MeteoAerosols[0];
    1090                 :             case METEO_GAS:
    1091               0 :                *tableLen = sizeof (MeteoGases) / sizeof (GRIB2ParmTable);
    1092               0 :                return &MeteoGases[0];
    1093                 :             case METEO_RADAR:
    1094               0 :                *tableLen = sizeof (MeteoRadar) / sizeof (GRIB2ParmTable);
    1095               0 :                return &MeteoRadar[0];
    1096                 :             case METEO_RADAR_IMAGERY:
    1097                 :             case METEO_ELECTRO:
    1098               0 :                *tableLen = 0;
    1099               0 :                return NULL;
    1100                 :             case METEO_NUCLEAR:
    1101               0 :                *tableLen = sizeof (MeteoNuclear) / sizeof (GRIB2ParmTable);
    1102               0 :                return &MeteoNuclear[0];
    1103                 :             case METEO_ATMOS:
    1104               0 :                *tableLen = sizeof (MeteoAtmos) / sizeof (GRIB2ParmTable);
    1105               0 :                return &MeteoAtmos[0];
    1106                 :             case METEO_CCITT:
    1107                 :             case METEO_CCITT2:
    1108               0 :                *tableLen = sizeof (MeteoText) / sizeof (GRIB2ParmTable);
    1109               0 :                return &MeteoText[0];
    1110                 :             case METEO_MISC:
    1111               0 :                *tableLen = sizeof (MeteoMisc) / sizeof (GRIB2ParmTable);
    1112               0 :                return &MeteoMisc[0];
    1113                 :             default:
    1114               0 :                *tableLen = 0;
    1115               0 :                return NULL;
    1116                 :          }
    1117                 :       case 1:          /* Hydro type. */
    1118               0 :          switch (cat) {
    1119                 :             case HYDRO_BASIC:
    1120               0 :                *tableLen = sizeof (HydroBasic) / sizeof (GRIB2ParmTable);
    1121               0 :                return &HydroBasic[0];
    1122                 :             case HYDRO_PROB:
    1123               0 :                *tableLen = sizeof (HydroProb) / sizeof (GRIB2ParmTable);
    1124               0 :                return &HydroProb[0];
    1125                 :             default:
    1126               0 :                *tableLen = 0;
    1127               0 :                return NULL;
    1128                 :          }
    1129                 :       case 2:          /* Land type. */
    1130               0 :          switch (cat) {
    1131                 :             case LAND_VEG:
    1132               0 :                *tableLen = sizeof (LandVeg) / sizeof (GRIB2ParmTable);
    1133               0 :                return &LandVeg[0];
    1134                 :             case LAND_SOIL:
    1135               0 :                *tableLen = sizeof (LandSoil) / sizeof (GRIB2ParmTable);
    1136               0 :                return &LandSoil[0];
    1137                 :             default:
    1138               0 :                *tableLen = 0;
    1139               0 :                return NULL;
    1140                 :          }
    1141                 :       case 3:          /* Space type. */
    1142               0 :          switch (cat) {
    1143                 :             case SPACE_IMAGE:
    1144               0 :                *tableLen = sizeof (SpaceImage) / sizeof (GRIB2ParmTable);
    1145               0 :                return &SpaceImage[0];
    1146                 :             case SPACE_QUANTIT:
    1147                 :                *tableLen = (sizeof (SpaceQuantitative) /
    1148               0 :                             sizeof (GRIB2ParmTable));
    1149               0 :                return &SpaceQuantitative[0];
    1150                 :             default:
    1151               0 :                *tableLen = 0;
    1152               0 :                return NULL;
    1153                 :          }
    1154                 :       case 10:         /* ocean type. */
    1155               0 :          switch (cat) {
    1156                 :             case OCEAN_WAVES:
    1157               0 :                *tableLen = sizeof (OceanWaves) / sizeof (GRIB2ParmTable);
    1158               0 :                return &OceanWaves[0];
    1159                 :             case OCEAN_CURRENTS:
    1160               0 :                *tableLen = sizeof (OceanCurrents) / sizeof (GRIB2ParmTable);
    1161               0 :                return &OceanCurrents[0];
    1162                 :             case OCEAN_ICE:
    1163               0 :                *tableLen = sizeof (OceanIce) / sizeof (GRIB2ParmTable);
    1164               0 :                return &OceanIce[0];
    1165                 :             case OCEAN_SURF:
    1166               0 :                *tableLen = sizeof (OceanSurface) / sizeof (GRIB2ParmTable);
    1167               0 :                return &OceanSurface[0];
    1168                 :             default:
    1169               0 :                *tableLen = 0;
    1170               0 :                return NULL;
    1171                 :          }
    1172                 :       default:
    1173               0 :          *tableLen = 0;
    1174               0 :          return NULL;
    1175                 :    }
    1176                 : }
    1177                 : 
    1178                 : /* *INDENT-OFF* */
    1179                 : NDFD_AbrevOverideTable NDFD_Overide[] = {
    1180                 :    /*  0 */ {"TMP", "T"},
    1181                 :    /*  1 */ {"TMAX", "MaxT"},
    1182                 :    /*  2 */ {"TMIN", "MinT"},
    1183                 :    /*  3 */ {"DPT", "Td"},
    1184                 :    /*  4 */ {"APCP", "QPF"},
    1185                 :    /* Don't need SNOD for now. */
    1186                 :    /*  5 */ /* {"SNOD", "SnowDepth"}, */
    1187                 :    /*  6 */ {"WDIR", "WindDir"},
    1188                 :    /*  7 */ {"WIND", "WindSpd"},
    1189                 :    /*  8 */ {"TCDC", "Sky"},
    1190                 :    /*  9 */ {"WVHGT", "WaveHeight"},
    1191                 :    /* 10 */ {"ASNOW", "SnowAmt"},
    1192                 :    /* 11 */ {"GUST", "WindGust"},
    1193                 : };
    1194                 : 
    1195                 : GRIB2LocalTable NDFD_LclTable[] = {
    1196                 :    /* 0 */ {0, 1, 192, "Wx", "Weather string", "-", UC_NONE},
    1197                 :    /* 1 */ {0, 0, 193, "ApparentT", "Apparent Temperature", "K", UC_K2F},
    1198                 :    /* 2 */ {0, 14, 192, "O3MR", "Ozone Mixing Ratio", "kg/kg", UC_NONE},
    1199                 :    /* 3 */ {0, 14, 193, "OZCON", "Ozone Concentration", "PPB", UC_NONE},
    1200                 :    /* grandfather'ed in a NDFD choice for POP. */
    1201                 :    /* 4 */ {0, 10, 8, "PoP12", "Prob of 0.01 In. of Precip", "%", UC_NONE},
    1202                 :            {0, 13, 194, "smokes", "Surface level smoke from fires",
    1203                 :             "log10(µg/m^3)", UC_LOG10},
    1204                 :            {0, 13, 195, "smokec", "Average vertical column smoke from fires",
    1205                 :             "log10(µg/m^3)", UC_LOG10},
    1206                 :    /* Arthur Added this to both NDFD and NCEP local tables. (5/1/2006) */
    1207                 :            {10, 3, 192, "Surge", "Hurricane Storm Surge", "m", UC_M2Feet},
    1208                 :            {10, 3, 193, "ETSurge", "Extra Tropical Storm Surge", "m", UC_M2Feet},
    1209                 : };
    1210                 : 
    1211                 : GRIB2LocalTable HPC_LclTable[] = {
    1212                 :    /* 0 */ {0, 1, 192, "HPC-Wx", "HPC Code", "-", UC_NONE},
    1213                 : };
    1214                 : 
    1215                 : /*
    1216                 : Updated this table last on 12/29/2005
    1217                 : Based on:
    1218                 : http://www.nco.ncep.noaa.gov/pmb/docs/grib2/GRIB2_parmeter_conversion_table.html
    1219                 : Better source is:
    1220                 : http://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_table4-1.shtml
    1221                 : For abreviations see:
    1222                 : http://www.nco.ncep.noaa.gov/pmb/docs/on388/table2.html
    1223                 : 
    1224                 : Updated again on 2/14/2006
    1225                 : Updated again on 3/15/2006
    1226                 : */
    1227                 : GRIB2LocalTable NCEP_LclTable[] = {
    1228                 :    /*  0 */ {0, 0, 192, "SNOHF", "Snow Phase Change Heat Flux", "W/(m^2)", UC_NONE},
    1229                 :             {0, 0, 193, "TTRAD", "Temperature tendency by all radiation", "K/s", UC_NONE},
    1230                 : 
    1231                 :    /*  1 */ {0, 1, 192, "CRAIN", "Categorical Rain", "(0 no; 1 yes)", UC_NONE},
    1232                 :    /*  2 */ {0, 1, 193, "CFRZR", "Categorical Freezing Rain", "(0 no; 1 yes)", UC_NONE},
    1233                 :    /*  3 */ {0, 1, 194, "CICEP", "Categorical Ice Pellets", "(0 no; 1 yes)", UC_NONE},
    1234                 :    /*  4 */ {0, 1, 195, "CSNOW", "Categorical Snow", "(0 no; 1 yes)", UC_NONE},
    1235                 :    /*  5 */ {0, 1, 196, "CPRAT", "Convective Precipitation Rate", "kg/(m^2*s)", UC_NONE},
    1236                 :    /*  6 */ {0, 1, 197, "MCONV", "Horizontal Moisture Divergence", "kg/(kg*s)", UC_NONE},
    1237                 : /* Following was grandfathered in... Should use: 1, 1, 193 */
    1238                 :    /*  7 */ {0, 1, 198, "CPOFP", "Percent Frozen Precipitation", "%", UC_NONE},
    1239                 :    /*  8 */ {0, 1, 199, "PEVAP", "Potential Evaporation", "kg/(m^2)", UC_NONE},
    1240                 :    /*  9 */ {0, 1, 200, "PEVPR", "Potential Evaporation Rate", "W/(m^2)", UC_NONE},
    1241                 :    /* 10 */ {0, 1, 201, "SNOWC", "Snow Cover", "%", UC_NONE},
    1242                 :    /* 11 */ {0, 1, 202, "FRAIN", "Rain Fraction of Total Liquid Water", "-", UC_NONE},
    1243                 : /* FRIME -> RIME 12/29/2005 */
    1244                 :    /* 12 */ {0, 1, 203, "RIME", "Rime Factor", "-", UC_NONE},
    1245                 :    /* 13 */ {0, 1, 204, "TCOLR", "Total Column Integrated Rain", "kg/(m^2)", UC_NONE},
    1246                 :    /* 14 */ {0, 1, 205, "TCOLS", "Total Column Integrated Snow", "kg/(m^2)", UC_NONE},
    1247                 :             {0, 1, 206, "TIPD", "Total Icing Potential Diagnostic", "-", UC_NONE},
    1248                 :             {0, 1, 207, "NCIP", "Number concentration for ice particles", "-", UC_NONE},
    1249                 :             {0, 1, 208, "SNOT", "Snow temperature", "K", UC_NONE},
    1250                 : 
    1251                 :    /* 15 */ {0, 2, 192, "VWSH", "Vertical speed sheer", "1/s", UC_NONE},
    1252                 :    /* 16 */ {0, 2, 193, "MFLX", "Horizontal Momentum Flux", "N/(m^2)", UC_NONE},
    1253                 :    /* 17 */ {0, 2, 194, "USTM", "U-Component Storm Motion", "m/s", UC_NONE},
    1254                 :    /* 18 */ {0, 2, 195, "VSTM", "V-Component Storm Motion", "m/s", UC_NONE},
    1255                 :    /* 19 */ {0, 2, 196, "CD", "Drag Coefficient", "-", UC_NONE},
    1256                 :    /* 20 */ {0, 2, 197, "FRICV", "Frictional Velocity", "m/s", UC_NONE},
    1257                 : 
    1258                 :    /* 21 */ {0, 3, 192, "MSLET", "Mean Sea Level Pressure (Eta Reduction)", "Pa", UC_NONE},
    1259                 :    /* 22 */ {0, 3, 193, "5WAVH", "5-Wave Geopotential Height", "gpm", UC_NONE},
    1260                 :    /* 23 */ {0, 3, 194, "U-GWD", "Zonal Flux of Gravity Wave Stress", "N/(m^2)", UC_NONE},
    1261                 :    /* 24 */ {0, 3, 195, "V-GWD", "Meridional Flux of Gravity Wave Stress", "N/(m^2)", UC_NONE},
    1262                 :    /* 25 */ {0, 3, 196, "HPBL", "Planetary Boundary Layer Height", "m", UC_NONE},
    1263                 :    /* 26 */ {0, 3, 197, "5WAVA", "5-Wave Geopotential Height Anomaly", "gpm", UC_NONE},
    1264                 :             {0, 3, 198, "MSLMA", "Mean Sea Level Pressure (MAPS System Reduction)", "Pa", UC_NONE},
    1265                 :             {0, 3, 199, "TSLSA", "3-hr pressure tendency (Std. Atmos. Reduction)", "Pa/s", UC_NONE},
    1266                 :             {0, 3, 200, "PLPL", "Pressure of level from which parcel was lifted", "Pa", UC_NONE},
    1267                 : 
    1268                 :    /* 27 */ {0, 4, 192, "DSWRF", "Downward Short-Wave Rad. Flux", "W/(m^2)", UC_NONE},
    1269                 :    /* 28 */ {0, 4, 193, "USWRF", "Upward Short-Wave Rad. Flux", "W/(m^2)", UC_NONE},
    1270                 :             {0, 4, 194, "DUVB", "UV-B downward solar flux", "W/(m^2)", UC_NONE},
    1271                 :             {0, 4, 195, "CDUVB", "Clear sky UV-B downward solar flux", "W/(m^2)", UC_NONE},
    1272                 : 
    1273                 :    /* 29 */ {0, 5, 192, "DLWRF", "Downward Long-Wave Rad. Flux", "W/(m^2)", UC_NONE},
    1274                 :    /* 30 */ {0, 5, 193, "ULWRF", "Upward Long-Wave Rad. Flux", "W/(m^2)", UC_NONE},
    1275                 : 
    1276                 :    /* 31 */ {0, 6, 192, "CDLYR", "Non-Convective Cloud Cover", "%", UC_NONE},
    1277                 :    /* 32 */ {0, 6, 193, "CWORK", "Cloud Work Function", "J/kg", UC_NONE},
    1278                 :    /* 33 */ {0, 6, 194, "CUEFI", "Convective Cloud Efficiency", "-", UC_NONE},
    1279                 :    /* 34 */ {0, 6, 195, "TCOND", "Total Condensate", "kg/kg", UC_NONE},
    1280                 :    /* 35 */ {0, 6, 196, "TCOLW", "Total Column-Integrated Cloud Water", "kg/(m^2)", UC_NONE},
    1281                 :    /* 36 */ {0, 6, 197, "TCOLI", "Total Column-Integrated Cloud Ice", "kg/(m^2)", UC_NONE},
    1282                 :    /* 37 */ {0, 6, 198, "TCOLC", "Total Column-Integrated Condensate", "kg/(m^2)", UC_NONE},
    1283                 :    /* 38 */ {0, 6, 199, "FICE", "Ice fraction of total condensate", "-", UC_NONE},
    1284                 : 
    1285                 :    /* 39 */ {0, 7, 192, "LFTX", "Surface Lifted Index", "K", UC_NONE},
    1286                 :    /* 40 */ {0, 7, 193, "4LFTX", "Best (4 layer) Lifted Index", "K", UC_NONE},
    1287                 :    /* 41 */ {0, 7, 194, "RI", "Richardson Number", "-", UC_NONE},
    1288                 : 
    1289                 :             {0, 13, 192, "PMTC", "Particulate matter (coarse)", "µg/m^3", UC_NONE},
    1290                 :             {0, 13, 193, "PMTF", "Particulate matter (fine)", "µg/m^3", UC_NONE},
    1291                 :             {0, 13, 194, "LPMTF", "Particulate matter (fine)",
    1292                 :              "log10(µg/m^3)", UC_LOG10},
    1293                 :             {0, 13, 195, "LIPMF", "Integrated column particulate matter "
    1294                 :              "(fine)", "log10(µg/m^3)", UC_LOG10},
    1295                 : 
    1296                 :    /* 42 */ {0, 14, 192, "O3MR", "Ozone Mixing Ratio", "kg/kg", UC_NONE},
    1297                 :    /* 43 */ {0, 14, 193, "OZCON", "Ozone Concentration", "PPB", UC_NONE},
    1298                 :    /* 44 */ {0, 14, 194, "OZCAT", "Categorical Ozone Concentration", "-", UC_NONE},
    1299                 : 
    1300                 :             {0, 16, 192, "REFZR", "Derived radar reflectivity backscatter from rain", "mm^6/m^3", UC_NONE},
    1301                 :             {0, 16, 193, "REFZI", "Derived radar reflectivity backscatter from ice", "mm^6/m^3", UC_NONE},
    1302                 :             {0, 16, 194, "REFZC", "Derived radar reflectivity backscatter from parameterized convection", "mm^6/m^3", UC_NONE},
    1303                 :             {0, 16, 195, "REFD", "Derived radar reflectivity", "dB", UC_NONE},
    1304                 :             {0, 16, 196, "REFC", "Maximum / Composite radar reflectivity", "dB", UC_NONE},
    1305                 : 
    1306                 :             {0, 17, 192, "LTNG", "Lightning", "-", UC_NONE},
    1307                 : 
    1308                 :    /* 45 */ {0, 19, 192, "MXSALB", "Maximum Snow Albedo", "%", UC_NONE},
    1309                 :    /* 46 */ {0, 19, 193, "SNFALB", "Snow-Free Albedo", "%", UC_NONE},
    1310                 :             {0, 19, 194, "", "Slight risk convective outlook", "categorical", UC_NONE},
    1311                 :             {0, 19, 195, "", "Moderate risk convective outlook", "categorical", UC_NONE},
    1312                 :             {0, 19, 196, "", "High risk convective outlook", "categorical", UC_NONE},
    1313                 :             {0, 19, 197, "", "Tornado probability", "%", UC_NONE},
    1314                 :             {0, 19, 198, "", "Hail probability", "%", UC_NONE},
    1315                 :             {0, 19, 199, "", "Wind probability", "%", UC_NONE},
    1316                 :             {0, 19, 200, "", "Significant Tornado probability", "%", UC_NONE},
    1317                 :             {0, 19, 201, "", "Significant Hail probability", "%", UC_NONE},
    1318                 :             {0, 19, 202, "", "Significant Wind probability", "%", UC_NONE},
    1319                 :             {0, 19, 203, "TSTMC", "Categorical Thunderstorm", "0=no, 1=yes", UC_NONE},
    1320                 :             {0, 19, 204, "MIXLY", "Number of mixed layers next to surface", "integer", UC_NONE},
    1321                 : 
    1322                 :    /* 47 */ {0, 191, 192, "NLAT", "Latitude (-90 to 90)", "deg", UC_NONE},
    1323                 :    /* 48 */ {0, 191, 193, "ELON", "East Longitude (0 to 360)", "deg", UC_NONE},
    1324                 :    /* 49 */ {0, 191, 194, "TSEC", "Seconds prior to initial reference time", "s", UC_NONE},
    1325                 : 
    1326                 :    /* 50 */ {1, 0, 192, "BGRUN", "Baseflow-Groundwater Runoff", "kg/(m^2)", UC_NONE},
    1327                 :    /* 51 */ {1, 0, 193, "SSRUN", "Storm Surface Runoff", "kg/(m^2)", UC_NONE},
    1328                 : 
    1329                 :             {1, 1, 192, "CPOZP", "Probability of Freezing Precipitation", "%", UC_NONE},
    1330                 :             {1, 1, 193, "CPOFP", "Probability of Frozen Precipitation", "%", UC_NONE},
    1331                 :             {1, 1, 194, "PPFFG", "Probability of precipitation exceeding flash flood guidance values", "%", UC_NONE},
    1332                 : 
    1333                 :    /* 52 */ {2, 0, 192, "SOILW", "Volumetric Soil Moisture Content", "Fraction", UC_NONE},
    1334                 :    /* 53 */ {2, 0, 193, "GFLUX", "Ground Heat Flux", "W/(m^2)", UC_NONE},
    1335                 :    /* 54 */ {2, 0, 194, "MSTAV", "Moisture Availability", "%", UC_NONE},
    1336                 :    /* 55 */ {2, 0, 195, "SFEXC", "Exchange Coefficient", "(kg/(m^3))(m/s)", UC_NONE},
    1337                 :    /* 56 */ {2, 0, 196, "CNWAT", "Plant Canopy Surface Water", "kg/(m^2)", UC_NONE},
    1338                 :    /* 57 */ {2, 0, 197, "BMIXL", "Blackadar's Mixing Length Scale", "m", UC_NONE},
    1339                 :    /* 58 */ {2, 0, 198, "VGTYP", "Vegetation Type", "0..13", UC_NONE},
    1340                 :    /* 59 */ {2, 0, 199, "CCOND", "Canopy Conductance", "m/s", UC_NONE},
    1341                 :    /* 60 */ {2, 0, 200, "RSMIN", "Minimal Stomatal Resistance", "s/m", UC_NONE},
    1342                 :    /* 61 */ {2, 0, 201, "WILT", "Wilting Point", "Fraction", UC_NONE},
    1343                 :    /* 62 */ {2, 0, 202, "RCS", "Solar parameter in canopy conductance", "Fraction", UC_NONE},
    1344                 :    /* 63 */ {2, 0, 203, "RCT", "Temperature parameter in canopy conductance", "Fraction", UC_NONE},
    1345                 :    /* 64 */ {2, 0, 204, "RCQ", "Humidity parameter in canopy conductance", "Fraction", UC_NONE},
    1346                 :    /* 65 */ {2, 0, 205, "RCSOL", "Soil moisture parameter in canopy conductance", "Fraction", UC_NONE},
    1347                 :             {2, 0, 206, "RDRIP", "Rate of water dropping from canopy to ground", "unknown", UC_NONE},
    1348                 :             {2, 0, 207, "ICWAT", "Ice-free water surface", "%", UC_NONE},
    1349                 : 
    1350                 :    /* 66 */ {2, 3, 192, "SOILL", "Liquid Volumetric Soil Moisture (non Frozen)", "Proportion", UC_NONE},
    1351                 :    /* 67 */ {2, 3, 193, "RLYRS", "Number of Soil Layers in Root Zone", "-", UC_NONE},
    1352                 :    /* 68 */ {2, 3, 194, "SLTYP", "Surface Slope Type", "Index", UC_NONE},
    1353                 :    /* 69 */ {2, 3, 195, "SMREF", "Transpiration Stress-onset (soil moisture)", "Proportion", UC_NONE},
    1354                 :    /* 70 */ {2, 3, 196, "SMDRY", "Direct Evaporation Cease (soil moisture)", "Proportion", UC_NONE},
    1355                 :    /* 71 */ {2, 3, 197, "POROS", "Soil Porosity", "Proportion", UC_NONE},
    1356                 : 
    1357                 : /* ScatEstUWind -> USCT, ScatEstVWind -> VSCT as of 7/5/2006 (pre 1.80) */
    1358                 :    /* 72 */ {3, 1, 192, "USCT", "Scatterometer Estimated U Wind", "m/s", UC_NONE},
    1359                 :    /* 73 */ {3, 1, 193, "VSCT", "Scatterometer Estimated V Wind", "m/s", UC_NONE},
    1360                 : 
    1361                 :    /* Arthur Added this to both NDFD and NCEP local tables. (5/1/2006) */
    1362                 :            {10, 3, 192, "SURGE", "Hurricane Storm Surge", "m", UC_M2Feet},
    1363                 :            {10, 3, 193, "ETSRG", "Extra Tropical Storm Surge", "m", UC_M2Feet},
    1364                 : };
    1365                 : /* *INDENT-ON* */
    1366                 : 
    1367               4 : int IsData_NDFD (unsigned short int center, unsigned short int subcenter)
    1368                 : {
    1369                 :    return ((center == 8) &&
    1370               4 :            ((subcenter == GRIB2MISSING_u2) || (subcenter == 0)));
    1371                 : }
    1372                 : 
    1373               0 : int IsData_MOS (unsigned short int center, unsigned short int subcenter)
    1374                 : {
    1375               0 :    return ((center == 7) && (subcenter == 14));
    1376                 : }
    1377                 : 
    1378                 : /*****************************************************************************
    1379                 :  * Choose_LocalParmTable() --
    1380                 :  *
    1381                 :  * Arthur Taylor / MDL
    1382                 :  *
    1383                 :  * PURPOSE
    1384                 :  *   Chooses the local parameter table for a given center/subcenter.
    1385                 :  * Typically this is called after the default Choose_ParmTable was tried,
    1386                 :  * since it consists of all the local specs, and one has to linearly walk
    1387                 :  * through the table.
    1388                 :  *
    1389                 :  * ARGUMENTS
    1390                 :  *    center = The center that created the data. (Input)
    1391                 :  * subcenter = The subcenter that created the data. (Input)
    1392                 :  *  tableLen = The length of the returned table (Output)
    1393                 :  *
    1394                 :  * FILES/DATABASES: None
    1395                 :  *
    1396                 :  * RETURNS: LocalParmTable (appropriate parameter table.)
    1397                 :  *
    1398                 :  * HISTORY
    1399                 :  *   1/2004 Arthur Taylor (MDL/RSIS): Created
    1400                 :  *
    1401                 :  * NOTES
    1402                 :  *****************************************************************************
    1403                 :  */
    1404               0 : static GRIB2LocalTable *Choose_LocalParmTable (unsigned short int center,
    1405                 :                                                unsigned short int subcenter,
    1406                 :                                                size_t *tableLen)
    1407                 : {
    1408               0 :    switch (center) {
    1409                 :       case 7:          /* NWS NCEP */
    1410                 :          /* Check if all subcenters of NCEP use the same local table. */
    1411                 : /*
    1412                 :          *tableLen = sizeof (NCEP_LclTable) / sizeof (GRIB2LocalTable);
    1413                 :          return &NCEP_LclTable[0];
    1414                 : */
    1415               0 :          switch (subcenter) {
    1416                 :             case 5:    /* Have HPC use NDFD table. */
    1417               0 :                *tableLen = sizeof (HPC_LclTable) / sizeof (GRIB2LocalTable);
    1418               0 :                return &HPC_LclTable[0];
    1419                 :             default:
    1420               0 :                *tableLen = sizeof (NCEP_LclTable) / sizeof (GRIB2LocalTable);
    1421               0 :                return &NCEP_LclTable[0];
    1422                 : /*
    1423                 :                *tableLen = 0;
    1424                 :                return NULL;
    1425                 : */
    1426                 :          }
    1427                 :       case 8:          /* NWS Telecomunications gateway */
    1428               0 :          switch (subcenter) {
    1429                 :             case GRIB2MISSING_u2: /* NDFD */
    1430                 :             case 0:    /* NDFD */
    1431               0 :                *tableLen = sizeof (NDFD_LclTable) / sizeof (GRIB2LocalTable);
    1432               0 :                return &NDFD_LclTable[0];
    1433                 :             default:
    1434               0 :                *tableLen = 0;
    1435               0 :                return NULL;
    1436                 :          }
    1437                 :       default:
    1438               0 :          *tableLen = 0;
    1439               0 :          return NULL;
    1440                 :    }
    1441                 : }
    1442                 : 
    1443                 : /*****************************************************************************
    1444                 :  * ParseElemName() --
    1445                 :  *
    1446                 :  * Arthur Taylor / MDL
    1447                 :  *
    1448                 :  * PURPOSE
    1449                 :  *   Converts a prodType, template, category and subcategory quadruple to the
    1450                 :  * ASCII string abreviation of that variable.
    1451                 :  *   For example: 0, 0, 0, 0, = "T" for temperature.
    1452                 :  *
    1453                 :  * ARGUMENTS
    1454                 :  *    center = The center that created the data. (Input)
    1455                 :  * subcenter = The subcenter that created the data. (Input)
    1456                 :  *  prodType = The GRIB2, section 0 product type. (Input)
    1457                 :  *   templat = The GRIB2 section 4 template number. (Input)
    1458                 :  *       cat = The GRIB2 section 4 "General category of Product." (Input)
    1459                 :  *    subcat = The GRIB2 section 4 "Specific subcategory of Product". (Input)
    1460                 :  *   lenTime = The length of time over which statistics are done
    1461                 :  *             (see template 4.8). (Input)
    1462                 :  *     genID = The Generating process ID (used for GFS MOS) (Input)
    1463                 :  *  probType = For Probability templates (Input)
    1464                 :  * lowerProb = Lower Limit for probability templates. (Input)
    1465                 :  * upperProb = Upper Limit for probability templates. (Input)
    1466                 :  *      name = Short name for the data set (T, MaxT, etc) (Output)
    1467                 :  *   comment = Long form of the name (Temperature, etc) (Output)
    1468                 :  *      unit = What unit this variable is originally in (Output)
    1469                 :  *
    1470                 :  * FILES/DATABASES: None
    1471                 :  *
    1472                 :  * RETURNS: void
    1473                 :  *
    1474                 :  * HISTORY
    1475                 :  *   1/2004 Arthur Taylor (MDL/RSIS): Re-Created.
    1476                 :  *   6/2004 AAT: Added deltTime (because of Ozone issues).
    1477                 :  *   8/2004 AAT: Adjusted so template 9 gets units of % and no convert.
    1478                 :  *   3/2005 AAT: ReWrote to handle template 5, 9 and MOS.
    1479                 :  *   9/2005 AAT: Added code to handle MOS PoP06 vs MOS PoP12.
    1480                 :  *
    1481                 :  * NOTES
    1482                 :  *****************************************************************************
    1483                 :  */
    1484                 : /* Deal with probability templates 2/16/2006 */
    1485               0 : static void ElemNameProb (uShort2 center, uShort2 subcenter, int prodType,
    1486                 :                           int templat, uChar cat, uChar subcat, sInt4 lenTime,
    1487                 :                           uChar timeIncrType, uChar genID, uChar probType,
    1488                 :                           double lowerProb, double upperProb, char **name,
    1489                 :                           char **comment, char **unit, int *convert)
    1490                 : {
    1491                 :    GRIB2ParmTable *table;
    1492                 :    GRIB2LocalTable *local;
    1493                 :    size_t tableLen;
    1494                 :    size_t i;
    1495               0 :    char f_isNdfd = IsData_NDFD (center, subcenter);
    1496               0 :    char f_isMos = IsData_MOS (center, subcenter);
    1497                 : 
    1498               0 :    *unit = (char *) malloc (strlen ("[%]") + 1);
    1499               0 :    strcpy (*unit, "[%]");
    1500                 : 
    1501               0 :    if (f_isNdfd || f_isMos) {
    1502                 :       /* Deal with NDFD/MOS handling of Prob Precip_Tot -> PoP12 */
    1503               0 :       if ((prodType == 0) && (cat == 1) && (subcat == 8)) {
    1504               0 :          myAssert (probType == 1);
    1505               0 :          if (lenTime > 0) {
    1506               0 :             mallocSprintf (name, "PoP%02d", lenTime);
    1507                 :             mallocSprintf (comment, "%02d hr Prob of Precip > 0.01 "
    1508               0 :                            "In. [%%]", lenTime);
    1509                 :          } else {
    1510               0 :             *name = (char *) malloc (strlen ("PoP") + 1);
    1511               0 :             strcpy (*name, "PoP");
    1512                 :             *comment =
    1513                 :                   (char *) malloc (strlen ("Prob of Precip > 0.01 In. [%]") +
    1514               0 :                                    1);
    1515               0 :             strcpy (*comment, "Prob of Precip > 0.01 In. [%]");
    1516                 :          }
    1517               0 :          *convert = UC_NONE;
    1518               0 :          return;
    1519                 :       }
    1520                 :       /* 
    1521                 :        * Deal with NDFD handling of Prob. Wind speeds.
    1522                 :        * There are different solutions for naming the Prob. Wind fields
    1523                 :        * AAT(Mine): ProbSurge5c
    1524                 :        */
    1525               0 :       if ((prodType == 10) && (cat == 3) && (subcat == 192)) {
    1526               0 :          myAssert (probType == 1);
    1527               0 :          myAssert (lenTime > 0);
    1528               0 :          if (timeIncrType == 2) {
    1529                 :             /* Incremental */
    1530                 :             mallocSprintf (name, "ProbSurge%02di",
    1531               0 :                            (int) ((upperProb / 0.3048) + .5));
    1532                 :          } else {
    1533                 :             /* Cumulative */
    1534               0 :             myAssert (timeIncrType == 192);
    1535                 :             mallocSprintf (name, "ProbSurge%02dc",
    1536               0 :                            (int) ((upperProb / 0.3048) + .5));
    1537                 :          }
    1538                 :          mallocSprintf (comment, "%02d hr Prob of Hurricane Storm Surge > %g "
    1539               0 :                         "m [%%]", lenTime, upperProb);
    1540               0 :          *convert = UC_NONE;
    1541               0 :          return;
    1542                 :       }
    1543                 :    }
    1544               0 :    if (f_isNdfd) {
    1545                 :       /* 
    1546                 :        * Deal with NDFD handling of Prob. Wind speeds.
    1547                 :        * There are different solutions for naming the Prob. Wind fields
    1548                 :        * Tim Boyer: TCWindSpdIncr34 TCWindSpdIncr50 TCWindSpdIncr64
    1549                 :        *            TCWindSpdCumu34 TCWindSpdCumu50 TCWindSpdCumu64
    1550                 :        * Dave Ruth: tcwspdabv34i tcwspdabv50i tcwspdabv64i
    1551                 :        *            tcwspdabv34c tcwspdabv50c tcwspdabv64c
    1552                 :        * AAT(Mine): ProbWindSpd34c ProbWindSpd50c ProbWindSpd64c
    1553                 :        *            ProbWindSpd34i ProbWindSpd50i ProbWindSpd64i
    1554                 :        */
    1555               0 :       if ((prodType == 0) && (cat == 2) && (subcat == 1)) {
    1556               0 :          myAssert (probType == 1);
    1557               0 :          myAssert (lenTime > 0);
    1558               0 :          if (timeIncrType == 2) {
    1559                 :             /* Incremental */
    1560                 :             mallocSprintf (name, "ProbWindSpd%02di",
    1561               0 :                            (int) ((upperProb * 3600. / 1852.) + .5));
    1562                 :          } else {
    1563                 :             /* Cumulative */
    1564               0 :             myAssert (timeIncrType == 192);
    1565                 :             mallocSprintf (name, "ProbWindSpd%02dc",
    1566               0 :                            (int) ((upperProb * 3600. / 1852.) + .5));
    1567                 :          }
    1568                 :          mallocSprintf (comment, "%02d hr Prob of Wind speed > %g m/s [%%]",
    1569               0 :                         lenTime, upperProb);
    1570               0 :          *convert = UC_NONE;
    1571               0 :          return;
    1572                 :       }
    1573                 :    }
    1574                 : 
    1575                 :    /* Generic tables. */
    1576               0 :    table = Choose_GRIB2ParmTable (prodType, cat, &tableLen);
    1577               0 :    if (table != NULL) {
    1578               0 :       if (subcat < tableLen) {
    1579                 :          /* Check for NDFD over-rides. */
    1580                 :          /* The NDFD over-rides for probability templates have already been
    1581                 :           * handled. */
    1582               0 :          if (lenTime > 0) {
    1583               0 :             mallocSprintf (name, "Prob%s%02d", table[subcat].name, lenTime);
    1584                 :             mallocSprintf (comment, "%02d hr Prob of %s ", lenTime,
    1585               0 :                            table[subcat].comment);
    1586                 :          } else {
    1587               0 :             mallocSprintf (name, "Prob%s", table[subcat].name);
    1588               0 :             mallocSprintf (comment, "Prob of %s ", table[subcat].comment);
    1589                 :          }
    1590               0 :          if (probType == 0) {
    1591                 :             reallocSprintf (comment, "< %g %s [%%]", lowerProb,
    1592               0 :                             table[subcat].unit);
    1593               0 :          } else if (probType == 1) {
    1594                 :             reallocSprintf (comment, "> %g %s [%%]", upperProb,
    1595               0 :                             table[subcat].unit);
    1596               0 :          } else if (probType == 2) {
    1597                 :             reallocSprintf (comment, ">= %g, < %g %s [%%]", lowerProb,
    1598               0 :                             upperProb, table[subcat].unit);
    1599               0 :          } else if (probType == 3) {
    1600                 :             reallocSprintf (comment, "> %g %s [%%]", lowerProb,
    1601               0 :                             table[subcat].unit);
    1602               0 :          } else if (probType == 4) {
    1603                 :             reallocSprintf (comment, "< %g %s [%%]", upperProb,
    1604               0 :                             table[subcat].unit);
    1605                 :          } else {
    1606               0 :             reallocSprintf (comment, "%s [%%]", table[subcat].unit);
    1607                 :          }
    1608               0 :          *convert = UC_NONE;
    1609               0 :          return;
    1610                 :       }
    1611                 :    }
    1612                 : 
    1613                 :    /* Local use tables. */
    1614               0 :    local = Choose_LocalParmTable (center, subcenter, &tableLen);
    1615               0 :    if (local != NULL) {
    1616               0 :       for (i = 0; i < tableLen; i++) {
    1617               0 :          if ((prodType == local[i].prodType) && (cat == local[i].cat) &&
    1618               0 :              (subcat == local[i].subcat)) {
    1619               0 :             if (lenTime > 0) {
    1620               0 :                mallocSprintf (name, "Prob%s%02d", local[i].name, lenTime);
    1621                 :                mallocSprintf (comment, "%02d hr Prob of %s ", lenTime,
    1622               0 :                               local[i].comment);
    1623                 :             } else {
    1624               0 :                mallocSprintf (name, "Prob%s", local[i].name);
    1625               0 :                mallocSprintf (comment, "Prob of %s ", local[i].comment);
    1626                 :             }
    1627               0 :             if (probType == 0) {
    1628                 :                reallocSprintf (comment, "< %g %s [%%]", lowerProb,
    1629               0 :                                local[i].unit);
    1630               0 :             } else if (probType == 1) {
    1631                 :                reallocSprintf (comment, "> %g %s [%%]", upperProb,
    1632               0 :                                local[i].unit);
    1633               0 :             } else if (probType == 2) {
    1634                 :                reallocSprintf (comment, ">= %g, < %g %s [%%]", lowerProb,
    1635               0 :                                upperProb, local[i].unit);
    1636               0 :             } else if (probType == 3) {
    1637                 :                reallocSprintf (comment, "> %g %s [%%]", lowerProb,
    1638               0 :                                local[i].unit);
    1639               0 :             } else if (probType == 4) {
    1640                 :                reallocSprintf (comment, "< %g %s [%%]", upperProb,
    1641               0 :                                local[i].unit);
    1642                 :             } else {
    1643               0 :                reallocSprintf (comment, "%s [%%]", local[i].unit);
    1644                 :             }
    1645               0 :             *convert = UC_NONE;
    1646               0 :             return;
    1647                 :          }
    1648                 :       }
    1649                 :    }
    1650                 : 
    1651               0 :    *name = (char *) malloc (strlen ("ProbUnknown") + 1);
    1652               0 :    strcpy (*name, "ProbUnknown");
    1653                 :    mallocSprintf (comment, "Prob of (prodType %d, cat %d, subcat %d) [-]",
    1654               0 :                   prodType, cat, subcat);
    1655               0 :    *convert = UC_NONE;
    1656               0 :    return;
    1657                 : }
    1658                 : 
    1659                 : /* Deal with percentile templates 5/1/2006 */
    1660               0 : static void ElemNamePerc (uShort2 center, uShort2 subcenter, int prodType,
    1661                 :                           int templat, uChar cat, uChar subcat, sInt4 lenTime,
    1662                 :                           sChar percentile, char **name, char **comment,
    1663                 :                           char **unit, int *convert)
    1664                 : {
    1665                 :    GRIB2ParmTable *table;
    1666                 :    GRIB2LocalTable *local;
    1667                 :    size_t tableLen;
    1668                 :    size_t i;
    1669                 : 
    1670                 :    /* Generic tables. */
    1671               0 :    table = Choose_GRIB2ParmTable (prodType, cat, &tableLen);
    1672               0 :    if (table != NULL) {
    1673               0 :       if (subcat < tableLen) {
    1674                 :          /* Check for NDFD over-rides. */
    1675               0 :          if (IsData_NDFD (center, subcenter) ||
    1676                 :              IsData_MOS (center, subcenter)) {
    1677               0 :             for (i = 0; i < (sizeof (NDFD_Overide) /
    1678                 :                              sizeof (NDFD_AbrevOverideTable)); i++) {
    1679               0 :                if (strcmp (NDFD_Overide[i].GRIB2name, table[subcat].name) ==
    1680                 :                    0) {
    1681                 :                   mallocSprintf (name, "%s%02d", NDFD_Overide[i].NDFDname,
    1682               0 :                                  percentile);
    1683               0 :                   if (lenTime > 0) {
    1684                 :                      mallocSprintf (comment, "%02d hr %s Percentile(%d) [%s]",
    1685               0 :                                     lenTime, table[subcat].comment,
    1686               0 :                                     percentile, table[subcat].unit);
    1687                 :                   } else {
    1688                 :                      mallocSprintf (comment, "%s Percentile(%d) [%s]",
    1689               0 :                                     table[subcat].comment, percentile,
    1690               0 :                                     table[subcat].unit);
    1691                 :                   }
    1692               0 :                   mallocSprintf (unit, "[%s]", table[subcat].unit);
    1693               0 :                   *convert = table[subcat].convert;
    1694               0 :                   return;
    1695                 :                }
    1696                 :             }
    1697                 :          }
    1698               0 :          mallocSprintf (name, "%s%02d", table[subcat].name, percentile);
    1699               0 :          if (lenTime > 0) {
    1700                 :             mallocSprintf (comment, "%02d hr %s Percentile(%d) [%s]",
    1701               0 :                            lenTime, table[subcat].comment, percentile,
    1702               0 :                            table[subcat].unit);
    1703                 :          } else {
    1704                 :             mallocSprintf (comment, "%s Percentile(%d) [%s]",
    1705               0 :                            table[subcat].comment, percentile,
    1706               0 :                            table[subcat].unit);
    1707                 :          }
    1708               0 :          mallocSprintf (unit, "[%s]", table[subcat].unit);
    1709               0 :          *convert = table[subcat].convert;
    1710               0 :          return;
    1711                 :       }
    1712                 :    }
    1713                 : 
    1714                 :    /* Local use tables. */
    1715               0 :    local = Choose_LocalParmTable (center, subcenter, &tableLen);
    1716               0 :    if (local != NULL) {
    1717               0 :       for (i = 0; i < tableLen; i++) {
    1718               0 :          if ((prodType == local[i].prodType) && (cat == local[i].cat) &&
    1719               0 :              (subcat == local[i].subcat)) {
    1720               0 :             mallocSprintf (name, "%s%02d", local[i].name, percentile);
    1721               0 :             if (lenTime > 0) {
    1722                 :                mallocSprintf (comment, "%02d hr %s Percentile(%d) [%s]",
    1723               0 :                               lenTime, local[i].comment, percentile,
    1724               0 :                               local[i].unit);
    1725                 :             } else {
    1726                 :                mallocSprintf (comment, "%s Percentile(%d) [%s]",
    1727               0 :                               local[i].comment, percentile, local[i].unit);
    1728                 :             }
    1729               0 :             mallocSprintf (unit, "[%s]", local[i].unit);
    1730               0 :             *convert = local[i].convert;
    1731               0 :             return;
    1732                 :          }
    1733                 :       }
    1734                 :    }
    1735                 : 
    1736               0 :    *name = (char *) malloc (strlen ("unknown") + 1);
    1737               0 :    strcpy (*name, "unknown");
    1738                 :    mallocSprintf (comment, "(prodType %d, cat %d, subcat %d) [-]", prodType,
    1739               0 :                   cat, subcat);
    1740               0 :    *unit = (char *) malloc (strlen ("[-]") + 1);
    1741               0 :    strcpy (*unit, "[-]");
    1742               0 :    *convert = UC_NONE;
    1743               0 :    return;
    1744                 : }
    1745                 : 
    1746                 : /* Deal with non-prob templates 2/16/2006 */
    1747               4 : static void ElemNameNorm (uShort2 center, uShort2 subcenter, int prodType,
    1748                 :                           int templat, uChar cat, uChar subcat, sInt4 lenTime,
    1749                 :                           uChar timeIncrType, uChar genID, uChar probType,
    1750                 :                           double lowerProb, double upperProb, char **name,
    1751                 :                           char **comment, char **unit, int *convert)
    1752                 : {
    1753                 :    GRIB2ParmTable *table;
    1754                 :    GRIB2LocalTable *local;
    1755                 :    size_t tableLen;
    1756                 :    size_t i;
    1757                 :    sChar f_accum;
    1758                 : 
    1759                 :    /* Check for over-ride case for ozone.  Originally just for NDFD, but I
    1760                 :     * think it is useful for ozone data that originated elsewhere. */
    1761               4 :    if ((prodType == 0) && (templat == 8) && (cat == 14) && (subcat == 193)) {
    1762               0 :       if (lenTime > 0) {
    1763               0 :          mallocSprintf (name, "Ozone%02d", lenTime);
    1764                 :          mallocSprintf (comment, "%d hr Average Ozone Concentration "
    1765               0 :                         "[PPB]", lenTime);
    1766                 :       } else {
    1767               0 :          *name = (char *) malloc (strlen ("AVGOZCON") + 1);
    1768               0 :          strcpy (*name, "AVGOZCON");
    1769                 :          *comment =
    1770                 :                (char *) malloc (strlen ("Average Ozone Concentration [PPB]") +
    1771               0 :                                 1);
    1772               0 :          strcpy (*comment, "Average Ozone Concentration [PPB]");
    1773                 :       }
    1774               0 :       *unit = (char *) malloc (strlen ("[PPB]") + 1);
    1775               0 :       strcpy (*unit, "[PPB]");
    1776               0 :       *convert = UC_NONE;
    1777               0 :       return;
    1778                 :    }
    1779                 : 
    1780                 :    /* Generic tables. */
    1781               4 :    table = Choose_GRIB2ParmTable (prodType, cat, &tableLen);
    1782               4 :    if (table != NULL) {
    1783               4 :       if (subcat < tableLen) {
    1784                 :          /* Check for NDFD over-rides. */
    1785               4 :          if (IsData_NDFD (center, subcenter) ||
    1786                 :              IsData_MOS (center, subcenter)) {
    1787              12 :             for (i = 0; i < (sizeof (NDFD_Overide) /
    1788                 :                              sizeof (NDFD_AbrevOverideTable)); i++) {
    1789              12 :                if (strcmp (NDFD_Overide[i].GRIB2name, table[subcat].name) ==
    1790                 :                    0) {
    1791                 :                   *name =
    1792                 :                         (char *) malloc (strlen (NDFD_Overide[i].NDFDname) +
    1793               4 :                                          1);
    1794               4 :                   strcpy (*name, NDFD_Overide[i].NDFDname);
    1795               4 :                   mallocSprintf (comment, "%s [%s]", table[subcat].comment,
    1796               8 :                                  table[subcat].unit);
    1797               4 :                   mallocSprintf (unit, "[%s]", table[subcat].unit);
    1798               4 :                   *convert = table[subcat].convert;
    1799               4 :                   return;
    1800                 :                }
    1801                 :             }
    1802                 :          }
    1803                 :          /* Allow hydrologic PoP, thunderstorm probability (TSTM), or APCP to 
    1804                 :           * have lenTime labels. */
    1805                 :          f_accum = (((prodType == 1) && (cat == 1) && (subcat == 2)) ||
    1806                 :                     ((prodType == 0) && (cat == 19) && (subcat == 2)) ||
    1807                 :                     ((prodType == 0) && (cat == 1) && (subcat == 8)) ||
    1808               0 :                     ((prodType == 0) && (cat == 19) && (subcat == 203)));
    1809               0 :          if (f_accum && (lenTime > 0)) {
    1810               0 :             mallocSprintf (name, "%s%02d", table[subcat].name, lenTime);
    1811                 :             mallocSprintf (comment, "%02d hr %s [%s]", lenTime,
    1812               0 :                            table[subcat].comment, table[subcat].unit);
    1813                 :          } else {
    1814               0 :             *name = (char *) malloc (strlen (table[subcat].name) + 1);
    1815               0 :             strcpy (*name, table[subcat].name);
    1816               0 :             mallocSprintf (comment, "%s [%s]", table[subcat].comment,
    1817               0 :                            table[subcat].unit);
    1818                 :          }
    1819               0 :          mallocSprintf (unit, "[%s]", table[subcat].unit);
    1820               0 :          *convert = table[subcat].convert;
    1821               0 :          return;
    1822                 :       }
    1823                 :    }
    1824                 : 
    1825                 :    /* Local use tables. */
    1826               0 :    local = Choose_LocalParmTable (center, subcenter, &tableLen);
    1827               0 :    if (local != NULL) {
    1828               0 :       for (i = 0; i < tableLen; i++) {
    1829               0 :          if ((prodType == local[i].prodType) && (cat == local[i].cat) &&
    1830               0 :              (subcat == local[i].subcat)) {
    1831                 :             /* Allow specific products with non-zero lenTime to reflect that. 
    1832                 :              */
    1833               0 :             f_accum = 0;
    1834               0 :             if (f_accum && (lenTime > 0)) {
    1835               0 :                mallocSprintf (name, "%s%02d", local[i].name, lenTime);
    1836                 :                mallocSprintf (comment, "%02d hr %s [%s]", lenTime,
    1837               0 :                               local[i].comment, local[i].unit);
    1838                 :             } else {
    1839               0 :                *name = (char *) malloc (strlen (local[i].name) + 1);
    1840               0 :                strcpy (*name, local[i].name);
    1841               0 :                mallocSprintf (comment, "%s [%s]", local[i].comment,
    1842               0 :                               local[i].unit);
    1843                 :             }
    1844               0 :             mallocSprintf (unit, "[%s]", local[i].unit);
    1845               0 :             *convert = local[i].convert;
    1846               0 :             return;
    1847                 :          }
    1848                 :       }
    1849                 :    }
    1850                 : 
    1851               0 :    *name = (char *) malloc (strlen ("unknown") + 1);
    1852               0 :    strcpy (*name, "unknown");
    1853                 :    mallocSprintf (comment, "(prodType %d, cat %d, subcat %d) [-]", prodType,
    1854               0 :                   cat, subcat);
    1855               0 :    *unit = (char *) malloc (strlen ("[-]") + 1);
    1856               0 :    strcpy (*unit, "[-]");
    1857               0 :    *convert = UC_NONE;
    1858               0 :    return;
    1859                 : }
    1860                 : 
    1861               4 : void ParseElemName (uShort2 center, uShort2 subcenter, int prodType,
    1862                 :                     int templat, int cat, int subcat, sInt4 lenTime,
    1863                 :                     uChar timeIncrType, uChar genID, uChar probType,
    1864                 :                     double lowerProb, double upperProb, char **name,
    1865                 :                     char **comment, char **unit, int *convert,
    1866                 :                     sChar percentile)
    1867                 : {
    1868               4 :    myAssert (*name == NULL);
    1869               4 :    myAssert (*comment == NULL);
    1870               4 :    myAssert (*unit == NULL);
    1871                 : 
    1872                 :    /* Check if this is Probability data */
    1873               4 :    if ((templat == GS4_PROBABIL_TIME) || (templat == GS4_PROBABIL_PNT)) {
    1874                 :       ElemNameProb (center, subcenter, prodType, templat, cat, subcat,
    1875                 :                     lenTime, timeIncrType, genID, probType, lowerProb,
    1876               0 :                     upperProb, name, comment, unit, convert);
    1877               4 :    } else if (templat == GS4_PERCENTILE) {
    1878                 :       ElemNamePerc (center, subcenter, prodType, templat, cat, subcat,
    1879               0 :                     lenTime, percentile, name, comment, unit, convert);
    1880                 :    } else {
    1881                 :       ElemNameNorm (center, subcenter, prodType, templat, cat, subcat,
    1882                 :                     lenTime, timeIncrType, genID, probType, lowerProb,
    1883               4 :                     upperProb, name, comment, unit, convert);
    1884                 :    }
    1885               4 : }
    1886                 : 
    1887                 : /*****************************************************************************
    1888                 :  * ParseElemName2() -- Review 12/2002
    1889                 :  *
    1890                 :  * Arthur Taylor / MDL
    1891                 :  *
    1892                 :  * PURPOSE
    1893                 :  *   Converts a prodType, template, category and subcategory quadruple to the
    1894                 :  * ASCII string abreviation of that variable.
    1895                 :  *   For example: 0, 0, 0, 0, = "T" for temperature.
    1896                 :  *
    1897                 :  * ARGUMENTS
    1898                 :  * prodType = The GRIB2, section 0 product type. (Input)
    1899                 :  *  templat = The GRIB2 section 4 template number. (Input)
    1900                 :  *      cat = The GRIB2 section 4 "General category of Product." (Input)
    1901                 :  *   subcat = The GRIB2 section 4 "Specific subcategory of Product". (Input)
    1902                 :  *     name = Where to store the result (assumed already allocated to at
    1903                 :  *            least 15 bytes) (Output)
    1904                 :  *  comment = Extra info about variable (assumed already allocated to at
    1905                 :  *            least 100 bytes) (Output)
    1906                 :  *     unit = What unit this variable is in. (assumed already allocated to at
    1907                 :  *            least 20 bytes) (Output)
    1908                 :  *
    1909                 :  * FILES/DATABASES: None
    1910                 :  *
    1911                 :  * RETURNS: char *
    1912                 :  *   Same as 'strcpy', ie it returns name.
    1913                 :  *
    1914                 :  * HISTORY
    1915                 :  *   9/2002 Arthur Taylor (MDL/RSIS): Created.
    1916                 :  *  11/2002 AAT: Added MOIST_TOT_SNOW (and switched MOIST_SNOWAMT to
    1917                 :  *               SnowDepth)
    1918                 :  *  12/2002 (TK,AC,TB,&MS): Code Review.
    1919                 :  *   2/2003 AAT: moved from degrib.c to metaparse.c
    1920                 :  *              (Reason: primarily for Sect2 Parsing)
    1921                 :  *              (renamed from ElementName to ParseElemName)
    1922                 :  *   4/2003 AAT: Added the comment as a return element.(see GRIB2 discipline)
    1923                 :  *   6/2003 AAT: Added the unit as a return element.
    1924                 :  *   6/2003 AAT: Added Wave Height.
    1925                 :  *
    1926                 :  * NOTES
    1927                 :  *   Similar to GRIB1_Table2LookUp... May want to take this and the unit
    1928                 :  * stuff and combine them into a module.
    1929                 :  *****************************************************************************
    1930                 :  */
    1931                 : /*
    1932                 : static void ParseElemName2 (int prodType, int templat, int cat, int subcat,
    1933                 :                             char *name, char *comment, char *unit)
    1934                 : {
    1935                 :    if (prodType == 0) {
    1936                 :       if (cat == CAT_TEMP) { * 0 *
    1937                 :          switch (subcat) {
    1938                 :             case TEMP_TEMP: * 0 *
    1939                 :                strcpy (comment, "Temperature [K]");
    1940                 :                strcpy (name, "T");
    1941                 :                strcpy (unit, "[K]");
    1942                 :                return;
    1943                 :             case TEMP_MAXT: * 4 *
    1944                 :                strcpy (comment, "Maximum temperature [K]");
    1945                 :                strcpy (name, "MaxT");
    1946                 :                strcpy (unit, "[K]");
    1947                 :                return;
    1948                 :             case TEMP_MINT: * 5 *
    1949                 :                strcpy (comment, "Minimum temperature [K]");
    1950                 :                strcpy (name, "MinT");
    1951                 :                strcpy (unit, "[K]");
    1952                 :                return;
    1953                 :             case TEMP_DEW_TEMP: * 6 *
    1954                 :                strcpy (comment, "Dew point temperature [K]");
    1955                 :                strcpy (name, "Td");
    1956                 :                strcpy (unit, "[K]");
    1957                 :                return;
    1958                 :             case TEMP_WINDCHILL: * 13 *
    1959                 :                strcpy (comment, "Wind chill factor [K]");
    1960                 :                strcpy (name, "WCI");
    1961                 :                strcpy (unit, "[K]");
    1962                 :                return;
    1963                 :             case TEMP_HEAT: * 12 *
    1964                 :                strcpy (comment, "Heat index [K]");
    1965                 :                strcpy (name, "HeatIndex");
    1966                 :                strcpy (unit, "[K]");
    1967                 :                return;
    1968                 :          }
    1969                 :       } else if (cat == CAT_MOIST) { * 1 *
    1970                 :          switch (subcat) {
    1971                 :             case MOIST_REL_HUMID: * 1 *
    1972                 :                strcpy (comment, "Relative Humidity [%]");
    1973                 :                strcpy (name, "RH");
    1974                 :                strcpy (unit, "[%]");
    1975                 :                return;
    1976                 :             case MOIST_PRECIP_TOT: * 8 *
    1977                 :                if (templat == GS4_PROBABIL_TIME) { * template number 9 implies prob. *
    1978                 :                   strcpy (comment, "Prob of 0.01 In. of Precip [%]");
    1979                 :                   strcpy (name, "PoP12");
    1980                 :                   strcpy (unit, "[%]");
    1981                 :                   return;
    1982                 :                } else {
    1983                 :                   strcpy (comment, "Total precipitation [kg/(m^2)]");
    1984                 :                   strcpy (name, "QPF");
    1985                 :                   strcpy (unit, "[kg/(m^2)]");
    1986                 :                   return;
    1987                 :                }
    1988                 :             case MOIST_SNOWAMT: * 11 *
    1989                 :                strcpy (comment, "Snow Depth [m]");
    1990                 :                strcpy (name, "SnowDepth");
    1991                 :                strcpy (unit, "[m]");
    1992                 :                return;
    1993                 :             case MOIST_TOT_SNOW: * 29 *
    1994                 :                strcpy (comment, "Total snowfall [m]");
    1995                 :                strcpy (name, "SnowAmt");
    1996                 :                strcpy (unit, "[m]");
    1997                 :                return;
    1998                 :             case 192:  * local use moisture. *
    1999                 :                strcpy (comment, "Weather (local use moisture) [-]");
    2000                 :                strcpy (name, "Wx");
    2001                 :                strcpy (unit, "[-]");
    2002                 :                return;
    2003                 :          }
    2004                 :       } else if (cat == CAT_MOMENT) { * 2 *
    2005                 :          switch (subcat) {
    2006                 :             case MOMENT_WINDDIR: * 0 *
    2007                 :                strcpy (comment, "Wind direction (from which blowing) "
    2008                 :                        "[deg true]");
    2009                 :                strcpy (name, "WindDir");
    2010                 :                strcpy (unit, "[deg true]");
    2011                 :                return;
    2012                 :             case MOMENT_WINDSPD: * 1 *
    2013                 :                strcpy (comment, "Wind speed [m/s]");
    2014                 :                strcpy (name, "WindSpd");
    2015                 :                strcpy (unit, "[m/s]");
    2016                 :                return;
    2017                 :          }
    2018                 :       } else if (cat == CAT_CLOUD) { * 6 *
    2019                 :          switch (subcat) {
    2020                 :             case CLOUD_COVER: * 1 *
    2021                 :                strcpy (comment, "Total cloud cover [%]");
    2022                 :                strcpy (name, "Sky");
    2023                 :                strcpy (unit, "[%]");
    2024                 :                return;
    2025                 :          }
    2026                 :       } else if (cat == CAT_MOISTURE_PROB) { * 10 *
    2027                 :          if (subcat == 8) { * grandfather'ed in. *
    2028                 :             strcpy (comment, "Prob of 0.01 In. of Precip [%]");
    2029                 :             strcpy (name, "PoP12");
    2030                 :             strcpy (unit, "[%]");
    2031                 :             return;
    2032                 :          }
    2033                 :       }
    2034                 :    } else if (prodType == 10) {
    2035                 :       if (cat == OCEAN_CAT_WAVES) { * 0 *
    2036                 :          if (subcat == OCEAN_WAVE_SIG_HT_WV) { * 5 *
    2037                 :             strcpy (comment, "Significant height of wind waves [m]");
    2038                 :             strcpy (name, "WaveHeight");
    2039                 :             strcpy (unit, "[m]");
    2040                 :             return;
    2041                 :          }
    2042                 :       }
    2043                 :    }
    2044                 :    strcpy (name, "");
    2045                 :    strcpy (comment, "unknown");
    2046                 :    strcpy (unit, "[-]");
    2047                 :    return;
    2048                 : }
    2049                 : */
    2050                 : 
    2051                 : /*****************************************************************************
    2052                 :  * ComputeUnit() --
    2053                 :  *
    2054                 :  * Arthur Taylor / MDL
    2055                 :  *
    2056                 :  * PURPOSE
    2057                 :  *   Sets m, and b for equation y = mx + b, where x is in the unit
    2058                 :  * specified by GRIB2, and y is the one specified by f_unit.  The default
    2059                 :  * is m = 1, b = 0.
    2060                 :  *
    2061                 :  * Currently:
    2062                 :  *   For f_unit = 1 (english) we return Fahrenheit, knots, and inches for
    2063                 :  * temperature, wind speed, and amount of snow or rain.  The original units
    2064                 :  * are Kelvin, m/s, kg/m**2.
    2065                 :  *   For f_unit = 2 (metric) we return Celsius instead of Kelvin.
    2066                 :  *
    2067                 :  * ARGUMENTS
    2068                 :  *  convert = The enumerated type describing the type of conversion. (Input)
    2069                 :  * origName = Original unit name (needed for log10 option) (Input)
    2070                 :  *   f_unit = What type of unit to return (see above) (Input).
    2071                 :  *    unitM = M in equation y = m x + b (Output)
    2072                 :  *    unitB = B in equation y = m x + b (Output)
    2073                 :  *     name = Where to store the result (assumed already allocated to at
    2074                 :  *           least 15 bytes) (Output)
    2075                 :  *
    2076                 :  * FILES/DATABASES: None
    2077                 :  *
    2078                 :  * RETURNS: int
    2079                 :  *   0 if we set M and B, 1 if we used defaults.
    2080                 :  *
    2081                 :  * HISTORY
    2082                 :  *   1/2004 Arthur Taylor (MDL/RSIS): Re-Created.
    2083                 :  *
    2084                 :  * NOTES
    2085                 :  *****************************************************************************
    2086                 :  */
    2087               6 : int ComputeUnit (int convert, char *origName, sChar f_unit, double *unitM,
    2088                 :                  double *unitB, char *name)
    2089                 : {
    2090               6 :    switch (convert) {
    2091                 :       case UC_NONE:
    2092               4 :          break;
    2093                 :       case UC_K2F:     /* Convert from Kelvin to F or C. */
    2094               2 :          if (f_unit == 1) {
    2095               0 :             strcpy (name, "[F]");
    2096               0 :             *unitM = 9. / 5.;
    2097                 :             /* 32 - (9/5 * 273.15) = 32 - 491.67 = -459.67. */
    2098               0 :             *unitB = -459.67;
    2099               0 :             return 0;
    2100               2 :          } else if (f_unit == 2) {
    2101               2 :             strcpy (name, "[C]");
    2102               2 :             *unitM = 1;
    2103               2 :             *unitB = -273.15;
    2104               2 :             return 0;
    2105                 :          }
    2106               0 :          break;
    2107                 :       case UC_InchWater: /* Convert from kg/(m^2) to inches water. */
    2108               0 :          if (f_unit == 1) {
    2109               0 :             strcpy (name, "[inch]");
    2110                 :             /* 
    2111                 :              * kg/m**2 / density of water (1000 kg/m**3)
    2112                 :              * 1/1000 m * 1/2.54 in/cm * 100 cm/m = 1/25.4 inches
    2113                 :              */
    2114               0 :             *unitM = 1. / 25.4;
    2115               0 :             *unitB = 0;
    2116               0 :             return 0;
    2117                 :          }
    2118               0 :          break;
    2119                 :       case UC_M2Feet:  /* Convert from meters to feet. */
    2120               0 :          if (f_unit == 1) {
    2121                 :             /* 1 (m) * (100cm/m) * (inch/2.54cm) * (ft/12inch) = X (ft) */
    2122               0 :             strcpy (name, "[feet]");
    2123               0 :             *unitM = 100. / 30.48;
    2124               0 :             *unitB = 0;
    2125               0 :             return 0;
    2126                 :          }
    2127               0 :          break;
    2128                 :       case UC_M2Inch:  /* Convert from meters to inches. */
    2129               0 :          if (f_unit == 1) {
    2130               0 :             strcpy (name, "[inch]");
    2131               0 :             *unitM = 100. / 2.54; /* inch / m */
    2132               0 :             *unitB = 0;
    2133               0 :             return 0;
    2134                 :          }
    2135               0 :          break;
    2136                 :          /* NCEP goes with a convention of 1 nm = 1853.248 m.
    2137                 :           * http://www.sizes.com/units/mile_USnautical.htm Shows that on
    2138                 :           * 7/1/1954 US Department of Commerce switched to 1 nm = 1852 m
    2139                 :           * (International standard.) */
    2140                 :       case UC_MS2Knots: /* Convert from m/s to knots. */
    2141               0 :          if (f_unit == 1) {
    2142               0 :             strcpy (name, "[knots]");
    2143               0 :             *unitM = 3600. / 1852.; /* knot / m s**-1 */
    2144               0 :             *unitB = 0;
    2145               0 :             return 0;
    2146                 :          }
    2147               0 :          break;
    2148                 :       case UC_LOG10:   /* convert from log10 (x) to x */
    2149               0 :          if ((f_unit == 1) || (f_unit == 2)) {
    2150               0 :             origName[strlen (origName) - 2] = '\0';
    2151               0 :             if (strlen (origName) > 21)
    2152               0 :                origName[21] = '\0';
    2153               0 :             sprintf (name, "[%s]", origName + 7);
    2154               0 :             *unitM = -10; /* M = -10 => take 10^(x) */
    2155               0 :             *unitB = 0;
    2156               0 :             return 0;
    2157                 :          }
    2158                 :          break;
    2159                 :    }
    2160                 :    /* Default case is for the unit in the GRIB2 document. */
    2161               4 :    strcpy (name, "[GRIB2 unit]");
    2162               4 :    *unitM = 1;
    2163               4 :    *unitB = 0;
    2164               4 :    return 1;
    2165                 : }
    2166                 : 
    2167                 : /*****************************************************************************
    2168                 :  * ComputeUnit2() --
    2169                 :  *
    2170                 :  * Arthur Taylor / MDL
    2171                 :  *
    2172                 :  * PURPOSE
    2173                 :  *   Sets m, and b for equation y = mx + b, where x is in the unit
    2174                 :  * specified by GRIB2, and y is the one specified by f_unit.  The default
    2175                 :  * is m = 1, b = 0.
    2176                 :  *
    2177                 :  * Currently:
    2178                 :  *   For f_unit = 1 (english) we return Fahrenheit, knots, and inches for
    2179                 :  * temperature, wind speed, and amount of snow or rain.  The original units
    2180                 :  * are Kelvin, m/s, kg/m**2.
    2181                 :  *   For f_unit = 2 (metric) we return Celsius instead of Kelvin.
    2182                 :  *
    2183                 :  * ARGUMENTS
    2184                 :  * prodType = The GRIB2, section 0 product type. (Input)
    2185                 :  *  templat = The GRIB2 section 4 template number. (Input)
    2186                 :  *      cat = The GRIB2 section 4 "General category of Product." (Input)
    2187                 :  *   subcat = The GRIB2 section 4 "Specific subcategory of Product". (Input)
    2188                 :  *   f_unit = What type of unit to return (see above) (Input).
    2189                 :  *    unitM = M in equation y = m x + b (Output)
    2190                 :  *    unitB = B in equation y = m x + b (Output)
    2191                 :  *     name = Where to store the result (assumed already allocated to at
    2192                 :  *            least 15 bytes) (Output)
    2193                 :  *
    2194                 :  * FILES/DATABASES: None
    2195                 :  *
    2196                 :  * RETURNS: int
    2197                 :  *   0 if we set M and B, 1 if we used defaults.
    2198                 :  *
    2199                 :  * HISTORY
    2200                 :  *  11/2002 Arthur Taylor (MDL/RSIS): Created.
    2201                 :  *
    2202                 :  * NOTES
    2203                 :  *****************************************************************************
    2204                 :  */
    2205                 : /*
    2206                 : static int ComputeUnit2 (int prodType, int templat, int cat, int subcat,
    2207                 :                          sChar f_unit, double *unitM, double *unitB,
    2208                 :                          char *name)
    2209                 : {
    2210                 :    if (prodType == 0) {
    2211                 :       switch (cat) {
    2212                 :          case CAT_TEMP:
    2213                 :             * subcat 8 is K/m, 10, 11 is W/m**2 *
    2214                 :             if ((subcat < 16) && (subcat != 8) &&
    2215                 :                 (subcat != 10) && (subcat != 11)) {
    2216                 :                if (f_unit == 1) {
    2217                 :                   strcpy (name, "[F]");
    2218                 :                   *unitM = 9. / 5.;
    2219                 :                   * 32 - (9/5 * 273.15) = 32 - 491.67 = -459.67. *
    2220                 :                   *unitB = -459.67;
    2221                 :                   return 0;
    2222                 :                } else if (f_unit == 2) {
    2223                 :                   strcpy (name, "[C]");
    2224                 :                   *unitM = 1;
    2225                 :                   *unitB = -273.15;
    2226                 :                   return 0;
    2227                 :                }
    2228                 :             }
    2229                 :             break;
    2230                 :          case CAT_MOIST:
    2231                 :             if (subcat == MOIST_PRECIP_TOT) {
    2232                 :                if (templat != 9) { * template number != 9 implies QPF. *
    2233                 :                   if (f_unit == 1) {
    2234                 :                      strcpy (name, "[inch]");
    2235                 :                      *
    2236                 :                       * kg/m**2 / density of water (1000 kg/m**3)
    2237                 :                       * 1/1000 m * 1/2.54 in/cm * 100 cm/m = 1/25.4 inches
    2238                 :                       *
    2239                 :                      *unitM = 1. / 25.4;
    2240                 :                      *unitB = 0;
    2241                 :                      return 0;
    2242                 :                   }
    2243                 :                }
    2244                 :             }
    2245                 :             if ((subcat == MOIST_SNOWAMT) || (subcat == MOIST_TOT_SNOW)) {
    2246                 :                if (f_unit == 1) {
    2247                 :                   strcpy (name, "[inch]");
    2248                 :                   *unitM = 100. / 2.54; * inch / m *
    2249                 :                   *unitB = 0;
    2250                 :                   return 0;
    2251                 :                }
    2252                 :             }
    2253                 :             break;
    2254                 :          case CAT_MOMENT:
    2255                 :             if (subcat == MOMENT_WINDSPD) {
    2256                 :                if (f_unit == 1) {
    2257                 :                   strcpy (name, "[knots]");
    2258                 :                   *unitM = 3600. / 1852.; * knot / m s**-1 *
    2259                 :                   *unitB = 0;
    2260                 :                   return 0;
    2261                 :                }
    2262                 :             }
    2263                 :             break;
    2264                 :       }
    2265                 :    } else if (prodType == 10) {
    2266                 :       if (cat == OCEAN_CAT_WAVES) { * 0 *
    2267                 :          if (subcat == OCEAN_WAVE_SIG_HT_WV) { * 5 *
    2268                 :             if (f_unit == 1) {
    2269                 :                * 1 (m) * (100cm/m) * (inch/2.54cm) * (ft/12inch) = X (ft) *
    2270                 :                strcpy (name, "[feet]");
    2271                 :                *unitM = 100. / 30.48;
    2272                 :                *unitB = 0;
    2273                 :                return 0;
    2274                 :             }
    2275                 :          }
    2276                 :       }
    2277                 :    }
    2278                 :    * Default case is for the unit in the GRIB2 document. *
    2279                 :    strcpy (name, "[GRIB2 unit]");
    2280                 :    *unitM = 1;
    2281                 :    *unitB = 0;
    2282                 :    return 1;
    2283                 : }
    2284                 : */
    2285                 : 
    2286                 : /* GRIB2 Code Table 4.5 */
    2287                 : /* *INDENT-OFF* */
    2288                 : GRIB2SurfTable Surface[] = {
    2289                 :    /* 0 */ {"RESERVED", "Reserved", "-"},
    2290                 :    /* 1 */ {"SFC", "Ground or water surface", "-"},
    2291                 :    /* 2 */ {"CBL", "Cloud base level", "-"},
    2292                 :    /* 3 */ {"CTL", "Level of cloud tops", "-"},
    2293                 :    /* 4 */ {"0DEG", "Level of 0 degree C isotherm", "-"},
    2294                 :    /* 5 */ {"ADCL", "Level of adiabatic condensation lifted from the surface", "-"},
    2295                 :    /* 6 */ {"MWSL", "Maximum wind level", "-"},
    2296                 :    /* 7 */ {"TRO", "Tropopause", "-"},
    2297                 :    /* 8 */ {"NTAT", "Nominal top of atmosphere", "-"},
    2298                 :    /* 9 */ {"SEAB", "Sea bottom", "-"},
    2299                 :    /* 10: 10-19 */ {"RESERVED", "Reserved", "-"},
    2300                 :    /* 11: 20 */ {"TMPL", "Isothermal level", "K"},
    2301                 :    /* 12: 21-99 */ {"RESERVED", "Reserved", "-"},
    2302                 :    /* 13: 100 */ {"ISBL", "Isobaric surface", "Pa"},
    2303                 :    /* 14: 101 */ {"MSL", "Mean sea level", "-"},
    2304                 :    /* 15: 102 */ {"GPML", "Specific altitude above mean sea level", "m"},
    2305                 :    /* 16: 103 */ {"HTGL", "Specified height level above ground", "m"},
    2306                 :    /* 17: 104 */ {"SIGL", "Sigma level", "'sigma' value"},
    2307                 :    /* 18: 105 */ {"HYBL", "Hybrid level", "-"},
    2308                 :    /* 19: 106 */ {"DBLL", "Depth below land surface", "m"},
    2309                 :    /* 20: 107 */ {"THEL", "Isentropic (theta) level", "K"},
    2310                 :    /* 21: 108 */ {"SPDL", "Level at specified pressure difference from ground to level", "Pa"},
    2311                 :    /* 22: 109 */ {"PVL", "Potential vorticity surface", "(K m^2)/(kg s)"},
    2312                 :    /* 23: 110 */ {"RESERVED", "Reserved", "-"},
    2313                 :    /* 24: 111 */ {"EtaL", "Eta* level", "-"},
    2314                 :    /* 25: 112-116 */ {"RESERVED", "Reserved", "-"},
    2315                 :    /* 26: 117 */ {"unknown", "Mixed layer depth", "m"}, /* unknown abbrev */
    2316                 :    /* 27: 118-159 */ {"RESERVED", "Reserved", "-"},
    2317                 :    /* 28: 160 */ {"DBSL", "Depth below sea level", "m"},
    2318                 :    /* 29: 161-191 */ {"RESERVED", "Reserved", "-"},
    2319                 :    /* 30: 192-254 */ {"RESERVED", "Reserved Local use", "-"},
    2320                 :    /* 31: 255 */ {"MISSING", "Missing", "-"},
    2321                 : };
    2322                 : 
    2323                 : typedef struct {
    2324                 :    int index;
    2325                 :    GRIB2SurfTable surface;
    2326                 : } GRIB2LocalSurface;
    2327                 : 
    2328                 : /* based on http://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_table4-5.shtml
    2329                 :  * updated last on 3/14/2006 */
    2330                 : GRIB2LocalSurface NCEP_Surface[] = {
    2331                 :    {200, {"EATM", "Entire atmosphere (considerd as a single layer)", "-"}},
    2332                 :    {201, {"EOCN", "Entire ocean (considered as a single layer)", "-"}},
    2333                 :    {204, {"HTFL", "Highest tropospheric freezing level", "-"}},
    2334                 :    {206, {"GCBL", "Grid scale cloud bottom level", "-"}},
    2335                 :    {207, {"GCTL", "Grid scale cloud top level", "-"}},
    2336                 :    {209, {"BCBL", "Boundary layer cloud bottom level", "-"}},
    2337                 :    {210, {"BCTL", "Boundary layer cloud top level", "-"}},
    2338                 :    {211, {"BCY", "Boundary layer cloud level", "-"}},
    2339                 :    {212, {"LCBL", "Low cloud bottom level", "-"}},
    2340                 :    {213, {"LCTL", "Low cloud top level", "-"}},
    2341                 :    {214, {"LCY", "Low cloud level", "-"}},
    2342                 :    {215, {"CEIL", "Cloud ceiling", "-"}},
    2343                 :    {222, {"MCBL", "Middle cloud bottom level", "-"}},
    2344                 :    {223, {"MCTL", "Middle cloud top level", "-"}},
    2345                 :    {224, {"MCY", "Middle cloud level", "-"}},
    2346                 :    {232, {"HCBL", "High cloud bottom level", "-"}},
    2347                 :    {233, {"HCTL", "High cloud top level", "-"}},
    2348                 :    {234, {"HCY", "High cloud level", "-"}},
    2349                 :    {235, {"OITL", "Ocean Isotherm Level (1/10 deg C)", "-"}},
    2350                 :    {236, {"OLYR", "Layer between two depths below ocean surface", "-"}},
    2351                 :    {237, {"OBML", "Bottom of Ocean Mixed Layer (m)", "-"}},
    2352                 :    {238, {"OBIL", "Bottom of Ocean Isothermal Layer (m)", "-"}},
    2353                 :    {242, {"CCBL", "Convective cloud bottom level", "-"}},
    2354                 :    {243, {"CCTL", "Convective cloud top level", "-"}},
    2355                 :    {244, {"CCY", "Convective cloud level", "-"}},
    2356                 :    {245, {"LLTW", "Lowest level of the wet bulb zero", "-"}},
    2357                 :    {246, {"MTHE", "Maximum equivalent potential temperature level", "-"}},
    2358                 :    {247, {"EHLT", "Equilibrium level", "-"}},
    2359                 :    {248, {"SCBL", "Shallow convective cloud bottom level", "-"}},
    2360                 :    {249, {"SCTL", "Shallow convective cloud top level", "-"}},
    2361                 :    {251, {"DCBL", "Deep convective cloud bottom level", "-"}},
    2362                 :    {252, {"DCTL", "Deep convective cloud top level", "-"}},
    2363                 :    {253, {"LBLSW", "Lowest bottom level of supercooled liquid water layer", "-"}},
    2364                 :    {254, {"HTLSW", "Highest top level of supercooled liquid water layer", "-"}},
    2365                 : };
    2366                 : /* *INDENT-ON* */
    2367                 : 
    2368                 : /*****************************************************************************
    2369                 :  * Table45Index() --
    2370                 :  *
    2371                 :  * Arthur Taylor / MDL
    2372                 :  *
    2373                 :  * PURPOSE
    2374                 :  *   To figure out the entry in the "Surface" table (used for Code Table 4.5)
    2375                 :  *
    2376                 :  * ARGUMENTS
    2377                 :  *          i = The original index to look up. (Input)
    2378                 :  * f_reserved = If the index is a "reserved" index (Output)
    2379                 :  *
    2380                 :  * FILES/DATABASES: None
    2381                 :  *
    2382                 :  * RETURNS: GRIB2SurfTable
    2383                 :  *
    2384                 :  * HISTORY
    2385                 :  *   9/2002 Arthur Taylor (MDL/RSIS): Created.
    2386                 :  *  12/2004 Arthur Taylor (RSIS): Modified to return SurfaceTable.
    2387                 :  *
    2388                 :  * NOTES
    2389                 :  *****************************************************************************
    2390                 :  */
    2391               4 : GRIB2SurfTable Table45Index (int i, int *f_reserved, uShort2 center,
    2392                 :                              uShort2 subcenter)
    2393                 : {
    2394                 :    size_t j;
    2395                 : 
    2396               4 :    *f_reserved = 1;
    2397               4 :    if ((i > 255) || (i < 0)) {
    2398                 : #ifdef DEBUG
    2399               0 :       printf ("Surface index is out of 0..255 range?\n");
    2400                 : #endif
    2401               0 :       return Surface[0];
    2402                 :    }
    2403               4 :    if (i == 255)
    2404               0 :       return Surface[31];
    2405               4 :    if (i > 191) {
    2406               0 :       if (center == 7) {
    2407               0 :          for (j = 0; j < sizeof (NCEP_Surface) / sizeof (NCEP_Surface[0]);
    2408                 :               j++) {
    2409               0 :             if (i == NCEP_Surface[j].index) {
    2410               0 :                *f_reserved = 0;
    2411               0 :                return (NCEP_Surface[j].surface);
    2412                 :             }
    2413                 :          }
    2414                 :       }
    2415               0 :       return Surface[30];
    2416                 :    }
    2417               4 :    if (i > 160)
    2418               0 :       return Surface[29];
    2419               4 :    if (i == 160) {
    2420               0 :       *f_reserved = 0;
    2421               0 :       return Surface[28];
    2422                 :    }
    2423               4 :    if (i > 117)
    2424               0 :       return Surface[27];
    2425               4 :    if (i == 117) {
    2426               0 :       *f_reserved = 0;
    2427               0 :       return Surface[26];
    2428                 :    }
    2429               4 :    if (i > 111)
    2430               0 :       return Surface[25];
    2431               4 :    if (i == 111) {
    2432               0 :       *f_reserved = 0;
    2433               0 :       return Surface[i - 87];
    2434                 :    }
    2435               4 :    if (i == 110)
    2436               0 :       return Surface[i - 87];
    2437               4 :    if (i > 99) {
    2438               0 :       *f_reserved = 0;
    2439               0 :       return Surface[i - 87];
    2440                 :    }
    2441               4 :    if (i > 20)
    2442               0 :       return Surface[12];
    2443               4 :    if (i == 20) {
    2444               0 :       *f_reserved = 0;
    2445               0 :       return Surface[11];
    2446                 :    }
    2447               4 :    if (i > 9)
    2448               0 :       return Surface[10];
    2449               4 :    if (i > 0) {
    2450               4 :       *f_reserved = 0;
    2451               4 :       return Surface[i];
    2452                 :    }
    2453               0 :    return Surface[0];
    2454                 : }
    2455                 : 
    2456               4 : void ParseLevelName (unsigned short int center, unsigned short int subcenter,
    2457                 :                      uChar surfType, double value, sChar f_sndValue,
    2458                 :                      double sndValue, char **shortLevelName,
    2459                 :                      char **longLevelName)
    2460                 : {
    2461                 :    int f_reserved;
    2462                 :    char valBuff[512];
    2463                 :    char sndBuff[512];
    2464                 :    GRIB2SurfTable surf = Table45Index (surfType, &f_reserved, center,
    2465               4 :                                        subcenter);
    2466                 : 
    2467                 :    /* Check if index is defined... 191 is undefined. */
    2468               4 :    free (*shortLevelName);
    2469               4 :    *shortLevelName = NULL;
    2470               4 :    free (*longLevelName);
    2471               4 :    *longLevelName = NULL;
    2472               4 :    sprintf (valBuff, "%f", value);
    2473               4 :    strTrimRight (valBuff, '0');
    2474               4 :    if (valBuff[strlen (valBuff) - 1] == '.') {
    2475               4 :       valBuff[strlen (valBuff) - 1] = '\0';
    2476                 :    }
    2477               4 :    if (f_sndValue) {
    2478               0 :       sprintf (sndBuff, "%f", sndValue);
    2479               0 :       strTrimRight (sndBuff, '0');
    2480               0 :       if (sndBuff[strlen (sndBuff) - 1] == '.') {
    2481               0 :          sndBuff[strlen (sndBuff) - 1] = '\0';
    2482                 :       }
    2483               0 :       if (f_reserved) {
    2484                 :          reallocSprintf (shortLevelName, "%s-%s-%s(%d)", valBuff, sndBuff,
    2485               0 :                          surf.name, surfType);
    2486                 :          reallocSprintf (longLevelName, "%s-%s[%s] %s(%d) (%s)", valBuff,
    2487                 :                          sndBuff, surf.unit, surf.name, surfType,
    2488               0 :                          surf.comment);
    2489                 :       } else {
    2490                 :          reallocSprintf (shortLevelName, "%s-%s-%s", valBuff, sndBuff,
    2491               0 :                          surf.name);
    2492                 :          reallocSprintf (longLevelName, "%s-%s[%s] %s=\"%s\"", valBuff,
    2493               0 :                          sndBuff, surf.unit, surf.name, surf.comment);
    2494                 :       }
    2495                 :    } else {
    2496               4 :       if (f_reserved) {
    2497                 :          reallocSprintf (shortLevelName, "%s-%s(%d)", valBuff, surf.name,
    2498               0 :                          surfType);
    2499                 :          reallocSprintf (longLevelName, "%s[%s] %s(%d) (%s)", valBuff,
    2500               0 :                          surf.unit, surf.name, surfType, surf.comment);
    2501                 :       } else {
    2502               4 :          reallocSprintf (shortLevelName, "%s-%s", valBuff, surf.name);
    2503                 :          reallocSprintf (longLevelName, "%s[%s] %s=\"%s\"", valBuff,
    2504               4 :                          surf.unit, surf.name, surf.comment);
    2505                 :       }
    2506                 :    }
    2507               4 : }

Generated by: LCOV version 1.7