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

FortranMagics.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 FortranMagics.cc
    \brief Implementation of the Template class FortranMagics.
    
    Magics Team - ECMWF 2007
    
    Started: Fri 9-Mar-2007
    
    Changes:
    
*/


#include "magics_ecmwf_log.h"
#include "FortranMagics.h"
#include "Timer.h"

#include "RootSceneNode.h"
#include "SceneNode.h"
#include "ViewNode.h"
#include "Coastlines.h"
#include "TextVisitor.h"
#include "LegendVisitor.h"
#include "VisualAction.h"
#include "GribDecoder.h"
#include "GeoPointsDecoder.h"
#include "Contour.h"
#include "GeoPoint.h"
#include "UserPoint.h"
#include "SymbolInput.h"
#include "SymbolPlotting.h"
#include "Wind.h"
#include "Axis.h"
#include "XYList.h"
#include "GraphPlotting.h"
#include "InputMatrix.h"
#include "NetcdfDecoder.h"
#include "ImagePlotting.h"
#include "BoxPlotDecoder.h"
#include "BoxPlotVisualiser.h"
#include "SimplePolylineInput.h"
#include "SimplePolylineVisualiser.h"
#include "TitleTemplate.h"
#include "TaylorGrid.h"

#include "ImportAction.h"
#include "ImportPlot.h"
#include "ImportObjectHandler.h"

#ifdef MAGICS_BUFR
#include "ObsPlotting.h"
#include "ObsDecoder.h"
#endif


using namespace magics;

FortranMagics::FortranMagics() :  drivers_(0), output_(0), geoaction_(0), xyaction_(0), empty_(true), gribindex_(0),legend_done_(false)
{
      assert (singleton_ == 0);
      singleton_ = this;

      if(getEnvVariable("MAGPLUS_HOME").empty())
      {
            Log::error() << "FATAL ERROR: $MAGPLUS_HOME has to be defined!!!"<< "\n";
            exit(0);
      }

      writeLog("fortran");
}     


FortranMagics::~FortranMagics() 
{
      if ( drivers_ ) delete drivers_;
      if ( root_ ) delete root_;
      if ( output_ ) delete output_;
      singleton_ = 0;
      
      /* 
      ParameterManager::release();
      TitleTemplate::release();

      GribDecoder::releaseContext();
      */
}

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

void FortranMagics::popen()
{
   if(getEnvVariable("MAGPLUS_QUIET").empty() )
   {
      Log::userInfo() << "------------------------------------------------------------------\n";
      Log::userInfo() << "\n";
      Log::userInfo() << "                  "<< getMagicsVersionString() <<"\n";
      Log::userInfo() << "\n";
      Log::userInfo() << " Meteorological Applications Graphics Integrated Colour System\n";
      Log::userInfo() << "\n";
      Log::userInfo() << "                    Developed By\n";     
      Log::userInfo() << "\n";
      Log::userInfo() << "   The European Centre for Medium-Range Weather Forecasts\n";
      Log::userInfo() << "\n";
      Log::userInfo() << "                Copyright ECMWF "<<MAGICS_COPYRIGHT_PERIOD<<"\n";
      Log::userInfo() << "\n";
      Log::userInfo() << "------------------------------------------------------------------\n";
   }
   actions_.push(&FortranMagics::subpage);      
   actions_.push(&FortranMagics::page);   
   actions_.push(&FortranMagics::superpage);    
   actions_.push(&FortranMagics::drivers);      
}

void FortranMagics::pclose()
{
      finish();

      if ( root_ )
      {
            drivers_->setDriversWidth(root_->absoluteWidth());
            drivers_->setDriversHeight(root_->absoluteHeight());
  
            root_->execute();
            drivers_->openDrivers();
            drivers_->dispatch(root_->root());
            drivers_->closeDrivers();

            delete root_;
            delete drivers_;
            delete output_;

            drivers_ = 0;
            root_ = 0;
            output_ = 0;
      }

      if(getEnvVariable("MAGPLUS_QUIET").empty() )
      {
      /*
            Log::userInfo() << "------------------------------------------------------------------\n";
            Log::userInfo() << " Output files generated:\n";
            stringarray::iterator it = output_resource_list_.begin();
            stringarray::iterator itend = output_resource_list_.end();
            for(; it != itend; it++)
            {
                  Log::userInfo() << "  - "<<(*it)<<"\n";  
            }
            Log::userInfo() << "\n";
      */
            Log::userInfo() << "------------------------------------------------------------------\n";
            Log::userInfo() << "    COMPLETED\n";
            Log::userInfo() << "\n";
            Log::userInfo() << "    Any problems or suggestions? Please contact us at\n";
            Log::userInfo() << "                magicsplus@ecmwf.int\n";
            Log::userInfo() << "------------------------------------------------------------------\n";
      }
}

void FortranMagics::drivers()
{
      if (!drivers_)  drivers_ = new DriverManager();
      if (!output_)   output_ = new OutputHandler();
      output_->set(*drivers_);
}

void FortranMagics::subpage()
{
      axisContainer_ = new FortranViewNode();   

      top()->push_back(axisContainer_);
      axisContainer_->getReady();
      push(axisContainer_);
      
      
}


void FortranMagics::page()
{
      if ( empty() ) return;
      
      while (top() != root_) {
            pop(); 
            if ( empty() ) break;
      }
      
      FortranSceneNode* node = new FortranSceneNode();
      root_->insert(node);
      push(node);
}

void FortranMagics::newpage()
{
      if ( empty() ) return;
      BasicSceneObject* to = top();
      
      while ( to != root_) {
            pop();
            to = top();
            if ( empty() ) break;
      }

      
      root_->newpage();
      //push(node);
}

void FortranMagics::superpage()
{
      root_ = new FortranRootSceneNode();
            push(root_);
}

void FortranMagics::legend()
{
      if ( legends_.empty() == false ) return;
    bool legend = Translator<string,bool>().magics("legend");
    
    if (!legend) return; 
    
    legend_done_ = true;   
    string mode;  
    ParameterManager::get("legend_box_mode", mode);
  
    if (magCompare(mode, "positional") ) 
      legends_.push_back(new FortranPositionalLegendVisitor()); 
    else 
      legends_.push_back(new FortranAutomaticLegendVisitor());          
      
}
void FortranMagics::plegend()
{    
    if ( actions_.empty() ) 
      legend(); // force the legend to be added! 
}

void FortranMagics::poverlay()
{    
      actions();        
      
      if (geographical()) {
            geoaction_ = new VisualAction<GeoPoint>();                        
          ImportAction<GeoPoint>* input = new ImportAction<GeoPoint>();
            ImportPlot<GeoPoint>* plot = new ImportPlot<GeoPoint>();
            top()->push_back(geoaction_); 
            geoaction_->data(input);
            Log::dev() << *input << "\n";   
            geoaction_->visdef(plot);
      }
      else {
            xyaction_ = new VisualAction<UserPoint>();
            
            ImportAction<UserPoint>* input = new ImportAction<UserPoint>();
            ImportPlot<UserPoint>* plot = new ImportPlot<UserPoint>();
            top()->push_back(xyaction_);  
            xyaction_->data(input);
            Log::dev() << *input << "\n";   
            xyaction_->visdef(plot);
      }
      
      
}
void FortranMagics::pimport()
{
      
      
      ImportObjectHandler* object = new ImportObjectHandler();
      
      later_.push_back(object);
}


void FortranMagics::pnew(const string& type)
{
      
                  
      

      
      if ( magCompare(type, "subpage") )
      {     
               if ( empty_ ) return;
                  finish();
            pop();
            actions_.push(&FortranMagics::subpage);   
      }
      if ( magCompare(type, "page") ) {
               if ( empty_ ) return;
                              finish();
            pop();
            actions_.push(&FortranMagics::subpage);   
            actions_.push(&FortranMagics::page);      
      }
      if ( magCompare(type, "super_page") ) {
                  finish();
                actions_.push(&FortranMagics::subpage);     
                actions_.push(&FortranMagics::page);  
                actions_.push(&FortranMagics::newpage);
      }
      // WE reset ! 
      axisContainer_ = 0;
      geoaction_ = 0;
      xyaction_ = 0;
      empty_ = true;
      
}

void FortranMagics::actions()
{
      while (!actions_.empty())
      {
            Action action = actions_.top();
            (this->*action)();
            actions_.pop();
            empty_ = false; 
      }
}


void FortranMagics::pcoast()
{
      actions();        

      Coastlines* coastlines = new Coastlines();
      top()->push_back(coastlines);
}

void FortranMagics::ptaylor()
{
      actions();        

      TaylorGrid* taylor = new TaylorGrid();
      top()->push_back(taylor);
}

void FortranMagics::pobs()
{
      actions();        
#ifdef MAGICS_BUFR
      geoaction_ = new VisualAction<GeoPoint>();
      geoaction_->data(new ObsDecoder());
      top()->push_back(geoaction_);
      geoaction_->visdef(new ObsPlotting());
#else
      Log::warning() << "OBS support is disabled!\n";
#endif
}

#include "MatrixTestDecoder.h"
void FortranMagics::ptest()
{
      actions();
      geoaction_ = new VisualAction<GeoPoint>();
      geoaction_->data(new MatrixTestDecoder());
      top()->push_back(geoaction_);
}

void FortranMagics::finish()
{
      if ( !empty_ ) {
            actions(); // The flag to force the generation of the plot has been set!  
            while ( !axis_.empty() ) {
                                    axisContainer_->push_back(axis_.top());
                                    axis_.pop();
            }
      }
      
      if ( !axisContainer_ ) return;
      // check if we have to add a legend! 
      if ( axisContainer_ &&  !axisContainer_->items_empty() ) {
            legend();
            for (vector<LegendVisitor* >::iterator legend = legends_.begin();  legend != legends_.end(); ++legend) {
                                                top()->legend(*legend);
                                          
                                    }
                                    
                              legends_.clear();
      }
      
      // Check any text 
      
    
      for (vector<BasicSceneObject* >::iterator other = later_.begin();  other != later_.end(); ++other) {
                              top()->push_back(*other);
                              
                        }
                        later_.clear();
      
      for (vector<FortranTextVisitor* >::iterator text = texts_.begin();  text != texts_.end(); ++text) {
                              top()->text(*text);
                              
                        }
                        texts_.clear();
                        
                  
}
void FortranMagics::pgrib()
{
      actions();
      geoaction_ = new VisualAction<GeoPoint>();
      static string gribfile;
      
      
      string grib;
      ParameterManager::get("grib_input_file_name", grib);
      int index;
      ParameterManager::get("grib_field_position", index);
      
    if ( grib == gribfile  ) {
      if ( index == gribindex_ ) {
            gribindex_++;
      }
      else {
            gribindex_ = index;
      }
      ParameterManager::set("grib_field_position", gribindex_);
    }
    else {
      gribfile = grib;
      gribindex_ = index;
    }
    
      geoaction_->data(new GribDecoder());
      top()->push_back(geoaction_);
}

void FortranMagics::pgeo()
{
      actions();
      geoaction_ = new VisualAction<GeoPoint>();
      geoaction_->data(new GeoPointsDecoder());
      top()->push_back(geoaction_);
}

void FortranMagics::pnetcdf()
{
      actions();
      if (geographical()) {
            geoaction_ = new VisualAction<GeoPoint>();
            geoaction_->data(new NetcdfDecoder<GeoPoint>());
            top()->push_back(geoaction_);
      }
      else {      
            xyaction_ = new VisualAction<UserPoint>();
            xyaction_->data(new NetcdfDecoder<UserPoint>());
            top()->push_back(xyaction_);
      }
}


void FortranMagics::pimage()
{

      actions();

      if ( geographical() ) {
            if ( !geoaction_ ) {
                  geoaction_ = new VisualAction<GeoPoint>();
                  geoaction_->data(new GribDecoder());
            }                 
            geoaction_->visdef(new ImagePlotting<GeoPoint>());
      }
      else {
            assert(xyaction_);
            xyaction_->visdef(new ImagePlotting<UserPoint>());
      }
      geoaction_ = 0;
      xyaction_ = 0;

}

#include "OdaDecoder.h"

void FortranMagics::podb()
{
#ifdef MAGICS_ODB
      geoaction_ = new VisualAction<GeoPoint>();
      geoaction_->data(new OdaDecoder());
    top()->push_back(geoaction_);
#endif
}


void FortranMagics::data(Data<GeoPoint>* data)
{
      assert ( geoaction_ == 0);
      geoaction_ = new VisualAction<GeoPoint>();
      geoaction_->data(data);
      top()->push_back(geoaction_);
}

void FortranMagics::data(Data<UserPoint>* data)
{
      assert ( xyaction_ == 0);
      xyaction_ = new VisualAction<UserPoint>();
      xyaction_->data(data);
      top()->push_back(xyaction_);
}


bool FortranMagics::geographical()
{
      string projection;
      ParameterManager::get("subpage_map_projection", projection);
      if ( magCompare(projection, "cartesian") ) return false;
      if ( magCompare(projection, "taylor") ) return false;
      return true;
}

template <class T>
void param(const string& from, const string& to, T& val)
{
      ParameterManager::get(from, val);
      ParameterManager::set(to,val);
}

template <class P>
void split(VisualAction<P>& action) {
      string split;
      //ParameterManager::get("contour_line_plotting", split);
      if ( magCompare(split, "split")) {
                  Log::warning() << " contour_line_plotting is deprecated" << endl;
                  double level;
                  ParameterManager::get("contour_split_level", level);
                  double max, min;
                  ParameterManager::get("contour_max_level", max);
                  ParameterManager::get("contour_min_level", min);
                  // set the below contour
                  ParameterManager::set("contour_max_level", level);
                  
                  LineStyle style, highlightstyle;
                  double thickness, highlightthickness;
                  string colour, highlightcolour;
                  
                  param("contour_below_line_style", "contour_line_style", style);
                  param("contour_below_line_thickness", "contour_line_thickness", thickness);
                  param("contour_below_line_colour", "contour_line_colour", colour);
                  param("contour_below_highlight_style", "contour_highlight_line_style", highlightstyle);
                  param("contour_below_highlight_thickness", "contour_highlight_line_thickness", highlightthickness);
                  param("contour_below_highlight_colour", "contour_highlight_line_colour",highlightcolour);
                  
                  action.visdef(new Contour<P>());
                  
                  // set the above contour
                  ParameterManager::set("contour_max_level", max);
                  ParameterManager::set("contour_min_level", level);
                  param("contour_above_line_style", "contour_line_style", style);
                  param("contour_above_line_thickness", "contour_line_thickness", thickness);
                  param("contour_above_line_colour", "contour_line_colour", colour);
                  param("contour_above_highlight_style", "contour_highlight_line_style", style);
                  param("contour_above_highlight_thickness", "contour_highlight_line_thickness", thickness);
                  param("contour_above_highlight_colour", "contour_highlight_line_colour", colour);
                  action.visdef(new Contour<P>());
                  // Should we reset???               
      }
      else {
            action.visdef(new Contour<P>());
      }
            
}

void FortranMagics::pcont()
{
      // First check any split contour! I hate it! 
      
      actions();        
      if ( geographical() ) {
      if ( !geoaction_ ) {
            geoaction_ = new VisualAction<GeoPoint>();
            InputMatrix<GeoPoint>* input = new InputMatrix<GeoPoint>();     
            if (input->defined() ) 
                  geoaction_->data(input);                                    
            else {
                  delete input;
                  geoaction_->data(new GribDecoder());
            }
            top()->push_back(geoaction_); 
      }

      split(*geoaction_);
      geoaction_ = 0;
      }
      else {
            if ( !xyaction_ ) {
                  xyaction_ = new VisualAction<UserPoint>();
                  InputMatrix<UserPoint>* input = new InputMatrix<UserPoint>();     
                  if (input->defined() ) 
                        xyaction_->data(input);                               
                  else {
                        Log::error() << "No data defined!" << endl;
                        return;
                  }
                  top()->push_back(xyaction_);  
            }
            split(*xyaction_);
            xyaction_ = 0;
      }
}

void FortranMagics::pwind()
{
      actions();        
      if ( !geoaction_ )
      {
            geoaction_ = new VisualAction<GeoPoint>();
            InputMatrix<GeoPoint>* input = new InputMatrix<GeoPoint>();     
            if (input->defined() ) 
                  geoaction_->data(input);                                    
            else {
                  delete input;
                  geoaction_->data(new GribDecoder());
            }
            top()->push_back(geoaction_); 
      }

      geoaction_->visdef(new Wind<GeoPoint>());
      geoaction_ = 0;
}





void FortranMagics::ptext()
{
      
      string mode;
      ParameterManager::get("text_mode", mode);
      
      
      FortranTextVisitor* node;
      if ( magCompare(mode, "positional") ) 
            node = new FortranPositionalTextVisitor(); 
      else 
            node = new FortranAutomaticTextVisitor(); 
      
      texts_.push_back(node);
      empty_ = false;
      
}

void FortranMagics::psymb()
{
      actions();  
 
      string mode;
      ParameterManager::get("symbol_position_mode", mode);
      if ( magCompare(mode, "graph")  )
      {
            xyaction_ = new VisualAction<UserPoint>();
            SymbolInput<UserPoint>* input = new SymbolInput<UserPoint>();
            top()->push_back(xyaction_);
            xyaction_->data(input);
            Log::dev() << *input << "\n";

            SymbolPlotting<UserPoint>* symbol = new SymbolPlotting<UserPoint>();
            Log::dev() << *symbol << "\n";
            xyaction_->visdef(symbol);
            xyaction_ = 0;
      }
      else
      {
            if ( geographical() ) {
                  if ( !geoaction_ ) {
                        geoaction_ = new VisualAction<GeoPoint>();
                        SymbolInput<GeoPoint>* input = new SymbolInput<GeoPoint>();
                        top()->push_back(geoaction_);
                        geoaction_->data(input);
                        Log::dev() << *input << "\n";
                  }     

                  SymbolPlotting<GeoPoint>* symbol = new SymbolPlotting<GeoPoint>();
                  Log::dev() << *symbol << "\n";
                  geoaction_->visdef(symbol);

                  geoaction_ = 0;
            }
            else {
                  if ( !xyaction_ ) {
                        xyaction_ = new VisualAction<UserPoint>();
                        SymbolInput<UserPoint>* input = new SymbolInput<UserPoint>();                       
                        top()->push_back(xyaction_);  
                        xyaction_->data(input);
                  }
                  xyaction_->visdef(new SymbolPlotting<UserPoint>());
                  xyaction_ = 0;
            }
      }
}

void FortranMagics::pline()
{
      actions();

      VisualAction<GeoPoint>* action = new VisualAction<GeoPoint>();

      SimplePolylineInput* input = new SimplePolylineInput();
      SimplePolylineVisualiser* plot = new SimplePolylineVisualiser();
      top()->push_back(action);     
      action->data(input);
      Log::dev() << *input << "\n";   
      action->visdef(plot);
      
}


void FortranMagics::paxis()
{
      
      try {
            string orientation;
            
            ParameterManager::get("axis_orientation", orientation); 
//          
            if (magCompare(orientation, "vertical") ) {
                  Axis* vaxis = new VerticalAxis();           
                  Log::dev() << *vaxis << "\n";
                  axis_.push(vaxis);
            } 
            else {                  
                  Axis* haxis = new HorizontalAxis();
                  Log::dev() << *haxis << "\n";
                  axis_.push(haxis);
            }
      }
      catch (MagicsException& e)
      {
            Log::error() << e << "\n";
      }
      empty_= false; // Force the generation of the plot!
}



void FortranMagics::pgraph()
{
      actions();        

      xyaction_ = new VisualAction<UserPoint>();

      GraphPlotting* graph = new GraphPlotting();
      top()->push_back(xyaction_);
      XYList<UserPoint>* input = new XYList<UserPoint>();   
      xyaction_->data(input);
      Log::dev() << *input << "\n";   
      xyaction_->visdef(graph);
}

void FortranMagics::pboxplot()
{
      actions();        
      
      xyaction_ = new VisualAction<UserPoint>();
      
      BoxPlotDecoder* input = new BoxPlotDecoder();
      BoxPlotVisualiser* plot = new BoxPlotVisualiser();
      top()->push_back(xyaction_);  
      xyaction_->data(input);
      Log::dev() << *input << "\n";   
      xyaction_->visdef(plot);
}

FortranMagics* FortranMagics::singleton_ = 0;

Generated by  Doxygen 1.6.0   Back to index