Logo Search packages:      
Sourcecode: magics++ version File versions  Download package

GribDecoder.cc

Go to the documentation of this file.
/******************************** LICENSE ********************************

 Copyright 2007 European Centre for Medium-Range Weather Forecasts (ECMWF)

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at 

    http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.

 ******************************** LICENSE ********************************/

/*! \file GribDecoder.cc
    \brief Implementation of the Template class GribDecoder.
    
    Magics Team - ECMWF 2004
    
    Started: Tue 16-Mar-2004
    
    Changes:
    
*/
 
#include "GribDecoder.h"
#include "Factory.h"
#include <limits>
#include "TitleTemplate.h"
#include "LocalTable.h"
#include "DateTime.h"
#include "GribTables.h"
#include <locale>
#include "GribInterpretor.h"
#include "XmlReader.h"
#include "TextVisitor.h"
#include "Timer.h"
#include "VisualAction.h"
#include "AnimationRules.h"


using namespace magics;
grib_context* GribDecoder::context_ = 0;
int  GribDecoder::count_ = 0;

GribDecoder::GribDecoder() :  matrix_(0),  xComponent_(0), yComponent_(0), handle_(0)
{
      count_++;
      title_ = "grib_" + tostring(count_);
      version();
}

void GribDecoder::version()
{
      static bool done = false;
      
      if ( done ) return;
      done = true;
      
      Log::info() << "GribAPi Version :" << grib_get_api_version() << endl;
}

GribDecoder::~GribDecoder() 
{
      if ( matrix_) delete matrix_;
    if ( xComponent_ ) delete xComponent_;
    if ( yComponent_ ) delete yComponent_;
      //context is a reference to a global context and should not be deleted
}

long  GribDecoder::getLong(const string& key) const
{
      assert (context_);
      long val;
      int err = grib_get_long(handle_, key.c_str(), &val);
      if ( err ) {
            Log::info() << "Grib Api : can not find key [" << key << "]\n";
            Log::info() << grib_get_error_message(err) <<"\n";
            return 0;
      }
      return val;
}



string GribDecoder::getString(const string& key) const
{
      
      assert (context_); 
      char val[1024];
      size_t length = 1024;
      int err = grib_get_string(handle_, key.c_str(), val, &length);
      if ( err )
      {
            Log::info() << "Grib Api : can not find key [" << key << "]\n";
            Log::info() << grib_get_error_message(err) <<"\n";
            return "";
      }
      return string(val);
}

double   GribDecoder::getDouble(const string& key) const
{
      assert (context_); 
      double val;
      int err = grib_get_double(handle_, key.c_str(), &val);
      if ( err )
      {
            Log::info() << "Grib Api : can not find key [" << key << "]\n";
            Log::info() << grib_get_error_message(err) <<"\n";
            return 0;
      }
      return val;
}

void   GribDecoder::setDouble(const string& key, double val) const
{
      assert (context_);
      int err = grib_set_double(handle_, key.c_str(), val);
      if ( err )
      {
            Log::info() << "Grib Api : can not find key [" << key << "]\n";
            Log::info() << grib_get_error_message(err) <<"\n";
      }

}


void GribDecoder::read(Matrix **matrix)
{
      
      long repres;    
      grib_get_long(handle_,"dataRepresentationType",&repres);
      
      string representation = getString("typeOfGrid");
 
   
    try {
      auto_ptr<GribInterpretor> interpretor(SimpleObjectMaker<GribInterpretor>::create(representation));          
        interpretor->interpretAsMatrix(*this, matrix);
        interpretor->scaling(*this, matrix); 
        
    }      
    catch (NoFactoryException&)
    {
      
      Log::error() << "Grib Decoder: Representation [" << representation << "] not yet supported.\n";
      throw MagicsException("Grib Decoder: Representation [] not yet supported.");
    }
      
}


/*!
 Class information are given to the output-stream.
*/          
void GribDecoder::print(ostream& out)  const
{
      out << "GribDecoder[";
      GribDecoderAttributes::print(out);
      out << "] ";
}



void GribDecoder::decode2D() 
{     
      if (xComponent_) return;
            
      
      
      Matrix     *w1 = 0;
    Matrix     *w2 = 0;     
    
   
    openFirstComponent();
    read(&w1);
    
    
    openSecondComponent();
    read(&w2);
    
    wind_mode_->x(&xComponent_, &yComponent_, w1, w2);
    
}

void GribDecoder::openFirstComponent() 
{
        grib_field_position_ =  position_1_;
        open();
}

void GribDecoder::openSecondComponent() 
{
        grib_field_position_ =  position_2_;
        open();
}


void  GribDecoder::open() 
{
      FILE* file = fopen(file_name_.c_str(),"r");
      if (!file)
      {
            Log::error() << "file can not be opened [" << file_name_ << ", " << grib_field_position_ << "]" << "\n";
            throw GribFileException(file_name_, grib_field_position_);
      }
      if (!context_) 
            context_ =  grib_context_get_default();   
    
      handle_ = (*address_mode_)(context_, file, grib_field_position_);

    if (handle_<=0) {
            Log::error() << "file can not be opened [" << file_name_ << ", " << grib_field_position_ << "]" << "\n";
           
            throw GribFileException(file_name_, grib_field_position_);
      }
       
}


      


bool GribDecoder::id(const string& id) const 
{
      return magCompare(id_, id);
}
void GribDecoder::decodePoints()
{
      if ( !points_.empty() ) return;
      open();     
      
      unsigned long flags;
    int error;
    
    grib_iterator* iter = grib_iterator_new(handle_, flags, &error);
    
   
    
    if (!iter) {
      Log::error() << "Grib Iterator not yet supported on this kind of grib\n";
      throw MagicsException("Grib Iterator not yet supported.");
    }
    double lat;
    double lon;
    double val;
      
    while (grib_iterator_next(iter,&lat,&lon,&val)){
         points_.push_back(GeoPoint(lon, lat, val));
    }
}


grib_context* GribDecoder::gribContext() 
{      
      if (!context_)
            context_ = grib_context_get_default();   
      return context_;
}


Data<GeoPoint>* GribLoop::current()
{
      return grib_;
}

map<string, string> GribLoop::ids_;
int GribLoop::index_ = 0;

void        GribLoop::next() {}
      
GribLoop::GribLoop::GribLoop():  grib_(0), file_(0)
{
            current_ = dim_.begin();
            current1_ = dim_1_.begin();
            current2_ = dim_2_.begin();
}

void GribLoop::setToFirst() 
{
      current_ = dim_.begin();
      current1_ = dim_1_.begin();
      current2_ = dim_2_.begin();
}

bool  GribLoop::hasMore()
{
      if (file_ == 0 ) {
            file_ = fopen(path_.c_str(),"r");
            if (!file_) {
                  Log::error() << "file can not be opened [" << path_ <<  "]" << "\n";
                  throw GribFileException(path_, 0);
            }     
      }
      
    grib_context* context = GribDecoder::gribContext();
    
    // Now we have to find the right Entry!!! 
    
    //check the dimension 
    
    if ( dimension_ < 1 || dimension_ > 2 ) {
      Log::warning() << " GribLoop setting grib_dimension reset to 1" << endl;
    }
    
   
    if ( dimension_ == 1 ) {   
      if (  dim_.empty() ) {
             // case 1 dimension= 1 and loop on all the fields! 
            int error;
            grib_handle* handle = grib_handle_new_from_file(context, file_, &error) ; 
            if (handle <=0)  return false;
            grib_ = new GribEntryDecoder(handle);
      }
      else {
            if ( current_ == dim_.end() )
                  return false;
             // Case 3 Dimension = 1 but we only used  a subset of fields
            grib_handle* handle =  (*address_mode_)(context, file_, *current_);
            current_++;
            if (handle <=0)  
                  return false;
            grib_ = new GribEntryDecoder(handle);
      
      }
    }
    
   
    if ( dimension_ == 2) {
      if ( dim_1_.empty()  ) {
       // case 2 Dimension = 2 and loop on all the field!
            int error;
                  grib_handle* handle1 = grib_handle_new_from_file(context, file_, &error) ; 
                  if (handle1 <=0)  return false;     
                  grib_handle* handle2 = grib_handle_new_from_file(context, file_, &error) ; 
            if (handle2 <=0)  return false;
            grib_ = new GribEntryDecoder(handle1, handle2);
      }
        else {
            // Case 4 Dimesnion = 2 and we only used a subset of fields! 
            if ( current1_ ==  dim_1_.end() || current2_ ==  dim_2_.end() )
                  return false;
            
            grib_handle* handle1 =  (*address_mode_)(context, file_, *current1_);
            grib_handle* handle2 =  (*address_mode_)(context, file_, *current2_);
            if ( handle1 <=0 )  
                  return false;
            if ( handle2 <=0 )  
                   return false;
            grib_ = new GribEntryDecoder(handle1, handle2);
            current1_++;
            current2_++;
        }
   }

     
    grib_->setFile_name(path_);
    if ( iconName_.empty() ) {
            map<string, string>::iterator id = ids_.find(path_);
            if ( id == ids_.end() ) {
                        iconName_ = "Grib" + tostring(index_);
                        index_++;
                        ids_.insert(make_pair(path_, iconName_));             
             }
              else 
                        iconName_ = id->second;
    }
   grib_->icon(*this);
      return true;
}

void GribLoop::print(ostream&) const {}



class GribTag: public XmlNodeVisitor
{
public:
      GribTag(GribDecoder& grib, TagHandler& title) : grib_(grib), title_(title) {
      }
      
      ~GribTag() {}
      string baseDate(const XmlNode& node) {
            string format= node.getAttribute("format");
            if ( format.empty() )  
                  format =  "%A %d %B %Y at %H UTC";
            long day =  grib_.getLong("date");  
            long hour = grib_.getLong("hour");  
            long mn =  grib_.getLong("minute"); 
            Date part1 = Date(day);
            magics::Time part2 = magics::Time(hour, mn, 0);
            DateTime full(part1, part2);
            tm convert = full;
            try {
                  locale loc("");
                  ostringstream out;
                  out.imbue(loc);   
                  const std::time_put<char>& tfac = use_facet<time_put<char> >(loc); 
                  tfac.put(out, out, ' ', &convert, format.c_str(), format.c_str()+format.length());       
                  return out.str();
            }
            catch (...)
            {
                  Log::error() << "Problem to setup the locale" << endl;
                  Log::error() << "Check you LOCALE variable-->current value : " <<  getEnvVariable("LANG")<< endl;
                  assert(false);
            }
      }
      string startDate(const XmlNode& node) {
                  string format= node.getAttribute("format");
                  if ( format.empty() )  
                        format =  "%A %d %B %Y at %H UTC";
                  long day =  grib_.getLong("date");  
                  long hour = grib_.getLong("hour");  
                  long mn =  grib_.getLong("minute");
                  long step =  grib_.getLong("startStepInHours");
                  
                                    
                  Date part1 = Date(day);
                  magics::Time part2 = magics::Time(hour, mn, 0);
                  DateTime full(part1, part2);  
                   full = full + (step*3600);
                  tm convert = full;
                  try {
                        locale loc("");
                        ostringstream out;
                        out.imbue(loc);   
                        const std::time_put<char>& tfac = use_facet<time_put<char> >(loc); 
                        tfac.put(out, out, ' ', &convert, format.c_str(), format.c_str()+format.length());       
                        return out.str();
                  }
                  catch (...)
                        {
                              Log::error() << "Problem to setup the locale" << endl;
                              Log::error() << "Check you LOCALE variable-->current value : " <<  getEnvVariable("LANG")<< endl;
                              assert(false);
                        }
            }
      string validDate(const XmlNode& node) {
                  string format= node.getAttribute("format");
                  if ( format.empty() )  
                        format =  "%A %d %B %Y at %H UTC";
                  long day =  grib_.getLong("date");  
                  long hour = grib_.getLong("hour");  
                  long mn =  grib_.getLong("minute");
                  long step =  grib_.getLong("stepRange");
                  
                                    
                  Date part1 = Date(day);
                  magics::Time part2 = magics::Time(hour, mn, 0);
                  DateTime full(part1, part2);  
                   full = full + (step*3600);
                  tm convert = full;
                  try {
                        locale loc("");
                        ostringstream out;
                        out.imbue(loc);   
                        const std::time_put<char>& tfac = use_facet<time_put<char> >(loc); 
                        tfac.put(out, out, ' ', &convert, format.c_str(), format.c_str()+format.length());       
                        return out.str();
                  }
                  catch (...)
                        {
                              Log::error() << "Problem to setup the locale" << endl;
                              Log::error() << "Check you LOCALE variable-->current value : " <<  getEnvVariable("LANG")<< endl;
                              assert(false);
                        }
            }
      string endDate(const XmlNode& node) {
                        string format=  node.getAttribute("format");
                        if ( format.empty() )  
                              format =  "%A %d %B %Y at %H UTC";
                        long day =  grib_.getLong("date");  
                        long hour = grib_.getLong("hour");  
                        long mn =  grib_.getLong("minute");
                        long step =  grib_.getLong("endStepInHours");
                        
                                          
                        Date part1 = Date(day);
                        magics::Time part2 = magics::Time(hour, mn, 0);
                        DateTime full(part1, part2);  
                         full = full + ( step*3600 );
                        tm convert = full;
                        try {
                              locale loc("");
                              ostringstream out;
                              out.imbue(loc);   
                              const std::time_put<char>& tfac = use_facet<time_put<char> >(loc); 
                              tfac.put(out, out, ' ', &convert, format.c_str(), format.c_str()+format.length());       
                              return out.str();
                        }
                        catch (...)
                              {
                                    Log::error() << "Problem to setup the locale" << endl;
                                    Log::error() << "Check you LOCALE variable-->current value : " <<  getEnvVariable("LANG")<< endl;
                                    assert(false);
                              }
                  }
      void visit(const XmlNode& node)
      {           
            
            if ( magCompare(node.name(), "grib_info") ) {
                  string grib = node.getAttribute("id");
                              if ( !grib_.id(grib)) return;
                  string def = node.getAttribute("key");
                  if (def.empty()) {
                         def = node.getAttribute("definition");
                         // for backward compatibility with the first version! 
                  }
                  
                  
                  if ( def == "base-date" ) {
                        title_.update("grib"+grib, def, baseDate(node));
                        return;
                  }
                  if ( def == "valid-date" ) {
                        title_.update("grib"+grib, def, validDate(node));
                        return;
                  }
                  if ( def == "start-date" ) {
                                          title_.update("grib"+grib, def, startDate(node));
                                          return;
                  }
                  if ( def == "end-date" ) {
                                                      title_.update("grib"+grib, def, endDate(node));
                                                      return;
                              }
                  string val =  grib_.getString(def);
                  if ( val.empty() ) 
                        val =  node.getAttribute("default");
                  title_.update("grib"+grib, def, val);
            }           
            
            if ( magCompare(node.name(), "magics_title") ) {
                  string grib = node.getAttribute("id");
                                                if ( !grib_.id(grib)) return;
                  ostringstream out;
                  TitleTemplate::title(out, grib_);
                  title_.update("grib"+grib, grib_.title(), out.str());
            }           
            node.visit(*this);      
      }
      
      void decode(const string& line)
      {
      
            XmlReader parser;
            XmlTree tree;
      
            ostringstream xml;
            xml << "<?xml version='1.0' ?> \n";       
            xml << "<xml> \n";
            xml << line;
            xml << "\n</xml>";
            
            
            try {
                  parser.decode(xml.str(), &tree);          
                  tree.visit(*this);
            }
            catch (MagicsException& e) {
                  Log::debug() << e.what() << endl;
                  
            }     
     } 
     string str() const { return out.str(); }
protected :
      GribDecoder& grib_;
      TagHandler& title_;
      ostringstream out;
      
};

void GribDecoder::visit(AnimationRules& rules) {
        
}

void GribDecoder::visit(AnimationStep& step) {
         try {
               TagHandler helper;
               vector<string> need;
               need.push_back("<grib_info key='shortName'/>");
               need.push_back("<grib_info key='lev'/>");
               need.push_back("<grib_info key='start-date' format='%Y-%m-%d %H:%M:00'/>");
               need.push_back("<grib_info key='end-date' format='%Y-%m-%d %H:%M:00'/>");
               GribTag tag1(*this, helper);
                  
                  for ( vector<string>::const_iterator t = need.begin(); t != need.end(); ++t ) {
                        tag1.decode(*t);
                  }
                  name_ = helper.get("grib", "shortName") +  " " +  helper.get("grib", "lev");
                  from_ = DateTime(helper.get("grib", "start-date"));
                  to_ =  DateTime(helper.get("grib", "end-date"));
                  
               //MatrixHandler<GeoPoint>& data = matrix() ; 
               // Information about contains...
                  Log::dev() << "GribDecoder::visit(AnimationRules&) --> " << endl;
                  
                  vector<string> info;
                  step.rules(info);
                  
                  GribTag tag2(*this, step);
                        
                        for ( vector<string>::const_iterator t = info.begin(); t != info.end(); ++t ) {
                              tag2.decode(*t);
                        }
                        
                   // information about resolution...
                        step.xResolution(1.5); //step.xResolution(abs(data.XResolution()));
                        step.yResolution(1.5); //     step.yResolution(abs(data.YResolution()));
               }
         catch (...)
         {
               
         }
         
              
               
      
}

void GribDecoder::decode() 
{
      if (matrix_) return;
      
      open();
      
      read(&matrix_);
      
      // here we build information for the layers!
      TagHandler helper; 
      vector<string> need;
      need.push_back("<grib_info id=\'" + id_ +"\' key='shortName'/>");
      need.push_back("<grib_info id=\'" + id_ +"\' key='lev'/>");
                     need.push_back("<grib_info id=\'" + id_ +"\'  key='start-date' format='%Y-%m-%d %H:%M:00'/>");
                     need.push_back("<grib_info id=\'" + id_ +"\' key='end-date' format='%Y-%m-%d %H:%M:00'/>");
                     GribTag tag1(*this, helper);
                        
                        for ( vector<string>::const_iterator t = need.begin(); t != need.end(); ++t ) {
                              tag1.decode(*t);
                        }
                        
                        name_ = helper.get("grib"+id_, "shortName") +  "-" +  helper.get("grib"+id_, "lev");
                        name_ = iconName_;
                        layerId_ = name_ + file_name_;
                        from_ = DateTime(helper.get("grib"+id_, "start-date"));
                        to_ =  DateTime(helper.get("grib"+id_, "end-date"));
                        
                  
}

void GribDecoder::visit(MagnifierVisitor& magnify) 
{
      
      vector<PaperPoint> thin;
      vector<PaperPoint> all;
      const Transformation& transformation = magnify.transformation();
      
      
      transformation.thin(matrix(), thin, all);
      
      for (vector<PaperPoint>::iterator point = thin.begin(); point != thin.end(); ++point) {
             magnify.add(*point);
      }
      for (vector<PaperPoint>::iterator point = all.begin(); point != all.end(); ++point) {
                   magnify.addMore(*point);
      }
            
      
       
}
void GribDecoder::visit(TextVisitor& title) 
{
      
      try {
            open();     
      }
      catch ( ... )
      {
            return;
      }
      
      vector<string> titles;

      title.titles(titles);
      GribTag tag(*this, title);
      
      for ( vector<string>::const_iterator t = titles.begin(); t != titles.end(); ++t ) {
            tag.decode(*t);
      }
      string entry = "<grib_info definition=\'" + title_ + "\'/>";
      title.add(new TextEntry(entry));
      
}



void GribDecoder::decodeRaster() 
{
      open();
      
      string representation = getString("typeOfGrid");
      
      try {
            GribInterpretor* interpretor = SimpleObjectMaker<GribInterpretor>::create(representation);
            interpretor->interpretAsRaster(*this, raster_);
      }
    
    catch (NoFactoryException&)
    {
      Log::error() << "Grib Decoder: Representation [" << representation << "] not yet supported.\n";
      throw MagicsException("Grib Decoder: Representation [] not yet supported.");
    }
}


namespace magics {
class GribInfo
{
public:
    GribInfo() {}
    virtual ~GribInfo() {}
    virtual void operator()(ostream&, const GribDecoder&) = 0;
    
};

class GribParameter : public GribInfo
{
public: 
      GribParameter() {}
      ~GribParameter() {}
      void operator()(ostream& out, const GribDecoder& grib)
      {
            long centre;
            long table;
            long param;

            grib_get_long(grib.id(), "indicatorOfParameter", &param);
            grib_get_long(grib.id(), "identificationOfOriginatingGeneratingCentre", &centre);
            grib_get_long(grib.id(), "gribTablesVersionNo", &table);
 
            try {
                  const ParamDef& parameter = LocalTable::localInfo(param, table, centre);
                  out << parameter.longTitle();
            }
            catch (...) {
                  out << param << "." << table;
            }
      }
};

class GribParamCriter : public MatchCriteria<GribDecoder>
{
public:
      GribParamCriter() {}
      ~GribParamCriter() {}
      bool verify(const GribDecoder& grib, const string&, const string& val)
      {
            string param = grib.getString("indicatorOfParameter");
            return (param == val);
      }
};

class GribLocalCriter : public MatchCriteria<GribDecoder>
{
public:
      GribLocalCriter() {}
      ~GribLocalCriter() {}
      bool verify(const GribDecoder& grib, const string& param, const string& val)
      {
            string key = param;
      
            string criter = grib.getString(key);
            
            
            Log::debug() << "I am verifing " << param << " for a GribDecoder : " << criter << " ==  " << val << "???" << "\n";
            return (criter == val);
      }
};

class GribLocalDefHandler : public TitleFieldHandler<GribDecoder>
{
public:
      GribLocalDefHandler() {}
      ~GribLocalDefHandler() {}

      virtual void operator()(TitleField&, ostream& out, const GribDecoder& grib)
      {
        if (!grib.getText()) return;      
            string local = grib.getString("localDefinitionNumber");       
        out << "local definition =" << local << " ";         
      }
};


class GribLocalHandler : public TitleFieldHandler<GribDecoder>
{
public:
      GribLocalHandler(const string& local) : local_(local) {}
      ~GribLocalHandler() {}

      virtual void operator()(TitleField&, ostream& out, const GribDecoder& grib)
      {
        if (!grib.getText()) return;
       string code = grib.getString(local_);
            out << local_ << "=" << code  << " ";
      }
protected :
      string local_;
};

class GribStreamHandler : public GribLocalHandler 
{
public:
      GribStreamHandler() : GribLocalHandler("marsStream") {}
      ~GribStreamHandler() {}
};

class GribClassHandler : public GribLocalHandler 
{
public:
      GribClassHandler() : GribLocalHandler("marsClass") {}
      ~GribClassHandler() {}
};

class GribTypeHandler : public GribLocalHandler 
{
public:
      GribTypeHandler() : GribLocalHandler("marsType") {}
      ~GribTypeHandler() {}
};


class GribParamHandler : public TitleFieldHandler<GribDecoder>
{
public:
      GribParamHandler() {}
      ~GribParamHandler() {}
      virtual void operator()(TitleField&, ostream& out, const GribDecoder& grib)
      {
            if (!grib.getText()) return;    
       
            long centre = grib.getLong("identificationOfOriginatingGeneratingCentre");       
            long table  = grib.getLong("gribTablesVersionNo");
            long param  = grib.getLong("indicatorOfParameter");        

            
            
            try {
                  const ParamDef& parameter = LocalTable::localInfo(param, table, centre);
                  out << parameter.longTitle() << " ";
            }
            catch (...) {
                  out <<  param << "."  << table << " ";
                  
            }
      }
};

static locale& getLocale()
{
      static locale loc= locale::classic();
      try {
            loc = locale("");
      }
      catch (...)
      {
            Log::error() << "Problem to setup the locale" << endl;
            Log::error() << "Check you LANG variable-->current value : " <<  getEnvVariable("LANG")<< endl;
      
            loc= locale::classic();
      }
      return loc;
}

class GribBaseDateHandler : public TitleFieldHandler<GribDecoder>
{
public:
      GribBaseDateHandler() {}
      ~GribBaseDateHandler() {}
      virtual void operator()(TitleField& field, ostream& title, const GribDecoder& grib)
      {
            if (!grib.getText()) return;
            ostringstream out;

            long date = grib.getLong("date");    
            long hour = grib.getLong("hour");  
            long mn =  grib.getLong("minute"); 
            Date part1 = Date(date);
            Time part2 = Time(hour, mn, 0);
            DateTime full(part1, part2);
            tm convert = full;
            
            
                  out.imbue(getLocale());   
                  const std::time_put<char>& tfac = use_facet<time_put<char> >(getLocale()); 
                  string format = field.attribute("format", "%A %d %B %Y at %H UTC");
                  tfac.put(out, out, ' ', &convert, format.c_str(), format.c_str()+format.length());        
      
                  title << out.str() << " ";
                  Log::dev() << "title--> " << out.str() << endl;
      }
            
};

class GribValidDateHandler : public TitleFieldHandler<GribDecoder>
{
public:
    GribValidDateHandler() {}
    ~GribValidDateHandler() {}
    virtual void operator()(TitleField& field, ostream& title, const GribDecoder& grib)
    {

            ostringstream out;
        long date = grib.getLong("date");    
        long hour = grib.getLong("hour");  
        long mn   = grib.getLong("minute"); 
        long step = grib.getLong("step") * 3600; // needs steps in second! 
       
        Date part1 = Date(date);
        Time part2 = Time(hour, mn, 0);
        DateTime full(part1, part2);
        full = full + step;
        
       

        tm convert = full;
        try {
              locale loc("");
            
              out.imbue(loc);
          
            
              const time_put<char>& tfac = use_facet<time_put<char> >(loc); 
              string format = field.attribute("format", "%A %d %B %Y %H UTC");
              tfac.put(out, out, ' ', &convert, format.c_str(), format.c_str()+format.length());        
              title << out.str()  << " ";
        }
      catch (...)
            {
                  Log::error() << "Problem to setup the locale" << endl;
                  Log::error() << "Check you LOCALE variable-->current value : " <<  getEnvVariable("LANG")<< endl;
                  assert(false);
            }

    }
};

class GribStepHandler : public TitleFieldHandler<GribDecoder>
{
public:
    GribStepHandler() {}
    ~GribStepHandler() {}
    virtual void operator()(TitleField& field, ostream& title, const GribDecoder& grib)
    {

//        if (!grib.getText()) return;
//        ostringstream out;
//        grib_int_t istep;
//        grib_get(grib.id(),(grib_string_t*)"forecastTime","i",&istep);
//        
//        ostringstream step;
//        step << istep;
//        string format = field.attribute("format", "t+%s");     
//        out << SimpleStringFormat(step.str(), format);
//        title.add(out.str());

      }
};


class GribLevelHandler : public TitleFieldHandler<GribDecoder>
{
public:
    GribLevelHandler() { 
      if (map_.empty()) {
            map_["Surface"] = &GribLevelHandler::surface;
            map_["Unknown"] = &GribLevelHandler::surface;
            map_["unknown"] = &GribLevelHandler::surface;
      }
    }
    
    ~GribLevelHandler() {}
    typedef string (GribLevelHandler::*Builder)(GeneralDef& def, const GribDecoder& grib) const;
    
    virtual void operator()(TitleField&, ostream& out, const GribDecoder& grib)
    {
            if (!grib.getText()) return;       
        long level_type = grib.getLong("indicatorOfTypeOfLevel");
           
        GeneralDef def = LevelTable::definition(level_type);
        map<string,  GribLevelHandler::Builder>::iterator help = map_.find(def.longTitle());
        if ( help != map_.end() ) out << (this->*help->second)(def, grib) << " ";
        else out << singleLevel(def, grib) << " ";    
    }
    
protected: 
      static map<string, GribLevelHandler::Builder> map_;
      
      string surface(GeneralDef&, const GribDecoder& ) const {
            return "";
      }     
      string unknown(GeneralDef&, const GribDecoder& grib) const {
            ostringstream out;
            long level_type = grib.getLong("indicatorOfTypeOfLevel");
            out << "Unknown type of level[" << level_type << "]";
            return out.str();
      }     
      string singleLevel(GeneralDef& def, const GribDecoder& grib) const {
            ostringstream out;
            long level = grib.getLong("level");
            out  << level  <<  " " << def.longTitle();
        return out.str();
      }     
};
map<string, GribLevelHandler::Builder> GribLevelHandler::map_;


class GribTimeHandler : public TitleFieldHandler<GribDecoder>
{
public:
    GribTimeHandler() {}
    ~GribTimeHandler() {}
    virtual void operator()(TitleField&, ostream& title, const GribDecoder& grib)
    {

//        if (!grib.getText()) return;
//        ostringstream out;
//        grib_int_t idate;
//        grib_get(grib.id(),(grib_string_t*)"time","I",&idate);      
//     
//        out << "Time:" << idate;
//        title.add(out.str());

             title << "Time?" << " ";

    }
};

class GribCentreHandler : public TitleFieldHandler<GribDecoder>
{
public:
      GribCentreHandler() {}
      ~GribCentreHandler() {}
      virtual void operator()(TitleField&, ostream& title, const GribDecoder& grib)
      {

            long centre = grib.getLong("identificationOfOriginatingGeneratingCentre");    
            GeneralDef def = CentreTable::definition(centre);
            title << def.longTitle() << " ";

}
};

class GribProductHandler : public TitleFieldHandler<GribDecoder>
{
public:
    GribProductHandler() {}
    ~GribProductHandler() {}
    virtual void operator()(TitleField&, ostream& title, const GribDecoder& grib)
    {

         if (!grib.getText()) return;     
       long type = grib.getLong("type");
       string marstype = grib.getString("type");
       
       
       GeneralDef def = TypeTable::definition(type);
       title << def.longTitle()  << " ";
    
    }
};

class GribPlotTypeHandler : public TitleFieldHandler<GribDecoder>
{
public:
    GribPlotTypeHandler() {}
    ~GribPlotTypeHandler() {}
    virtual void operator()(TitleField&, ostream&,const GribDecoder&)
    {
         //Log::warning() << "Plot Type: not implemented--> wait for the specification." << "\n";
    }
};

class SatelliteHandler : public TitleFieldHandler<GribDecoder>
{
public:
    SatelliteHandler()  {}
    ~SatelliteHandler() {}
    virtual void operator()(TitleField&, ostream& title,const GribDecoder& grib)
    {
      
        long ident =  grib.getLong("ident");

        title << "Sat:" << ident << " ";
       
    }
};

class ChannelHandler : public TitleFieldHandler<GribDecoder>
{
public:
    ChannelHandler()  {}
    ~ChannelHandler() {}
    virtual void operator()(TitleField&, ostream& title,const GribDecoder& grib)
    {       
        long band = grib.getLong("obstype");
        title << "Band:" << band << " ";
    }
};


class GribExpverHandler : public TitleFieldHandler<GribDecoder>
{
public:
    GribExpverHandler() {}
    ~GribExpverHandler() {}
    virtual void operator()(TitleField& field, ostream& title, const GribDecoder& grib)
    {

         if (!grib.getText()) return;
       if ( !grib.getExpver() ) return; 
       ostringstream out;    
       string expver = grib.getString("mars.experimentVersionNumber");
       string format = field.attribute("format", "Expver=%s");          
       out << SimpleStringFormat(expver, format);
       title << out.str() << " ";

   }
};

class GribEpsNumberInfoHandler : public TitleFieldHandler<GribDecoder>
{
public:
    GribEpsNumberInfoHandler() {}
    ~GribEpsNumberInfoHandler() {}
    virtual void operator()(TitleField& field, ostream& title, const GribDecoder& grib)
    {
          
//       if (!grib.getText()) return;
//        ostringstream out;
//       grib_int_t local;
//       grib_get(grib.id(),(grib_string_t*)"localDefinition","I","localDefinitionNumber",&local);
//       if (local != 1) return;
//
//       char number[1024];
//       grib_get(grib.id(),(grib_string_t*)"localDefinition","s","total",number);
//       string format = field.attribute("format", "(%s members)");     
//      
//      out << SimpleStringFormat(number, format);
//        title.add(out.str());

         title << "epsnumber?";

    }
};


class GribUnitHandler : public TitleFieldHandler<GribDecoder>
{
public:
    GribUnitHandler() {}
    ~GribUnitHandler() {}
    virtual void operator()(TitleField& field, ostream& title, const GribDecoder& grib)
    {

            if (!grib.getText()) return;
        if ( !grib.getUnits() ) return; 
        ostringstream out;      
     
        long centre = grib.getLong("identificationOfOriginatingGeneratingCentre");       
        long table  = grib.getLong("gribTablesVersionNo");
        long param  = grib.getLong("indicatorOfParameter");        
          
        const ParamDef& parameter = LocalTable::localInfo(param, table, centre);
           
        string format = field.attribute("format", "Units:%s");           
        string unit = (grib.getScaling()) ? parameter.derivedUnit() :  parameter.originalUnit();
        out << SimpleStringFormat(unit, format);
        title << out.str();
   
    }
};

}// end namespace magics



static SimpleObjectMaker<GribParamCriter, MatchCriteria<GribDecoder> > gribparamcriter("parameter");
static SimpleObjectMaker<GribParamHandler, TitleFieldHandler<GribDecoder> > gribparamhandler("parameter");
static SimpleObjectMaker<GribBaseDateHandler, TitleFieldHandler<GribDecoder> > gribbasedatehandler("base_date");
static SimpleObjectMaker<GribValidDateHandler, TitleFieldHandler<GribDecoder> > gribvaliddatehandler("valid_date");
static SimpleObjectMaker<GribStepHandler, TitleFieldHandler<GribDecoder> > gribstephandler("step");
static SimpleObjectMaker<GribEpsNumberInfoHandler, TitleFieldHandler<GribDecoder> > gribepsnumberhandler("eps_number_info");

static SimpleObjectMaker<GribTimeHandler, TitleFieldHandler<GribDecoder> > gribTimehandler("time");
static SimpleObjectMaker<GribLevelHandler, TitleFieldHandler<GribDecoder> > gribLevelhandler("level");


static SimpleObjectMaker<GribStreamHandler, TitleFieldHandler<GribDecoder> > gribstreamhandler("stream");
static SimpleObjectMaker<GribClassHandler, TitleFieldHandler<GribDecoder> > gribclasshandler("class");
static SimpleObjectMaker<GribTypeHandler, TitleFieldHandler<GribDecoder> > gribtypehandler("type");
static SimpleObjectMaker<GribLocalDefHandler, TitleFieldHandler<GribDecoder> > griblocaldefhandler("localdef");
static SimpleObjectMaker<GribCentreHandler, TitleFieldHandler<GribDecoder> > gribcentrehandler("centre");
static SimpleObjectMaker<GribProductHandler, TitleFieldHandler<GribDecoder> > gribproducthandler("product");
static SimpleObjectMaker<GribUnitHandler, TitleFieldHandler<GribDecoder> > gribunithandler("units");
static SimpleObjectMaker<GribExpverHandler, TitleFieldHandler<GribDecoder> > gribexpverhandler("expver");
static SimpleObjectMaker<GribPlotTypeHandler, TitleFieldHandler<GribDecoder> > gribplottypehandler("plot_type");
static SimpleObjectMaker<SatelliteHandler, TitleFieldHandler<GribDecoder> > satellitehandler("satellite");
static SimpleObjectMaker<ChannelHandler, TitleFieldHandler<GribDecoder> > channelhandler("channel");
static SimpleObjectMaker<GribBaseDateHandler, TitleFieldHandler<GribDecoder> > datehandler("date");



static SimpleObjectMaker<GribLocalCriter, MatchCriteria<GribDecoder> > gribstreamcriter("stream");
static SimpleObjectMaker<GribLocalCriter, MatchCriteria<GribDecoder> > gribtypecriter("type");
static SimpleObjectMaker<GribLocalCriter, MatchCriteria<GribDecoder> > gribclasscriter("class");


#include "GribRegularInterpretor.h"
static SimpleObjectMaker<GribRegularInterpretor, GribInterpretor> regular_ll("regular_ll");
static SimpleObjectMaker<GribReducedLatLonInterpretor, GribInterpretor> reduced_ll("reduced_ll");
static SimpleObjectMaker<GribRegularGaussianInterpretor, GribInterpretor> regular_gg("regular_gg");
static SimpleObjectMaker<GribReducedGaussianInterpretor, GribInterpretor> reduced_gg("reduced_gg");
static SimpleObjectMaker<GribRotatedInterpretor, GribInterpretor> rotated_ll("rotated_ll");
static SimpleObjectMaker<GribLambertAzimutalInterpretor, GribInterpretor> lambert_azimuthal_equal_area("lambert_azimuthal_equal_area");


#include "GribSatelliteInterpretor.h"
static SimpleObjectMaker<GribSatelliteInterpretor, GribInterpretor> satellite("space_view");

Generated by  Doxygen 1.6.0   Back to index