Index: trunk/SophyaPI/PIext/pihisto2d.cc
===================================================================
--- trunk/SophyaPI/PIext/pihisto2d.cc	(revision 3075)
+++ trunk/SophyaPI/PIext/pihisto2d.cc	(revision 3145)
@@ -3,4 +3,8 @@
 #include <pisysdep.h>
 #include PIAPP_H
+
+#include <iostream>
+#include <math.h>
+
 #include "sopnamsp.h"
 #include "pihisto2d.h"
@@ -9,4 +13,73 @@
 static int dbg = 0;
 
+
+//------ Implementation classe P2DHistoWrapper
+P2DHistoWrapper::P2DHistoWrapper(int_4 asx, int_4 asy) 
+  :  P2DArrayAdapter(asx, asy) , 
+     mScale(1.) , mOff(0.) , mRetFg(0)
+{
+}
+
+P2DHistoWrapper::~P2DHistoWrapper()
+{
+}
+
+int P2DHistoWrapper::GetStatInfoAsText(vector<string> & /* text */ )
+{
+  return 0;
+}
+
+int P2DHistoWrapper::DecodeOptionString(vector<string> & opt, bool rmdecopt)
+{
+  if(opt.size() < 1) return(0); 
+
+  vector<string> udopt;  // On gardera ici les options non decodees
+  unsigned int k = 0;
+  int ndec = opt.size();
+  for( k=0; k<opt.size(); k++ ) {
+    string & opts = opt[k];
+    if(opts.substr(0,7) == "hs1") {
+      mScale = 1.;  mOff = 0.; 
+    }
+    else if(opts.substr(0,7) == "hscale=") {
+      mScale = atof(opts.substr(7).c_str());
+    }
+    else if(opts.substr(0,8) == "hoffset=") {
+      mOff = atof(opts.substr(8).c_str());
+    }
+    else if(opts.substr(0,8) == "hbincont") {
+      mRetFg = 0;
+    }    
+    else if(opts.substr(0,8) == "hbinerr") {
+      mRetFg = 1;
+    }    
+    else if(opts.substr(0,8) == "hbinent") {
+      mRetFg = 2;
+    }    
+    else {
+      ndec--;
+      // S'il faut supprimer les options decodees
+      if (rmdecopt)  udopt.push_back(opts);
+    }
+  }
+  // S'il faut supprimer les options decodees, on remplace l'argument opt
+  // par le vecteur des options non decodees.
+  if (rmdecopt)  opt = udopt;
+  return(ndec);
+}
+
+int
+P2DHistoWrapper::OptionToString(vector<string> & opt) const
+{
+  char buff[64];
+  sprintf(buff, "hscale=%g", mScale);  opt.push_back(buff);
+  sprintf(buff, "hoffset=%g", mOff);  opt.push_back(buff);
+  if (mRetFg == 2) opt.push_back("hbinent");
+  else if (mRetFg == 1) opt.push_back("hbinerr");
+  else opt.push_back("hbincont");
+
+  return 1;
+}
+
 //++
 // Class	PIHisto2D
@@ -28,11 +101,11 @@
 
 //++
-PIHisto2D::PIHisto2D(Histo2D* histo, bool ad)
+PIHisto2D::PIHisto2D(P2DHistoWrapper* histowp, bool ad)
 //
 //	Createur d'une classe de dessin pour l'histogramme 2D histo.
 //--
-: PIDrawer(), mHisto(histo), mAdDO(ad), mLogScale(10.), mFPoints(0.5)
-{
-// mAdDO : Flag pour suppression automatique de mHisto
+: PIDrawer(), mHistoWp(histowp), mAdDO(ad), mLogScale(10.), mFPoints(0.5)
+{
+// mAdDO : Flag pour suppression automatique de mHistoWp
 // Attention: mFPoints n'est initialise que si on display par nuages de points
 //            mLogScale n'est initialise que si on utilise une echelle log
@@ -43,5 +116,5 @@
 UseFrac();
 SetStats();
- SetStatPosOffset();
+SetStatPosOffset();
 SetName("Histo2DDrw"); 
 // PIHisto2D has specific control tools
@@ -62,5 +135,5 @@
 // ---> parametre d'appel PIBaseWdgGen* wdg=NULL
 DeactivateControlWindow(NULL);
-if(mAdDO && mHisto!=NULL) delete mHisto;
+if(mAdDO && mHistoWp!=NULL) delete mHistoWp;
 }
 
@@ -139,5 +212,5 @@
 
 //++
-void PIHisto2D::UseDyn(float hmin,float hmax)
+void PIHisto2D::UseDyn(float fmin,float fmax)
 //
 //	Gestion de la dynamique a representer:
@@ -151,8 +224,19 @@
 //--
 {
-if(mHisto)
-  if(hmin>=hmax) {hmin = mHisto->VMin(); hmax = mHisto->VMax();}
-if(hmin>=hmax) hmax = hmin+1.;
-mHMin = hmin; mHMax = hmax;
+  if( (mHistoWp) && (mHistoWp->NBinX()>0) && (mHistoWp->NBinY()>0) && (fmin>=fmax) ) {
+    double v,hmin,hmax;
+    hmin = hmax = (*mHistoWp)(0,0);
+    for (int_4 i=0; i<mHistoWp->NBinX(); i++) 
+      for (int_4 j=0; j<mHistoWp->NBinY(); j++) {
+	v = (*mHistoWp)(i, j);
+	if(v<hmin) hmin = v;
+	if(v>hmax) hmax = v;
+      }
+    fmin = hmin;  fmax = hmax;   // $CHECK$ CMV : attention, double vers float !!
+  }
+
+// $CHECK$ CMV : Ne faut-il pas passer les attributs de la classe en double ??
+if(fmin>=fmax) fmax = fmin+1.;
+mHMin = fmin; mHMax = fmax;
 }
 
@@ -189,6 +273,6 @@
       ,(int)mFgCol,(int)mCmap,(int)mRevCmap,mTypScal,mTypDisp,mFPoints);
 printf("                 Dyn=%g,%g Frac=%g,%g LogSc=%g H=%p\n"
-      ,mHMin,mHMax,mFracMin,mFracMax,mLogScale,mHisto);
-if(lp>=1) mHisto->PrintStatus();
+      ,mHMin,mHMax,mFracMin,mFracMax,mLogScale,mHistoWp);
+// if(lp>=1) mHistoWp->PrintStatus();  $CHECK$ CMV : que faut-il faire ? 
 fflush(stdout);
 }
@@ -201,6 +285,6 @@
 //--
 {
- if(!mHisto) return;
- SetLimits(mHisto->XMin(), mHisto->XMax(), mHisto->YMin() , mHisto->YMax());
+ if(!mHistoWp) return;
+ SetLimits(mHistoWp->XMin(), mHistoWp->XMax(), mHistoWp->YMin() , mHistoWp->YMax());
 }
 
@@ -259,9 +343,9 @@
 if (axesFlags != kAxesNone) DrawAxes(g);
 
-if(!mHisto) return;
-if(mHisto->NBinX()<=0 || mHisto->NBinY()<=0) return;
+if(!mHistoWp) return;
+if(mHistoWp->NBinX()<=0 || mHistoWp->NBinY()<=0) return;
 
 // Caracteristiques histogramme
-double dx = mHisto->WBinX(),dy = mHisto->WBinY();
+double dx = mHistoWp->WBinX(),dy = mHistoWp->WBinY();
 double p1dx,p1dy;
 g->DGrC2UC(1.,1.,p1dx,p1dy);
@@ -309,12 +393,12 @@
 
 // Plot de l'histogramme
-for(int i=0; i<mHisto->NBinX(); i++)
-  for(int j=0; j<mHisto->NBinY(); j++) {
+for(int i=0; i<mHistoWp->NBinX(); i++)
+  for(int j=0; j<mHistoWp->NBinY(); j++) {
 
   r_8 left0,bottom0;
-  mHisto->BinLowEdge(i,j,left0,bottom0);
+  mHistoWp->BinLowEdge(i,j,left0,bottom0);
 
   // Gestion de la dynamique a dessiner
-  float frac = ((*mHisto)(i,j)-HMin())/(HMax()-HMin());
+  float frac = ((*mHistoWp)(i,j)-HMin())/(HMax()-HMin());
   if(frac<0.) continue;
   if(mTypScal==1) {              // echelle log10
@@ -385,14 +469,17 @@
 //--
 {
-Histo2D* h = Histogram();
+P2DHistoWrapper* h = HistoWrapper();
 if(h == NULL) return;
 
-int i,j;
-h->FindBin(x,y,i,j);
+int_4 i,j;
+i = floor((x-h->XMin())/h->WBinX()); 
+j = floor((y-h->YMin())/h->WBinY());
+
 if(i>=0 && i<h->NBinX() && j>=0 && j<h->NBinY()) {
   char str[64];
   if(fgdiff) {
     int i0,j0;
-    h->FindBin(x0,y0,i0,j0);
+    i0 = floor((x0-h->XMin())/h->WBinX()); 
+    j0 = floor((y0-h->YMin())/h->WBinY());
     if(i0>=0 && i0<h->NBinX() && j0>=0 && j0<h->NBinY()) {
       sprintf(str," DV=%g",(*h)(i,j)-(*h)(i0,j0));
@@ -417,5 +504,5 @@
 //--
 {
-  if (!mHisto) return;
+  if (!mHistoWp) return;
   if (GetGraphicAtt().GetLineAtt() == PI_NotDefLineAtt)  g->SelLine(PI_ThinLine);
   g->SelFontSz((YMax() - YMin())/30);
@@ -424,10 +511,19 @@
   PIGrCoord a, d;
   double cH = (double)g->GetFontHeight(a,d);
-  double cellHeight = 1.2 * cH;
-
-  // Les labels et leurs longueurs -> largeur de la cellule
-  char label[64];
-  sprintf(label,"N= %-g", mHisto->NData());
-  double cellWidth =  1.1 * (double)g->CalcStringWidth(label);
+  vector<string> lines;
+  int nlig = mHistoWp->GetStatInfoAsText(lines);
+  if (nlig < 1) return;
+
+  double cellHeight = nlig*1.2 * cH;
+
+  int idxll = 0;
+  
+  int kl;
+  // on recherche la ligne la plus longue
+  for(kl=1; kl<nlig; kl++)
+    if ( lines[kl].length() > lines[idxll].length() )  idxll = kl;
+
+  double cellWidth =  1.1 * (double)g->CalcStringWidth(lines[idxll].c_str());
+
 
   double ofpx = spoX*(XMax()-XMin());
@@ -446,11 +542,18 @@
   cw = (g->isAxeXDirRtoL()) ? -0.05*cellWidth : -0.95*cellWidth;
   xu = g->DeltaUCX(XMax(),cw);
-  cw = (g->isAxeYDirUpDown()) ? -0.1*cH : -1.1*cH;
+
+  cw = (g->isAxeYDirUpDown()) ? -0.15*cH : -1.15*cH;
   yu = g->DeltaUCY(YMax(),cw);
   xu += ofpx;  yu += ofpy;
-  g->DrawString(xu,yu,label);
+
+  for(kl=0; kl<nlig; kl++) {
+    g->DrawString(xu, yu, lines[kl].c_str() );
+    cw +=  -1.15*cH;
+    yu = g->DeltaUCY(YMax(),cw);  yu += ofpy;
+  }
+
 
   //  printf("H[%d,%d] Dynamique: [%g,%g] Frac [%g,%g]\n"
-  //        ,mHisto->NBinX(),mHisto->NBinY(),HMin(),HMax(),FMin(),FMax());
+  //        ,mHistoWp->NBinX(),mHistoWp->NBinY(),HMin(),HMax(),FMin(),FMax());
 }
 
@@ -489,5 +592,5 @@
 //--
 {
-double dx = mHisto->WBinX(),dy = mHisto->WBinY();
+double dx = mHistoWp->WBinX(),dy = mHistoWp->WBinY();
 double dxg,dyg;
 g->DUC2GrC(dx,dy,dxg,dyg);
@@ -573,8 +676,14 @@
   if (rmdecopt)  opt = udopt;
 
+  // Decodage des options par le histo-wrapper
+  int ndec2 = 0;
+  if ( ( optsz1-ndec1-ndec > 0) && (mHistoWp) ) {
+    ndec2 = mHistoWp->DecodeOptionString(opt, rmdecopt);
+  }
+
   // Liste des options si demande
   if(listopt) Print();
 
-  return(ndec+ndec1);
+  return(ndec+ndec1+ndec2);
 }
 
@@ -607,4 +716,6 @@
  if(mRevCmap) opt.push_back("revcmap");
 
+ // Les options du Histo2DWrapper :
+ mHistoWp->OptionToString(opt);
  return 1;
 }
@@ -630,8 +741,15 @@
 info += "- h2scale=lin/log[,logscale]: choose linear or logarithmic scale\n";
 info += "- h2dyn=[hmin][,hmax]: choose histogramme range for display\n";
-info += "- use general key to define color table (ex: grey32,midas_heat,...)\n";
+info += "- use graphic att. to define color table (ex: grey32,midas_heat,...)\n";
 info += "            (see general graphicatt description)\n";
-info += "- use key \"revcmap\" to reverse color table\n";
+info += "- use \"revcmap\" to reverse color table\n";
 info += "- h2frac=[fmin][,fmax]: choose sub-range display [0,1]\n";
+info += " ---- HistoWrapper options : \n" ;
+info += " hbincont: select bin content as Y value for display (default) \n";
+info += " hbinerr: select bin error as Y value for display \n";
+info += " hbinent: select bin entries as Y value for display \n";
+info += " hscale=value : multiplicative factor for Y value \n" ;
+info += " hoffset=value : additive coefficient for Y value \n" ;
+info += " hs1: set hscale=1 hoffset=0  (default) \n" ;
 // On recupere ensuite la chaine info de la classe de base
 PIDrawer::GetOptionsHelpInfo(info);
