Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

plotspecification.h

Go to the documentation of this file.
00001 
00007 #ifndef __PLOT_SPECIFICATION_H__
00008 #define __PLOT_SPECIFICATION_H__
00009 
00010 #include <utility>
00011 #include <string>
00012 using std::string;
00013 
00014 // Uses roundabout paths to the current directory to avoid Cray C bug
00015 #include "../src/matriximagefactory.h"
00016 #include "../src/pointermap.h"
00017 #include "../src/allocatingpointer.h"
00018 #include "../src/tnt_gnuplot.h"
00019 #include "../src/msg.h"
00020 #include "../src/parammap.h"
00021 #include "../src/stringutils.h"
00022 #include "../src/matrixhistogram.h"
00023 #include "../src/histogramimage.h"
00024 #include "../src/scale.h"
00025 
00026 
00027 /* Helper functions, without a real home */ 
00028 
00029 
00033 template<class Color>
00034 Color lookup_color
00035 (const ParamMap& params, const string& basename, const Color& default_val)
00036 {
00037   /* Assumes there will be three parameters named with the given
00038      suffixes, one for each color component. */
00039   const string R_param = basename+"_R";
00040   const string G_param = basename+"_G";
00041   const string B_param = basename+"_B";
00042   const double R = params.get_with_default(R_param.c_str(), default_val.red());
00043   const double G = params.get_with_default(G_param.c_str(), default_val.green());
00044   const double B = params.get_with_default(B_param.c_str(), default_val.blue());
00045   return Color(R,G,B);
00046 }
00047 
00048 
00049 
00052 template<class SubRegion>
00053 SubRegion lookup_subregion
00054 (const ParamMap& params, const SubRegion& default_val)
00055 {
00056   const int s_c  = params.get_with_default("start_c", -1);
00057   const int s_r  = params.get_with_default("start_r", -1);
00058   const int e_c  = params.get_with_default("end_c",   -1);
00059   const int e_r  = params.get_with_default("end_r",   -1);
00060 
00061   if (s_c<0 || s_r<0 || e_c<0 || e_r<0)
00062     return default_val;
00063   return   SubRegion(-s_c,-s_r,-e_c,-e_r);
00064 }
00065 
00066 
00067 
00068 namespace  Plot {
00069 
00070 
00071   
00076 template<class ParamMapType>
00077 ParamMapType* PlotSpec_params(const string& child_name,
00078                               ParamMapType& parent,
00079                               const string& strength_name="",
00080                               const string& color_name="",
00081                               const string& confidence_name="")
00082 {
00083   /* The dynamic_cast is required only because new_child has to return
00084      the base type only (to work with some compilers, e.g. Cray C++) */
00085   ParamMapType* p  = dynamic_cast<ParamMapType*>(parent.new_child(child_name));
00086   PlotSpec_child_map(*p,"Strength",strength_name);
00087   PlotSpec_child_map(*p,"Color",color_name);
00088   PlotSpec_child_map(*p,"Confidence",confidence_name);
00089   PlotSpec_child_map(*p,"Histogram","",false);
00090   return p;
00091 }
00092 
00093 
00094 
00097 template<class ParamMapType>
00098 ParamMapType* PlotSpec_child_map(ParamMapType& parent, const string& childname, const string& matrixname="",
00099                                  bool setmatrixname=true)
00100 {
00101   ParamMapType* c = dynamic_cast<ParamMapType*>(parent.new_child(childname,true)); assert(c);
00102   if (setmatrixname) c->set_local("name",matrixname);
00103   return c;
00104 }
00105 
00106 
00115 template <class Matrix, class String=string, class ScaleType=Scale::Linear<>,
00116           class MatrixTableType=PointerMap<Matrix>,
00117           class ParameterMapType=ParamMap >
00118 class PlotSpecification {
00119   typedef const String cStr;
00120   typedef ParameterMapType ParamMapType;
00121   typedef Histo::OneDHistogram<> Histogram;
00122   typedef Plot::RGBPixel<> ColorType;
00123   
00124 public:
00125   typedef MatrixTableType  MatrixTable;
00126 
00127 private:
00128   
00132   PlotSpecification(cStr& objectname, const MatrixTable& maptable, cStr& name, ParamMapType* params_)
00133     : plotname(name), objname(objectname), params(params_,true), maps(&maptable) { }
00134 
00135 public:
00137   typedef Boundary::AAArbitraryRectangle<double,int> SubRegion;
00138 
00147   const Matrix* reference_mapptr() const {
00148     assert (maps->begin()!=maps->end());
00149     return maps->begin()->second;
00150   }
00151   
00153   template <class DerivedFromParamMap>
00154   PlotSpecification(cStr& objectname, const MatrixTable& maptable, cStr& name, DerivedFromParamMap& parentparams,
00155                     const string& strength_name="", const string& color_name="", const string& confidence_name="")
00156     : plotname(name), objname(objectname),
00157       params(PlotSpec_params(name,parentparams,strength_name,color_name,confidence_name),true),
00158       maps(&maptable) { }
00159 
00160   ~PlotSpecification() {  }
00161   
00163   const string name()       const {  return plotname;  }
00164 
00167   const string objectname() const {  return objname;  }
00168 
00169   bool                 save_matrix  (const string filebase, const MatrixTable* tempmaps=0,
00170                                      const SubRegion* overriding_region=0) const;
00171   bool                 gnuplot_image(const string filebase, const MatrixTable* tempmaps=0,
00172                                      const SubRegion* overriding_region=0) const;
00173   Plot::MatrixImage<>* bitmap_image(const double master_scale=-1, const SubRegion* reference=0, const MatrixTable* tempmaps=0,
00174                                     const SubRegion* overriding_region=0,
00175                                     const int border_width=-1, const string overriding_colorspec="") const;
00176   Plot::AARImage<>*    bitmap_histogram(const double master_scale, const ParamMap& defaults, const SubRegion* reference,
00177                                         const MatrixTable* tempmaps=0, const string& name="Histogram") const;
00178 
00179   
00180   static void message(Msg::MessageLevel m, const string& s, const bool terminate=True) {
00181     // Written in this awkward fashion to avoid bug (ICE) in GCC 2.95
00182     const bool nonnull = (mhp!=0 && (*mhp)); 
00183     if (nonnull) (**mhp)(m,s,terminate);
00184   }
00185 
00188   template <class T>
00189   T lookup_param(const string& name, const T& default_val) const 
00190     {  return lookup_param(*params,name.c_str(),default_val);  }
00191   
00192   /* Cascading lookup command, with up to two levels of backup maps.
00193      The routine retrieves the parameter from each of the given maps,
00194      in order, returning the first value found that differs from the
00195      given default. If none were found or none differed, the default
00196      value itself is returned.
00197 
00198      This routine could possibly be used (within the ParameterMap
00199      class routine get_with_default) as the basis for a
00200      general-purpose defaults system, with each ParameterMap knowing
00201      the name of its set of defaults, to which get_with_default turns
00202      when only a default value is found (e.g. if never set
00203      explicitly).
00204   */
00205   template <class T>
00206   T lookup_param(const ParamMap& params1, const string& name, const T& default_val,
00207                  const ParamMap* params2=0, const ParamMap* params3=0) const {
00208     const T p1=params1.get_with_default(name.c_str(),default_val);
00209     if (p1!=default_val || !params2) return p1;
00210 
00211     const T p2=params2->get_with_default(name.c_str(),default_val);
00212     if (p2!=default_val || !params3) return p2;
00213     
00214     return     params3->get_with_default(name.c_str(),default_val);
00215   }
00216   
00217 
00218   ParamMapType&       param_map()       {  return *(params.valueptr());  }
00219   const ParamMapType& param_map() const {  return *params;               }
00220   
00221 private:
00222   Plot::AARImage<>* histogram_image(const double master_scale,
00223                                     const SubRegion* reference,
00224                                     const ParamMap&  histoparams,
00225                                     const Histogram& histo) const;
00226     
00227   double compute_size_scale(const double master_scale, const double specified_scale,
00228                             const SubRegion& paramregion, const SubRegion* reference) const;
00229 
00231   const Matrix* map_getptr(const string& name, const MatrixTable* tempmaps=0, bool warn=true) const {
00232     if (name=="") return 0;
00233     const Matrix* p  = (tempmaps ? tempmaps->getptr(name) : 0);
00234     const Matrix* pp = (p? p : maps->getptr(name) );
00235     if (warn && !pp && name!=lastwarning && name!=previouswarning) {
00236       message(Msg::Warning, "Could not find map matrix named '" + name
00237               + "' when plotting " + plotname + " for " + objname );
00238       previouswarning=lastwarning;
00239       lastwarning=name;
00240     }
00241     return pp;
00242   }
00243   
00244 
00245   /* Convenience macro which looks up the map name under the given
00246      paramname in the given parameter map */
00247   const Matrix* map_getptr(const ParamMap& params, const MatrixTable* tempmaps=0,
00248                            bool warn=true, const string& paramname="name") const
00249     {  return map_getptr(lookup_param(params, paramname, string()),tempmaps, warn);  }
00250   
00251   String plotname, objname;
00252   
00253   OwningPointer<ParamMapType> params;
00254   const MatrixTable* maps;
00255   
00259   mutable string lastwarning,previouswarning;
00260 
00261   static Msg::LevelHandler<>** mhp;
00262 };
00263 
00264 
00265 /* Static variables */
00266 template <class Matrix,class String,class ScaleType,class MatrixTableType,class ParameterMapType>
00267 Msg::LevelHandler<>**
00268 PlotSpecification<Matrix,String,ScaleType,MatrixTableType,ParameterMapType>::
00269 mhp=&(Msg::LevelHandler<>::default_instance());
00270 
00271 
00272 
00282 template <class Matrix,class String,class ScaleType,class MatrixTableType,class ParameterMapType>
00283 bool
00284 PlotSpecification<Matrix,String,ScaleType,MatrixTableType,ParameterMapType>::
00285 gnuplot_image(const string filebase, const MatrixTable* tempmaps,
00286               const SubRegion* overriding_region) const
00287 {
00288   const string  outname = (filebase=="" ? "" : filebase+"_"+objectname()+"_"+name()+".ps");
00289   const string  title   = objectname() + " " + name();
00290   const Matrix* s = map_getptr(params->get_child("Strength"), tempmaps);
00291   const Matrix* c = map_getptr(params->get_child("Color"),    tempmaps);
00292   const SubRegion paramregion = lookup_subregion(*params,SubRegion());
00293   const SubRegion subregion   = (overriding_region? *overriding_region : paramregion);
00294   typedef typename Matrix::value_type T;
00295   typedef mat::MatrixInterface<T> BaseMatrixType;
00296   typedef mat::MatrixAdapter<BaseMatrixType> MatrixWindow;
00297   
00298   const string messages = (s?  mat::gnuplot(MatrixWindow(*s,1.0,subregion),title,outname) :
00299                            (c? mat::gnuplot(MatrixWindow(*c,1.0,subregion),title,outname) : string()));
00300 
00301   if (messages != "") {
00302     message(Msg::Warning, "Gnuplot wrapper for " + title + ": " + messages);
00303     return false;
00304   }
00305   
00306   return true;
00307 }
00308 
00309 
00310 
00315 template <class Matrix,class String,class ScaleType,class MatrixTableType,class ParameterMapType>
00316 bool
00317 PlotSpecification<Matrix,String,ScaleType,MatrixTableType,ParameterMapType>::
00318 save_matrix(const string filebase, const MatrixTable* tempmaps,
00319             const SubRegion* overriding_region) const
00320 {
00321   /* Mostly copied from gnuplot_image */
00322   const string  outname = (filebase=="" ? "" : filebase+".matrix");
00323   const string  title   = objectname() + " " + name();
00324   const Matrix* s = map_getptr(params->get_child("Strength"), tempmaps);
00325   const Matrix* c = map_getptr(params->get_child("Color"),    tempmaps);
00326   const SubRegion paramregion = lookup_subregion(*params,SubRegion());
00327   const SubRegion subregion   = (overriding_region? *overriding_region : paramregion);
00328   typedef typename Matrix::value_type T;
00329   typedef mat::MatrixInterface<T> BaseMatrixType;
00330   typedef mat::MatrixAdapter<BaseMatrixType> MatrixWindow;
00331 
00332   std::ofstream matrixfile(outname.c_str());
00333   if (!matrixfile) {
00334     message(Msg::Warning, "Could not open matrix file " + outname);
00335     return false;
00336   }
00337   if (!c && !s){
00338     message(Msg::Warning, "Nothing to plot");
00339     return true;
00340   }
00341   MatrixWindow submatrix((s? *s : *c),1.0,subregion);
00342   
00343   /* Octave-compatible header */
00344   matrixfile
00345     << "# Created from " << title << std::endl
00346     << "# name: "        << name() << std::endl
00347     << "# type: matrix"  << std::endl
00348     << "# rows: "        << submatrix.nrows() << std::endl
00349     << "# columns: "     << submatrix.ncols() << std::endl;
00350 
00351   stream_output(MatrixWindow((s? *s : *c),1.0,subregion),matrixfile);
00352 
00353   return true;
00354 }
00355 
00356 
00357 
00363 template <class Matrix,class String,class ScaleType,class MatrixTableType,class ParameterMapType>
00364 double
00365 PlotSpecification<Matrix,String,ScaleType,MatrixTableType,ParameterMapType>::
00366 compute_size_scale(const double master_scale, const double specified_scale,
00367                    const SubRegion& paramregion, const SubRegion* reference) const
00368 {
00369   if (!reference) return specified_scale;
00370 
00371   if (master_scale>0) {
00372     const double height  = (!paramregion.isinfinite()? paramregion.height() : reference_mapptr()->nrows());
00373     const double width   = (!paramregion.isinfinite()? paramregion.width()  : reference_mapptr()->ncols());
00374     const int    hfactor = int(master_scale*reference->height()/height);
00375     const int    wfactor = int(master_scale*reference->width()/width);
00376     const int    factor  = std::min(hfactor,wfactor);
00377     if (factor>0) return factor;
00378   }
00379   
00380   return specified_scale;
00381 }
00382 
00383 
00384 
00388 template <class T>
00389 struct normalized_difference_fnobj : public std::binary_function<T, T, T> {
00390   T operator()(const T& x, const T& y) const { return 0.5+0.5*(x-y); }
00391 };
00392 
00393 
00400 template <class Matrix,class String,class ScaleType,class MatrixTableType,class ParameterMapType>
00401 Plot::MatrixImage<>*
00402 PlotSpecification<Matrix,String,ScaleType,MatrixTableType,ParameterMapType>::
00403 bitmap_image(const double master_scale, const SubRegion* reference,
00404              const MatrixTable* tempmaps, const SubRegion* overriding_region,
00405              const int border_width, const string overriding_colorspec) const
00406 {
00407   /* Get values for parameters (or use specified defaults if none) */
00408   const Tristate  paper_based = lookup_param(*params,"ppm_paper_based_colors", False);
00409   const double    subplot_hue = lookup_param(*params,"ppm_subplot_hue",        0.0);
00410   const string    colorspec   =(overriding_colorspec!=""? overriding_colorspec :
00411                                 lookup_param(*params,"colorspec",              string("RYW")));
00412   const ColorType bordercolor = lookup_color(*params,"ppm_bg",  AARImage<>::default_border);
00413   const int       border      = (border_width>=0 ? border_width : lookup_param(*params,"ppm_border", 1));
00414   const ParamMap& strength    = params->get_child("Strength");
00415   const ParamMap& color       = params->get_child("Color");
00416   const ParamMap& confidence  = params->get_child("Confidence");
00417   const SubRegion paramregion = lookup_subregion(*params,SubRegion());
00418   const SubRegion subregion   = (overriding_region? *overriding_region : paramregion);
00419   const double    size_scale  = compute_size_scale(master_scale,lookup_param(*params,"size_scale", 1.0),
00420                                                    paramregion,reference);
00421 
00422   Plot::ColorLookupFactory<>::result_type* clu =
00423     Plot::ColorLookupFactory<>(paper_based,subplot_hue)(colorspec);
00424   typedef typename Matrix::value_type T;
00425   typedef mat::MatrixInterface<T> BaseMatrixType; 
00426   const Plot::MatrixImageFactory<BaseMatrixType,T,ScaleType>
00427     factory(paper_based,size_scale,border,subregion,clu,bordercolor);
00428 
00429   
00430   /* Compute value with respect to reference, if any */
00431   typedef normalized_difference_fnobj<T>                               RefFunType;
00432   typedef mat::MatrixInterfaceBinaryAdapter<BaseMatrixType,RefFunType> BinFunAdapter;
00433   typedef mat::MatrixInterfaceAdapter<BaseMatrixType>                  MatAdapter;
00434   const BaseMatrixType*   strengthptr  = map_getptr(strength, tempmaps);
00435   const BaseMatrixType*   refptr       = map_getptr("__StrengthReference", tempmaps,false);
00436   const BinFunAdapter*    strength_ref = 0;
00437   if (strengthptr && refptr) {
00438     strength_ref = new BinFunAdapter(*strengthptr,*refptr,RefFunType());
00439     assert (strength_ref);
00440     strengthptr = strength_ref;
00441   }
00442 
00443   /* Create image */
00444   Plot::MatrixImage<>* img =
00445     factory(strengthptr,
00446             ScaleType( lookup_param(strength,   "value_scale", 1.0),
00447                        lookup_param(strength,   "value_offset",0.0)),
00448             map_getptr(color, tempmaps),
00449             ScaleType( lookup_param(color,      "value_scale", 1.0),
00450                        lookup_param(color,      "value_offset",0.0)),
00451             map_getptr(confidence, tempmaps),
00452             ScaleType( lookup_param(confidence, "value_scale", 1.0),
00453                        lookup_param(confidence, "value_offset",0.0)) );
00454   
00455   delete clu;
00456   delete strength_ref;
00457   
00458   /* Overlay line plots here? */
00459   //if (show_overlay)
00460   
00461   return img;
00462 }
00463 
00464 
00465 
00467 template <class Matrix,class String,class ScaleType,class MatrixTableType,class ParameterMapType>
00468 Plot::AARImage<>*
00469 PlotSpecification<Matrix,String,ScaleType,MatrixTableType,ParameterMapType>::
00470 bitmap_histogram(const double master_scale, const ParamMap& defaults,
00471                  const SubRegion* reference, const MatrixTable* tempmaps,
00472                  const string& name) const
00473 {
00474   const ParamMap& histoparams = params->get_child(name);
00475   
00476   /* The histogram values are determined by the Strength matrix of this plot (optional) */
00477   const Matrix*   str_mat     = map_getptr(params->get_child("Strength"), tempmaps); 
00478   
00479   /* The histogram bins are determined by name, if set, or default to the Color matrix of the plot */
00480   const ParamMap& colorparams = params->get_child("Color");
00481   const string    bin_name    = lookup_param(histoparams,"name",string(),&defaults,&colorparams);
00482   /* Warnings are turned off for this map lookup, to make the global
00483      default be easy to set even if some areas don't have the
00484      corresponding map. */
00485   const Matrix*   bin_mat     = map_getptr(bin_name, tempmaps, false);
00486   const bool      enabled     = lookup_param(histoparams,"ppm_histograms",True);
00487   if (!enabled || !bin_mat) return 0; /* No plot needed */
00488 
00489   const int       num_bins    = lookup_param(histoparams,"num_bins",    24  );
00490   const bool      cyclic      = lookup_param(histoparams,"cyclic",      True);
00491   ScaleType scale(num_bins);
00492 
00493   if (!str_mat) {  /* Substitute constant matrix for strength */
00494     typedef mat::MatrixInterfaceConstant<float>  ConstantMatrix;
00495     ConstantMatrix const_one(1.0,bin_mat->nrows(),bin_mat->ncols());
00496     return histogram_image(master_scale, reference, histoparams,
00497                            Histogram(Histo::matrix_histogram(*bin_mat,const_one,num_bins,scale,cyclic)));
00498   }
00499   else
00500     return histogram_image(master_scale, reference, histoparams,
00501                            Histogram(Histo::matrix_histogram(*bin_mat,*str_mat, num_bins,scale,cyclic)));
00502 }
00503 
00504 
00505 
00506 template <class Matrix,class String,class ScaleType,class MatrixTableType,class ParameterMapType>
00507 Plot::AARImage<>* 
00508 PlotSpecification<Matrix,String,ScaleType,MatrixTableType,ParameterMapType>::
00509 histogram_image(const double master_scale, const SubRegion* reference,
00510                 const ParamMap& histoparams, const Histogram& histo) const
00511 {
00512   const ColorType bordercolor   = lookup_color(histoparams,"ppm_bg", AARImage<>::default_border);
00513   const double    range         = lookup_param(histoparams,"range_end",   0.25);
00514   const bool      vertical      = lookup_param(histoparams,"vertical",    True);
00515   const double    aspect_ratio  = lookup_param(histoparams,"aspect_ratio",0.25);
00516   const int       border        = lookup_param(histoparams,"ppm_border",  1   );
00517   const string    hcolorspec    = lookup_param(histoparams,"histo_colorspec",string(""));
00518   const string    colorspec     =(hcolorspec!=""? hcolorspec :
00519                                   lookup_param(histoparams,"colorspec",   string("Hue")));
00520   const double    subplot_hue   = lookup_param(histoparams,"ppm_subplot_hue", 0.0);
00521   const Tristate  paper_based   = lookup_param(histoparams,"ppm_paper_based_colors", False);
00522   const ColorType histobg       = lookup_color(histoparams,"ppm_line",    ColorType());
00523   const double    psize_scale   = lookup_param(*params,"size_scale", 1.0);
00524   const SubRegion fakesubregion = SubRegion(0,0,
00525                                             histo.num_bins()*(vertical? aspect_ratio : 1.0),
00526                                             histo.num_bins()*(vertical? 1.0 : aspect_ratio));
00527   const double    size_scale    = compute_size_scale(master_scale,psize_scale,fakesubregion,reference);
00528 
00529   OwningPointer<Plot::ColorLookupFactory<>::result_type> clu
00530     (Plot::ColorLookupFactory<>(paper_based,subplot_hue)(colorspec),true);
00531 
00532   return new
00533     Plot::OneDHistogramImage<>(histo,vertical,size_scale,aspect_ratio,
00534                                range,border,*clu,bordercolor,histobg);
00535 }
00536 
00537 
00538 } /* namespace Plot */
00539 #endif /* __PLOT_SPECIFICATION_H__ */

Generated on Mon Jan 20 02:35:45 2003 for RF-LISSOM by doxygen1.3-rc2