Index: trunk/SophyaPI/PIext/piafitting.cc
===================================================================
--- trunk/SophyaPI/PIext/piafitting.cc	(revision 1200)
+++ trunk/SophyaPI/PIext/piafitting.cc	(revision 1207)
@@ -35,5 +35,15 @@
 #include "piafitting.h"
 #include "nobjmgr.h"
+#include "anydataobj.h"
 #include "pistdimgapp.h"
+
+#include "nomhistadapter.h"
+#include "nomgfdadapter.h"
+#include "nomimagadapter.h"
+#ifdef SANS_EVOLPLANCK
+#include "nommatvecadapter.h"
+#else
+#include "nomtmatvecadapter.h"
+#endif
 
 ////////////////////////////////////////////////////////////////////
@@ -56,9 +66,7 @@
   PICheckBox** ckb; int nckb;
   PIOptMenu**  pom; int npom;
-  bool ReFillGData;
-  bool ReDecodeFunc;
-  double ErrValue;
+  bool ReFillGData,ReDecodeFunc;
   int saveI1,saveI2, saveJ1, saveJ2;
-  double saveErrValue,saveXC,saveYC;
+  double saveErrScale,saveErrMin,saveXC,saveYC;
 };
 
@@ -72,5 +80,5 @@
 //| --------------- Fit Lineaire a 1 et 2 dimensions ---------------
 //| Syntaxe:
-//| fitlin nom pnn [o:.aa,bb,cc, o;dd,ee,ff o:gg,hh,jj,kk etc...]
+//| fitlin nom pnn [o:.aa,bb,cc, o:dd,ee,ff o:gg,hh,jj,kk etc...]
 //| avec:
 //| nom  : cf commentaire ordre ''fit''
@@ -84,5 +92,5 @@
 //| fitw nom func
 //|     [p:p1,p2,...,pn s:s1,s2,...,sn m:m1,m2,...,mn M:M1,mM2,...,Mn f:f1,...,fn]
-//|     [o:.aa,bb,cc, o;dd,ee,ff o:gg,hh,jj,kk etc...]
+//|     [o:.aa,bb,cc, o:dd,ee,ff o:gg,hh,jj,kk etc...]
 //| cf commentaire ordre ''fit''
 //|
@@ -92,5 +100,5 @@
 //| fit nom func
 //|     [p:p1,p2,...,pn s:s1,s2,...,sn m:m1,m2,...,mn M:M1,mM2,...,Mn f:f1,...,fn]
-//|     [o:.aa,bb,cc, o;dd,ee,ff o:gg,hh,jj,kk etc...]
+//|     [o:.aa,bb,cc, o:dd,ee,ff o:gg,hh,jj,kk etc...]
 //|----- OBJET -----
 //| nom  : nom de l'objet qui peut etre:
@@ -139,16 +147,20 @@
 //|      Ii1/i2 : numeros des bins X de l'histos utilises pour le fit [i1,i2]
 //|2D    Jj1/j2 : numeros des bins Y de l'histos utilises pour le fit [j1,j2]
-//|    - L'erreur est celle associee a l'objet (si elle existe),
-//|      elle est mise a 1 sinon, sauf si E... ou e... est precise:
-//|      Eaa.b : si |val|>=1 erreur = aa.b*sqrt(|val|)
-//|              si |val|<1  erreur = aa.b
-//|              si aa.b <=0 alors aa.b=1.0
-//|              E seul est equivalent a E1.0
-//|      eaa.b : erreur = aa.b
-//|              si aa.b <=0 alors aa.b=1.0
-//|              e seul est equivalent a e1.0
+//|    - Traitement des erreurs :
+//|      Par defaut, l'erreur est celle associee a l'objet (si elle existe),
+//|        elle est mise a 1 sinon.
+//|      haa.b/cc.d : erreur = aa.bb*(erreur associee a l'objet cf ci-dessus)
+//|      Haa.b/cc.d : erreur = aa.b*|val|
+//|      eaa.b/cc.d : erreur = aa.b
+//|      Eaa.b/cc.d : erreur = aa.b*sqrt(|val|)
+//|           aa.b<0 (ou non precise) est equivalent aa.b=1.0
+//|           cc.d non precise est equivalent a cc.d=0
+//|           si cc.d>=0  si erreur>0 erreur = max(erreur,cc.d)
+//|                       si erreur<=0 alors erreur
+//|           si cc.d<0   si erreur>0 erreur = max(erreur,|cc.d|)
+//|                       si erreur<=0 alors erreur=|cc.d|
 //|      xaa.b : demande de centrage: on fit x-aa.b au lieu de x)
 //|      x : demande de centrage: on fit x-xc au lieu de x
-//|          avec xc=abscisse du milieu de l'histogramme
+//|          avec xc=abscisse du ''milieu logique'' de l'objet.
 //|          Actif pour  exp+poly 1D, poly 1D
 //|          Pour gauss+poly 1D, xc est le centre de la gaussienne.
@@ -183,10 +195,9 @@
 PIAFitter::PIAFitter(PIACmd *piac, PIStdImgApp* app)
 : mApp(app), FWindFit(NULL)
-, mNObj(""), mObj(NULL), mGData(NULL)
-, mNPar(0), mNVar(0),  mNBinX(0), mNBinY(0), mNData(0)
+, mNObj(""), mAdObj(NULL), mGData(NULL), delmGData(false)
+, mNPar(0), mNVar(0), mNData(0)
 , mPar(1), mStep(1), mMin(1), mMax(1), mFix(1)
 , mParSave(1), mStepSave(1), mMinSave(1), mMaxSave(1), mFixSave(1)
-, mFit(NULL),ApplyXYcentering(false)
-, mV(NULL), mH(NULL), mM(NULL), mH2(NULL), mIm(NULL), mG(NULL)
+, mFit(NULL)
 , mFunction(NULL), mFName(""), mFunc(NULL)
 , mDlUFunc(NULL), mNameFitFunc(""), mFitFunc(NULL), mFitFuncDer(NULL)
@@ -207,5 +218,5 @@
 usage+="\n| --------------- Fit Lineaire a 1 et 2 dimensions ---------------    ";
 usage+="\n| Syntaxe:    ";
-usage+="\n| fitlin nom pnn [o:.aa,bb,cc, o;dd,ee,ff o:gg,hh,jj,kk etc...]    ";
+usage+="\n| fitlin nom pnn [o:.aa,bb,cc, o:dd,ee,ff o:gg,hh,jj,kk etc...]    ";
 usage+="\n| avec:    ";
 usage+="\n| nom  : cf commentaire ordre ''fit''    ";
@@ -219,5 +230,5 @@
 usage+="\n| fitw nom func    ";
 usage+="\n|     [p:p1,p2,...,pn s:s1,s2,...,sn m:m1,m2,...,mn M:M1,mM2,...,Mn f:f1,...,fn]    ";
-usage+="\n|     [o:.aa,bb,cc, o;dd,ee,ff o:gg,hh,jj,kk etc...]    ";
+usage+="\n|     [o:.aa,bb,cc, o:dd,ee,ff o:gg,hh,jj,kk etc...]    ";
 usage+="\n| cf commentaire ordre ''fit''    ";
 usage+="\n|    ";
@@ -227,5 +238,5 @@
 usage+="\n| fit nom func    ";
 usage+="\n|     [p:p1,p2,...,pn s:s1,s2,...,sn m:m1,m2,...,mn M:M1,mM2,...,Mn f:f1,...,fn]    ";
-usage+="\n|     [o:.aa,bb,cc, o;dd,ee,ff o:gg,hh,jj,kk etc...]    ";
+usage+="\n|     [o:.aa,bb,cc, o:dd,ee,ff o:gg,hh,jj,kk etc...]    ";
 usage+="\n|----- OBJET -----    ";
 usage+="\n| nom  : nom de l'objet qui peut etre:    ";
@@ -274,16 +285,20 @@
 usage+="\n|      Ii1/i2 : numeros des bins X de l'histos utilises pour le fit [i1,i2]    ";
 usage+="\n|2D    Jj1/j2 : numeros des bins Y de l'histos utilises pour le fit [j1,j2]    ";
-usage+="\n|    - L'erreur est celle associee a l'objet (si elle existe),    ";
-usage+="\n|      elle est mise a 1 sinon, sauf si E... ou e... est precise:    ";
-usage+="\n|      Eaa.b : si |val|>=1 erreur = aa.b*sqrt(|val|)    ";
-usage+="\n|              si |val|<1  erreur = aa.b    ";
-usage+="\n|              si aa.b <=0 alors aa.b=1.0    ";
-usage+="\n|              E seul est equivalent a E1.0    ";
-usage+="\n|      eaa.b : erreur = aa.b    ";
-usage+="\n|              si aa.b <=0 alors aa.b=1.0    ";
-usage+="\n|              e seul est equivalent a e1.0    ";
+usage+="\n|    - Traitement des erreurs :    ";
+usage+="\n|      Par defaut, l'erreur est celle associee a l'objet (si elle existe),    ";
+usage+="\n|        elle est mise a 1 sinon.    ";
+usage+="\n|      haa.b/cc.d : erreur = aa.bb*(erreur associee a l'objet cf ci-dessus)    ";
+usage+="\n|      Haa.b/cc.d : erreur = aa.b*|val|    ";
+usage+="\n|      eaa.b/cc.d : erreur = aa.b    ";
+usage+="\n|      Eaa.b/cc.d : erreur = aa.b*sqrt(|val|)    ";
+usage+="\n|           aa.b<0 (ou non precise) est equivalent aa.b=1.0    ";
+usage+="\n|           cc.d non precise est equivalent a cc.d=0    ";
+usage+="\n|           si cc.d>=0  si erreur>0 erreur = max(erreur,cc.d)    ";
+usage+="\n|                       si erreur<=0 alors erreur    ";
+usage+="\n|           si cc.d<0   si erreur>0 erreur = max(erreur,|cc.d|)    ";
+usage+="\n|                       si erreur<=0 alors erreur=|cc.d|    ";
 usage+="\n|      xaa.b : demande de centrage: on fit x-aa.b au lieu de x)    ";
 usage+="\n|      x : demande de centrage: on fit x-xc au lieu de x    ";
-usage+="\n|          avec xc=abscisse du milieu de l'histogramme    ";
+usage+="\n|          avec xc=abscisse du ''milieu logique'' de l'objet.    ";
 usage+="\n|          Actif pour  exp+poly 1D, poly 1D    ";
 usage+="\n|          Pour gauss+poly 1D, xc est le centre de la gaussienne.    ";
@@ -352,18 +367,10 @@
 PIAFitter::~PIAFitter()
 {
-if(mFit != NULL)      {delete mFit;      mFit=NULL;}
-if(mFunction != NULL) {delete mFunction; mFunction=NULL;}
-if(mFunc != NULL)     {delete mFunc;     mFunc=NULL;}
-if(mGData != NULL)    {delete mGData;    mGData=NULL;}
-if(FWindFit != NULL)  {delete FWindFit;  FWindFit=NULL;}
-if (mDlUFunc != NULL) {delete mDlUFunc;  mDlUFunc=NULL;}
-}
-
-/* --Methode-- */
-void PIAFitter::ResetDPointer(void)
-// Reset des pointeurs sur les donnees
-{
-mNObj = ""; mObj=NULL;
-mV=NULL; mH=NULL; mM=NULL; mH2=NULL; mIm=NULL; mG=NULL;
+if(delmGData && mGData != NULL) {delete mGData;    mGData=NULL; delmGData=false;}
+if(mFit != NULL)                {delete mFit;      mFit=NULL;}
+if(mFunction != NULL)           {delete mFunction; mFunction=NULL;}
+if(mFunc != NULL)               {delete mFunc;     mFunc=NULL;}
+if(FWindFit != NULL)            {delete FWindFit;  FWindFit=NULL;}
+if(mDlUFunc != NULL)            {delete mDlUFunc;  mDlUFunc=NULL;}
 }
 
@@ -373,11 +380,19 @@
 {
 mOpt.okres = mOpt.okfun = false;
+
 mOpt.polcx = mOpt.polcy = 0;
 mOpt.xc = mOpt.yc = 0.;
+
 mOpt.stc2 = 1.e-3;
 mOpt.nstep = 100;
-mOpt.err_e = mOpt.err_E = -1.;
+
+mOpt.err_type = GeneralFitData::DefaultError;
+mOpt.err_scale = 1.; mOpt.err_min = 0.;
+
 mOpt.lp = 1; mOpt.lpg = 0;
-mOpt.i1 = mOpt.j1 = mOpt.i2 = mOpt.j2 = -1;
+
+mOpt.i1 = mOpt.j1 = 0;
+mOpt.i2 = mOpt.j2 = -1;
+
 mOpt.fromlastfit = false;
 mOpt.autoinifit = false;
@@ -417,15 +432,27 @@
   }
 }
-if(strstr(opt.c_str(),",E")) { // Erreurs imposees a "sqrt(val)" ou "aa.b*sqrt(val)"
+if(strstr(opt.c_str(),",h")) {
+  mOpt.err_type = GeneralFitData::DefaultError;
+  p = opt.find(",h"); q = opt.find_first_of(',',p+1);
+  dum = opt.substr(p,q-p);
+  if(dum.length()>2) sscanf(dum.c_str(),",h%lf/%lf",&mOpt.err_scale,&mOpt.err_min);
+}
+if(strstr(opt.c_str(),",H")) {
+  mOpt.err_type = GeneralFitData::ProporError;
+  p = opt.find(",H"); q = opt.find_first_of(',',p+1);
+  dum = opt.substr(p,q-p);
+  if(dum.length()>2) sscanf(dum.c_str(),",H%lf/%lf",&mOpt.err_scale,&mOpt.err_min);
+}
+if(strstr(opt.c_str(),",e")) {
+  mOpt.err_type = GeneralFitData::ConstantError;
+  p = opt.find(",e"); q = opt.find_first_of(',',p+1);
+  dum = opt.substr(p,q-p);
+  if(dum.length()>2) sscanf(dum.c_str(),",e%lf/%lf",&mOpt.err_scale,&mOpt.err_min);
+}
+if(strstr(opt.c_str(),",E")) {
+  mOpt.err_type = GeneralFitData::SqrtError;
   p = opt.find(",E"); q = opt.find_first_of(',',p+1);
   dum = opt.substr(p,q-p);
-  if(dum.length()>2) sscanf(dum.c_str(),",E%lf",&mOpt.err_E);
-  if(mOpt.err_E<=0.) mOpt.err_E = 1.;  //mOpt.err_e=-1.;
-}
-if(strstr(opt.c_str(),",e")) { // Erreurs imposees a "1" ou "aa.b"
-  p = opt.find(",e"); q = opt.find_first_of(',',p+1);
-  dum = opt.substr(p,q-p);
-  if(dum.length()>2) sscanf(dum.c_str(),",e%lf",&mOpt.err_e);
-  if(mOpt.err_e<=0.) mOpt.err_e = 1.;  //mOpt.err_E=-1.;
+  if(dum.length()>2) sscanf(dum.c_str(),",E%lf/%lf",&mOpt.err_scale,&mOpt.err_min);
 }
 if(strstr(opt.c_str(),",X")) { // Valeur du StopChi2
@@ -467,4 +494,5 @@
 // Decodage de l'objet a fitter
 {
+mNObj = "";
 NamedObjMgr omg;
 AnyDataObj* mobj = omg.GetObj(obj);
@@ -473,61 +501,5 @@
    return;}
 
-// Reset
-ResetDPointer();
-mNVar = mNBinX = mNBinY = mNData = 0;
-
-mObj = mobj; mNObj = obj;
-string ctyp = typeid(*mObj).name();
-
-// 1D
-if (typeid(*mObj) == typeid(Vector)) {
-  mNVar = 1;
-  mV = (Vector*) mObj; mNBinX = mV->NElts(); mNBinY = 1;
-  }
-else if ( (typeid(*mObj) == typeid(HProf)) || (typeid(*mObj) == typeid(Histo)) ) {
-  mNVar = 1;
-  mH = (Histo*)  mObj; mNBinX = mH->NBins(); mNBinY = 1;
-  }
-// 2D
-else if (typeid(*mObj) == typeid(Matrix)) {
-  mNVar = 2;
-  mM = (Matrix*) mObj; mNBinX = mM->NCol(); mNBinY =mM->NRows();
-  }
-else if (typeid(*mObj) == typeid(Histo2D)) {
-  mNVar = 2;
-  mH2 = (Histo2D*) mObj; mNBinX = mH2->NBinX(); mNBinY = mH2->NBinY();
-  }
-else if (typeid(*mObj) == typeid(GeneralFitData)) {
-  mG = (GeneralFitData*) mObj; mNBinX = mG->NData(); mNBinY = 1;
-  if(     mG->NVar()==1) mNVar = 1;
-  else if(mG->NVar()==2) mNVar = 2;
-  else
-     {cout<<"PIAFitter::DecodeObject Error: \n"
-         <<" GeneralFitData ne peut avoir que 1 ou 2 variables d'abscisse: "
-         <<((GeneralFitData*) mObj)->NVar()<<endl;
-     return;}
-  }
-#ifdef SANS_EVOLPLANCK
-else if (dynamic_cast<RzImage*>(mObj)) {
-  mNVar = 2;
-  mIm = (RzImage*) mObj; mNBinX = mIm->XSize(); mNBinY = mIm->YSize();
-  }
-#else
-//CMV_A_FAIRE else if (dynamic_cast<RzImage*>(mObj)) {
-//CMV_A_FAIRE   mNVar = 2;
-//CMV_A_FAIRE   mIm = (RzImage*) mObj; mNBinX = mIm->XSize(); mNBinY = mIm->YSize();
-//CMV_A_FAIRE   }
-#endif
-else {
-  cout<<"PIAFitter::DecodeObject Error , Objet n'est pas un "
-      <<"Histo1D/HProf/Vector/Histo2D/Image/Matrix/GeneralFitData "<<ctyp<<endl;
-  return;
-  }
-
-mNData = mNBinX*mNBinY;
-if(mNData<=0) {
-  cout<<"L'objet a "<<mNBinX<<","<<mNBinY<<" bins ("<<mNData<<")"<<endl;
-  return;
-}
+mNObj = obj;
 
 return;
@@ -541,28 +513,6 @@
 if(mOpt.lp<0) mOpt.lp = 0;
 if(mOpt.lpg<0) mOpt.lpg = 0;
-mOpt.i1 = (mOpt.i1<0||mOpt.i1>=mNBinX)? 0: mOpt.i1;
-mOpt.i2 = (mOpt.i2<0||mOpt.i2>=mNBinX||mOpt.i2<=mOpt.i1)? mNBinX-1: mOpt.i2;
-if(mNVar>=2) {
-  mOpt.j1 = (mOpt.j1<0||mOpt.j1>=mNBinY)? 0: mOpt.j1;
-  mOpt.j2 = (mOpt.j2<0||mOpt.j2>=mNBinY||mOpt.j2<=mOpt.j1)? mNBinY-1: mOpt.j2;
-} else mOpt.j2 = mOpt.j1 = 0;
-if(mOpt.polcx==2) {
-  if(mV||mM)   mOpt.xc = (mOpt.i2-mOpt.i1+1)/2.;
-  else if(mH)  mOpt.xc = (mH->XMin()+mH->XMax())/2.;
-  else if(mH2) mOpt.xc = (mH2->XMin()+mH2->XMax())/2.;
-  else if(mG)  {double mini,maxi; mG->GetMnMx(2,mini,maxi); mOpt.xc=(mini+maxi)/2.;}
-  else if(mIm) {mOpt.xc = mIm->XOrg() + mIm->XPixSize()*(mOpt.i2-mOpt.i1+1)/2.;}
-}
-if(mOpt.polcy==2 && mNVar>=2) {
-  if(mM)  mOpt.yc = (mOpt.j2-mOpt.j1+1)/2.;
-  if(mH2) mOpt.yc = (mH2->YMin()+mH2->YMax())/2.;
-  if(mG)  {double mini,maxi; mG->GetMnMx(12,mini,maxi); mOpt.yc=(mini+maxi)/2.;}
-  if(mIm) {mOpt.yc = mIm->YOrg() + mIm->YPixSize()*(mOpt.j2-mOpt.j1+1)/2.;}
-}
-if(mOpt.err_e>0.) mOpt.err_E=-1.;
-if(mOpt.err_E>0.) mOpt.err_e =-1.;
 if(mOpt.stc2<=0.) mOpt.stc2 = 1.e-3;
 if(mOpt.nstep<2) mOpt.nstep = 100;
-
 return;
 }
@@ -572,8 +522,8 @@
 // Print des options
 {
-cout<<"Fit["<<mNBinX<<","<<mNBinY<<"] ("<<mNData<<") dim="<<mNVar<<":"
+cout<<"Fit("<<mNData<<") dim="<<mNVar<<":"
     <<" Int=["<<mOpt.i1<<","<<mOpt.i2<<"],["<<mOpt.j1<<","<<mOpt.j2<<"]"<<endl
     <<" Cent="<<mOpt.polcx<<","<<mOpt.polcy<<","<<mOpt.xc<<"+x"<<","<<mOpt.yc<<"+y"
-    <<" TypE="<<mOpt.err_e<<","<<mOpt.err_E
+    <<" TypE="<<mOpt.err_type<<","<<mOpt.err_scale<<","<<mOpt.err_min
     <<" StpX2="<<mOpt.stc2<<" Nstep="<<mOpt.nstep<<endl
     <<" Init.LFit="<<mOpt.fromlastfit<<" AutoIni.Fit="<<mOpt.autoinifit
@@ -587,49 +537,39 @@
 // ATTENTION: cette methode a besoin que les options soient decodees et checkees
 {
-if(mNData<=0) return;
-if(mGData!=NULL) {delete mGData; mGData=NULL;}
-mGData = new GeneralFitData(mNVar,mNData,0);
-
-for(int i=mOpt.i1;i<=mOpt.i2;i++) for(int j=mOpt.j1;j<=mOpt.j2;j++) {
-  double x,y=0.,f,e;
-
-  if(mV)
-    {x= (double) i; f=(*mV)(i); e=1.;}
-  else if(mH)
-    {x=mH->BinCenter(i); f=(*mH)(i); e=(mH->HasErrors())?mH->Error(i):1.;}
-  else if(mM)
-    {x=(double) i; y=(double) j; f=(*mM)(j,i); e=1.;}
-  else if(mH2)
-    {r_8 xf,yf; mH2->BinCenter(i,j,xf,yf); x=xf; y=yf;
-     f=(*mH2)(i,j); e=(mH2->HasErrors())?mH2->Error(i,j):1.;}
-  else if(mIm)
-    {x=mIm->XOrg()+(i+0.5)*mIm->XPixSize(); y=mIm->YOrg()+(j+0.5)*mIm->YPixSize();
-     f=mIm->DValue(i,j); e=1.;}
-  else if(mG&&mNVar==1) {x= mG->X(i); f=mG->Val(i); e=mG->EVal(i);}
-  else if(mG&&mNVar==2) {x= mG->X(i); y=mG->Y(i); f=mG->Val(i); e=mG->EVal(i);}
-  else x=y=f=e=0.;
-
-  // Gestion des erreurs a utiliser
-  if(mOpt.err_e>0.) e=mOpt.err_e;
-  else if(mOpt.err_E>0.) {e=(f<-1.||f>1.)?mOpt.err_E*sqrt(fabs(f)):mOpt.err_E;}
-
-  // Remplissage de generalfitdata
-  if(ApplyXYcentering) { // pour fitlin
-    if(mOpt.polcx>0) x-=mOpt.xc;
-    if(mNVar>=2 && mOpt.polcy>0) y-=mOpt.yc;
-  }
-  if(mNVar==1)      mGData->AddData1(x,f,e);
-  else if(mNVar==2) mGData->AddData2(x,y,f,e);
-}
-
-if(mGData->NData()<=0) {
-  cout<<"Pas de donnees dans GeneralFitData: "<<mGData->NData()<<endl;
+if(delmGData && mGData!=NULL) {delete mGData; mGData=NULL; delmGData=false;}
+mNVar = mNData = 0;
+
+NamedObjMgr omg;
+mAdObj = omg.GetObjAdapter(mNObj); // Ne pas deleter
+if(mAdObj == NULL) {
+  cout<<"PIAFitter::DecodeObject Error , ObjAdapter==NULL for "<<mNObj<<endl;
   return;
 }
-
+mGData = mAdObj->GetGeneralFitData(delmGData
+                 ,mOpt.err_type,mOpt.err_scale,mOpt.err_min
+                 ,mOpt.i1,mOpt.i2,mOpt.j1,mOpt.j2);
+if(mGData == NULL) {
+  cout<<"PIAFitter::DecodeObject Error , No adaptor for "<<mNObj<<endl;
+  return;
+}
+mNData = mGData->NData();
+if(mNData<=0) {
+  cout<<"No data in GeneralFitData: "<<mNData<<endl;
+  return;
+}
+mNVar = mGData->NVar();
+if(mNVar<=0 || mNVar>2) {
+  cout<<"Fit only support 1 and 2D :  NVar = "<<mNVar<<endl;
+  return;
+}
+
+// Gestion du centrage automatique si demande
+GetCentering();
+
+// Prints
 if(mOpt.lp>2) {
   mGData->PrintStatus();
   mGData->PrintData(0);
-  mGData->PrintData(mGData->NData()-1);
+  mGData->PrintData(mNData-1);
   double mini,maxi;
   mGData->GetMnMx(2,mini,maxi);
@@ -648,8 +588,25 @@
 
 /* --Methode-- */
+void PIAFitter::GetCentering(void)
+// Calcul le centrage automatique
+{
+if(!mGData) return;
+if(mOpt.polcx==2) {
+  double mini,maxi;
+  mGData->GetMnMx(2,mini,maxi);
+  mOpt.xc=(mini+maxi)/2.;
+}
+if(mOpt.polcy==2 && mNVar>=2) {
+  double mini,maxi;
+  mGData->GetMnMx(12,mini,maxi);
+  mOpt.yc=(mini+maxi)/2.;
+}
+}
+
+/* --Methode-- */
 void PIAFitter::DecodeFunction(string func)
 // Fonction a fitter
 // ATTENTION: cette methode a besoin que les donnees soient lues
-//                                    (pour mopt.xc,yc et mNVar)
+//                                    (pour mOpt.xc,yc et mNVar)
 {
 if(func.length()<=0)
@@ -911,104 +868,21 @@
 // Mise a disposition des resultats (fonction fitee et residus)
 {
-if(mFit && (mOpt.okres||mOpt.okfun)) {
-  NamedObjMgr omg;
-  string nomres = mNObj + "_res";
-  string nomfun = mNObj + "_fun";
-//####################
-#ifdef SANS_EVOLPLANCK
-//####################
-  if(mV) {
-    if(mOpt.okres) {Vector* ob = mV->FitResidus(*mFit);  if(ob) omg.AddObj(ob,nomres);}
-    if(mOpt.okfun) {Vector* ob = mV->FitFunction(*mFit); if(ob) omg.AddObj(ob,nomfun);}
-  } else if(mH) {
-    if(mOpt.okres) {Histo* ob = mH->FitResidus(*mFit);  if(ob) omg.AddObj(ob,nomres);}
-    if(mOpt.okfun) {Histo* ob = mH->FitFunction(*mFit); if(ob) omg.AddObj(ob,nomfun);}
-  } else if(mM) {
-    if(mOpt.okres) {Matrix* ob = mM->FitResidus(*mFit);  if(ob) omg.AddObj(ob,nomres);}
-    if(mOpt.okfun) {Matrix* ob = mM->FitFunction(*mFit); if(ob) omg.AddObj(ob,nomfun);}
-  } else if(mH2) {
-    if(mOpt.okres)
-      {Histo2D* ob = mH2->FitResidus(*mFit);  if(ob) omg.AddObj(ob,nomres);}
-    if(mOpt.okfun)
-      {Histo2D* ob = mH2->FitFunction(*mFit); if(ob) omg.AddObj(ob,nomfun);}
-  } else if(mIm) {
-    if(mOpt.okres) {
-      RzImage* ob = mIm->FitResidus(*mFit);  
-      if(ob) {ImageR4* rob = new ImageR4(*ob); omg.AddObj(rob,nomres); delete ob;}
-    }
-    if(mOpt.okfun) {
-      RzImage* ob = mIm->FitFunction(*mFit);
-      if(ob) {ImageR4* rob = new ImageR4(*ob); omg.AddObj(rob,nomfun); delete ob;}
-    }
-  } else if(mG) {
-    if(mOpt.okres)
-      {GeneralFitData* ob = mG->FitResidus(*mFit);  if(ob) omg.AddObj(ob,nomres);}
-    if(mOpt.okfun)
-      {GeneralFitData* ob = mG->FitFunction(*mFit); if(ob) omg.AddObj(ob,nomfun);}
-  }
-//####################
-#else
-//####################
-  if(mV) {
-    if(mOpt.okres) {
-      Vector* ob = new Vector(ObjectFitter::FitResidus(*mV, *mFit),true);  
-      if(ob) omg.AddObj(ob,nomres);
-    }
-    if(mOpt.okfun) {
-      Vector* ob = new Vector(ObjectFitter::FitFunction(*mV, *mFit),true); 
-      if(ob) omg.AddObj(ob,nomfun);
-    }
-  } else if(mH) {
-    if(mOpt.okres) {
-      Histo* ob = new Histo(ObjectFitter::FitResidus(*mH, *mFit));
-      if(ob) omg.AddObj(ob,nomres);
-    }
-    if(mOpt.okfun) {
-      Histo* ob = new Histo(ObjectFitter::FitFunction(*mH, *mFit));
-      if(ob) omg.AddObj(ob,nomfun);
-    }
-  } else if(mM) {
-    if(mOpt.okres) {
-      Matrix* ob = new Matrix(ObjectFitter::FitResidus(*mM, *mFit), true);  
-      if(ob) omg.AddObj(ob,nomres);
-    }
-    if(mOpt.okfun) {
-      Matrix* ob = new Matrix(ObjectFitter::FitFunction(*mM, *mFit), true); 
-      if(ob) omg.AddObj(ob,nomfun);
-    }
-  } else if(mH2) {
-    if(mOpt.okres) {
-      Histo2D* ob = new Histo2D(ObjectFitter::FitResidus(*mH2, *mFit));
-      if(ob) omg.AddObj(ob,nomres);
-    }
-    if(mOpt.okfun) {
-      Histo2D* ob = new Histo2D(ObjectFitter::FitFunction(*mH2, *mFit));
-      if(ob) omg.AddObj(ob,nomfun);
-    }
-//CMV_A_FAIRE  } else if(mIm) {
-//CMV_A_FAIRE    if(mOpt.okres) {
-//CMV_A_FAIRE      RzImage* ob = mIm->FitResidus(*mFit);  
-//CMV_A_FAIRE      if(ob) {ImageR4* rob = new ImageR4(*ob); omg.AddObj(rob,nomres); delete ob;}
-//CMV _A_FAIRE    }
-//CMV_A_FAIRE    if(mOpt.okfun) {
-//CMV_A_FAIRE      RzImage* ob = mIm->FitFunction(*mFit);
-//CMV_A_FAIRE      if(ob) {ImageR4* rob = new ImageR4(*ob); omg.AddObj(rob,nomfun); delete ob;}
-//CMV_A_FAIRE    }
-  } else if(mG) {
-    if(mOpt.okres) {
-      //GeneralFitData* ob = new GeneralFitData(mG->FitResidus(*mFit));
-      GeneralFitData* ob = new GeneralFitData(ObjectFitter::FitResidus(*mG, *mFit));
-      if(ob) omg.AddObj(ob,nomres);
-    }
-    if(mOpt.okfun) {
-      //GeneralFitData* ob = new GeneralFitData(mG->FitFunction(*mFit));
-      GeneralFitData* ob = new GeneralFitData(ObjectFitter::FitFunction(*mG, *mFit));
-      if(ob) omg.AddObj(ob,nomfun);
-    }
-  }
-//####################
-#endif
-//####################
-}
+if(!mFit) return;
+
+NamedObjMgr omg;
+string nomresfun = "__dummy__";
+
+if(mOpt.okres) {
+  nomresfun = mNObj + "_res";
+  AnyDataObj* ob = mAdObj->FitResidusObj(*mFit);
+  if(ob) omg.AddObj(ob,nomresfun);
+}
+
+if(mOpt.okfun) {
+  nomresfun = mNObj + "_fun";
+  AnyDataObj* ob = mAdObj->FitFunctionObj(*mFit);
+  if(ob) omg.AddObj(ob,nomresfun);
+}
+
 return;
 }
@@ -1029,14 +903,19 @@
 if(mFName.length()>1) sscanf(mFName.c_str()+1,"%d",&degre);
 
+double xc = (mOpt.polcx>0) ? mOpt.xc : 0.;
+double yc = (mOpt.polcy>0) ? mOpt.yc : 0.;
+
 if(mNVar==1) {  // Fit lineaire de polynome 1D
-  cout<<"Fit (lineaire) 1D polynome de degre "<<degre<<endl;
+  cout<<"Fit (lineaire) 1D polynome de degre "<<degre
+      <<" (xc="<<xc<<")"<<endl;
   Poly p1(0);
-  double c2rl = mGData->PolFit(0,p1,degre);
+  double c2rl = mGData->PolFit(0,p1,degre,xc);
   cout<<"C2r_lineaire = "<<c2rl<<endl;
   if(mOpt.lp>0) cout<<p1<<endl;
 } else if(mNVar==2) {  // Fit lineaire de polynome 2D
-  cout<<"Fit (lineaire) polynome 2D de degre "<<degre<<endl;
+  cout<<"Fit (lineaire) polynome 2D de degre "<<degre
+      <<" (xc,yc="<<xc<<","<<yc<<")"<<endl;
   Poly2 p2(0);
-  double c2rl = mGData->PolFit(0,1,p2,degre);
+  double c2rl = mGData->PolFit(0,1,p2,degre,xc,yc);
   cout<<"C2r_lineaire = "<<c2rl<<endl;
   if(mOpt.lp>0) cout<<p2<<endl;
@@ -1148,5 +1027,5 @@
   <<" avec Options: [p:p1,...,pn s:s1,...,sn m:m1,...,mn \n"
   <<"                M:M1,...,Mn f:f1,...,fn o:.,.,. o:.,.,.]\n"
-  <<" ou   fitlin nomobj func [o:.,.,. o:.,.,.]\n";
+  <<" ou   fitlin nomobj pnn [o:.,.,. o:.,.,.]\n";
   return(-1);
 }
@@ -1172,7 +1051,6 @@
 DecodeObject(tokens[0]);
 CheckOptions();
+FillGData();
 if(mOpt.lp>0) PrintOptions();
-if(kw == "fitlin") ApplyXYcentering=true; else ApplyXYcentering=false;
-FillGData();
 DecodeFunction(tokens[1]);
 DecodeParam(mSp,mSs,mSm,mSM,mSf);
@@ -1306,7 +1184,6 @@
 , mDap(par), mFitter(fiter), mFunc(func)
 , ReFillGData(false), ReDecodeFunc(false)
-, ErrValue(1.)
 , saveI1(0), saveI2(0), saveJ1(0), saveJ2(0)
-, saveErrValue(1.), saveXC(0.), saveYC(0.)
+, saveErrScale(1.),saveErrMin(0.), saveXC(0.), saveYC(0.)
 {
 #ifdef SANS_EVOLPLANCK
@@ -1319,6 +1196,6 @@
 
 // Alloc de la taille
-nlab = 13+npar;   lab = new PILabel*[nlab];    {for(int i=0;i<nlab;i++) lab[i]=NULL;}
-ntxt = 10+4*npar; txt = new PIText*[ntxt];     {for(int i=0;i<ntxt;i++) txt[i]=NULL;}
+nlab = 15+npar;   lab = new PILabel*[nlab];    {for(int i=0;i<nlab;i++) lab[i]=NULL;}
+ntxt = 15+4*npar; txt = new PIText*[ntxt];     {for(int i=0;i<ntxt;i++) txt[i]=NULL;}
 nbut = 6;         but = new PIButton*[nbut];   {for(int i=0;i<nbut;i++) but[i]=NULL;}
 nckb = 2+npar;    ckb = new PICheckBox*[nckb]; {for(int i=0;i<nckb;i++) ckb[i]=NULL;}
@@ -1360,58 +1237,68 @@
 // new ligne
 cpx = spx; cpy += bsy+spy;
-pom[0] = new PIOptMenu(this,"Err def",1.5*bsx,bsy,cpx,cpy);
+pom[0] = new PIOptMenu(this,"Err def",1.25*bsx,bsy,cpx,cpy);
   pom[0]->AppendItem("Err def",2101);
   pom[0]->AppendItem("Err cste",2102);
   pom[0]->AppendItem("Err sqrt",2103);
+  pom[0]->AppendItem("Err prop",2104);
   pom[0]->SetValue(2101);
 pom[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx += int(1.5*bsx+spx);
+cpx += int(1.25*bsx+spx);
+lab[1] = new PILabel(this,"E_Scale",bsx, bsy, cpx, cpy);
+lab[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
 txt[0] = new PIText(this,"",bsx,bsy,cpx,cpy);
 txt[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 cpx += bsx+spx;
-lab[1] = new PILabel(this,"Prt,dbg",bsx,bsy,cpx,cpy);
-lab[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx += bsx+spx;
-txt[1] = new PIText(this,"",bsx,bsy,cpx,cpy);
+lab[2] = new PILabel(this,"E_Min",0.75*bsx,bsy,cpx,cpy);
+lab[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(0.75*bsx+spx);
+txt[1] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
 txt[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 
 // new ligne
 cpx = spx; cpy += bsy+spy;
-lab[2] = new PILabel(this,"Stop Xi2",1.25*bsx,bsy,cpx,cpy);
-lab[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx += int(1.25*bsx+spx);
-txt[2] = new PIText(this,"",bsx,bsy,cpx,cpy);
+lab[3] = new PILabel(this,"Prt,dbg",bsx,bsy,cpx,cpy);
+lab[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+txt[2] = new PIText(this,"",0.5*bsx,bsy,cpx,cpy);
 txt[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx += bsx+spx;
-lab[3] = new PILabel(this,"Iter",bsx, bsy, cpx, cpy);
-lab[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(0.5*bsx+spx);
+lab[4] = new PILabel(this,"Stop X2",bsx,bsy,cpx,cpy);
+lab[4]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 cpx += bsx+spx;
 txt[3] = new PIText(this,"",bsx,bsy,cpx,cpy);
 txt[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+lab[5] = new PILabel(this,"Iter",0.5*bsx, bsy, cpx, cpy);
+lab[5]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(0.5*bsx+spx);
+txt[4] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
+txt[4]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 
 // new ligne
 cpx = spx; cpy += bsy+spy;
-lab[4] = new PILabel(this,"Range X",bsx,bsy,cpx,cpy);
-lab[4]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+lab[6] = new PILabel(this,"Range X",bsx,bsy,cpx,cpy);
+lab[6]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 cpx += bsx+spx;
-txt[4] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
-txt[4]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx += int(0.75*bsx+spx);
 txt[5] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
 txt[5]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 cpx += int(0.75*bsx+spx);
-lab[5] = new PILabel(this,"Y",bsx/2,bsy,cpx,cpy);
-lab[5]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx += int(bsx/2.+spx);
 txt[6] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
 txt[6]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 cpx += int(0.75*bsx+spx);
+lab[7] = new PILabel(this,"Y",bsx/2,bsy,cpx,cpy);
+lab[7]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(bsx/2.+spx);
 txt[7] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
 txt[7]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(0.75*bsx+spx);
+txt[8] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
+txt[8]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 
 // new ligne
 cpx = spx; cpy += bsy+spy;
-lab[6] = new PILabel(this,"Cent",bsx/2,bsy,cpx,cpy);
-lab[6]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+lab[8] = new PILabel(this,"Cent",bsx/2,bsy,cpx,cpy);
+lab[8]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 cpx += int(bsx/2.+spx);
 pom[1] = new PIOptMenu(this,"X.No",1.25*bsx,bsy,cpx,cpy);
@@ -1422,6 +1309,6 @@
 pom[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 cpx += int(1.25*bsx+spx);
-txt[8] = new PIText(this,"",bsx,bsy,cpx,cpy);
-txt[8]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+txt[9] = new PIText(this,"",bsx,bsy,cpx,cpy);
+txt[9]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 cpx += bsx+spx;
 pom[2] = new PIOptMenu(this,"Y.No",1.25*bsx,bsy,cpx,cpy);
@@ -1432,6 +1319,6 @@
 pom[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 cpx += int(1.25*bsx+spx);
-txt[9] = new PIText(this,"",bsx,bsy,cpx,cpy);
-txt[9]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+txt[10] = new PIText(this,"",bsx,bsy,cpx,cpy);
+txt[10]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 
 // new ligne
@@ -1451,21 +1338,21 @@
 // new ligne
 cpx = spx; cpy += bsy+spy;
-lab[7] = new PILabel(this,"Par",bsx/2,bsy,cpx,cpy);
-lab[7]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+lab[9] = new PILabel(this,"Par",bsx/2,bsy,cpx,cpy);
+lab[9]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 cpx += int(bsx/2.+spx);
-lab[8] = new PILabel(this,"Fx",bsx/3,bsy,cpx,cpy);
-lab[8]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+lab[10] = new PILabel(this,"Fx",bsx/3,bsy,cpx,cpy);
+lab[10]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 cpx += int(bsx/3.+spx);
-lab[9] = new PILabel(this,"Init",bsx,bsy,cpx,cpy);
-lab[9]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx += bsx+spx;
-lab[10] = new PILabel(this,"Step",bsx,bsy,cpx,cpy);
-lab[10]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx += bsx+spx;
-lab[11] = new PILabel(this,"Min",bsx,bsy,cpx,cpy);
+lab[11] = new PILabel(this,"Init",bsx,bsy,cpx,cpy);
 lab[11]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 cpx += bsx+spx;
-lab[12] = new PILabel(this,"Max",bsx,bsy,cpx,cpy);
+lab[12] = new PILabel(this,"Step",bsx,bsy,cpx,cpy);
 lab[12]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+lab[13] = new PILabel(this,"Min",bsx,bsy,cpx,cpy);
+lab[13]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+lab[14] = new PILabel(this,"Max",bsx,bsy,cpx,cpy);
+lab[14]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 
 // new lines: Parametres (npar lignes)
@@ -1474,6 +1361,6 @@
     cpx = spx; cpy += bsy+spy;
     char str[8]; sprintf(str,"P%d",i);
-    lab[13+i] = new PILabel(this,str,bsx/2,bsy,cpx,cpy);
-    lab[13+i]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+    lab[15+i] = new PILabel(this,str,bsx/2,bsy,cpx,cpy);
+    lab[15+i]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
     cpx += int(bsx/2.+spx);
     // Attention pas de message entre 1500 et 2000 (permet 500 parametres!)
@@ -1482,6 +1369,6 @@
     cpx+=int(bsx/3.+spx);
     for(int j=0;j<4;j++) {
-      txt[10+4*i+j] = new PIText(this,"",bsx,bsy,cpx,cpy);
-      txt[10+4*i+j]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+      txt[15+4*i+j] = new PIText(this,"",bsx,bsy,cpx,cpy);
+      txt[15+4*i+j]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
       cpx += bsx+spx;
     }
@@ -1523,4 +1410,10 @@
 int npar = mFitter->mNPar;
 
+// Les menus d'options
+if(mFitter->mOpt.err_type==GeneralFitData::DefaultError)  pom[0]->SetValue(2101);
+if(mFitter->mOpt.err_type==GeneralFitData::ConstantError) pom[0]->SetValue(2102);
+if(mFitter->mOpt.err_type==GeneralFitData::SqrtError)     pom[0]->SetValue(2103);
+if(mFitter->mOpt.err_type==GeneralFitData::ProporError)   pom[0]->SetValue(2104);
+
 // Les check-boxes
 ckb[0]->SetState(mFitter->mOpt.okfun);
@@ -1531,20 +1424,21 @@
 // Les champs textes
 char str[128]; string dum;
-sprintf(str,"%f",ErrValue); dum=str; txt[0]->SetText(dum);
-sprintf(str,"%d,%d",mFitter->mOpt.lp,mFitter->mOpt.lpg); dum=str; txt[1]->SetText(dum);
-sprintf(str,"%f",mFitter->mOpt.stc2);  dum=str; txt[2]->SetText(dum);
-sprintf(str,"%d",mFitter->mOpt.nstep); dum=str; txt[3]->SetText(dum);
-sprintf(str,"%d",mFitter->mOpt.i1);    dum=str; txt[4]->SetText(dum);
-sprintf(str,"%d",mFitter->mOpt.i2);    dum=str; txt[5]->SetText(dum);
-sprintf(str,"%d",mFitter->mOpt.j1);    dum=str; txt[6]->SetText(dum);
-sprintf(str,"%d",mFitter->mOpt.j2);    dum=str; txt[7]->SetText(dum);
-sprintf(str,"%f",mFitter->mOpt.xc);    dum=str; txt[8]->SetText(dum);
-sprintf(str,"%f",mFitter->mOpt.yc);    dum=str; txt[9]->SetText(dum);
+sprintf(str,"%f",mFitter->mOpt.err_scale); dum=str; txt[0]->SetText(dum);
+sprintf(str,"%f",mFitter->mOpt.err_min);   dum=str; txt[1]->SetText(dum);
+sprintf(str,"%d,%d",mFitter->mOpt.lp,mFitter->mOpt.lpg); dum=str; txt[2]->SetText(dum);
+sprintf(str,"%f",mFitter->mOpt.stc2);  dum=str; txt[3]->SetText(dum);
+sprintf(str,"%d",mFitter->mOpt.nstep); dum=str; txt[4]->SetText(dum);
+sprintf(str,"%d",mFitter->mOpt.i1);    dum=str; txt[5]->SetText(dum);
+sprintf(str,"%d",mFitter->mOpt.i2);    dum=str; txt[6]->SetText(dum);
+sprintf(str,"%d",mFitter->mOpt.j1);    dum=str; txt[7]->SetText(dum);
+sprintf(str,"%d",mFitter->mOpt.j2);    dum=str; txt[8]->SetText(dum);
+sprintf(str,"%f",mFitter->mOpt.xc);    dum=str; txt[9]->SetText(dum);
+sprintf(str,"%f",mFitter->mOpt.yc);    dum=str; txt[10]->SetText(dum);
 if(npar>0) {
   for(int i=0;i<npar;i++) {
-    sprintf(str,"%f",mFitter->mPar(i));  dum=str; txt[10+4*i+0]->SetText(dum);
-    sprintf(str,"%f",mFitter->mStep(i)); dum=str; txt[10+4*i+1]->SetText(dum);
-    sprintf(str,"%f",mFitter->mMin(i));  dum=str; txt[10+4*i+2]->SetText(dum);
-    sprintf(str,"%f",mFitter->mMax(i));  dum=str; txt[10+4*i+3]->SetText(dum);
+    sprintf(str,"%f",mFitter->mPar(i));  dum=str; txt[15+4*i+0]->SetText(dum);
+    sprintf(str,"%f",mFitter->mStep(i)); dum=str; txt[15+4*i+1]->SetText(dum);
+    sprintf(str,"%f",mFitter->mMin(i));  dum=str; txt[15+4*i+2]->SetText(dum);
+    sprintf(str,"%f",mFitter->mMax(i));  dum=str; txt[15+4*i+3]->SetText(dum);
   }
 }
@@ -1573,33 +1467,38 @@
   cout<<"PIAFitterWind::Process Error , Pas d'objet de nom "
       <<mFitter->mNObj<<endl;
-  mFitter->ResetDPointer(); return;
+  return;
 }
 
 // On recupere les champs textes
 string dum; char str[128];
-// Attention gestion du type d'erreur
+// Attention gestion du type d'erreur (scale et min)
 dum=txt[0]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
-  sscanf(str,"%lf",&ErrValue); if(ErrValue<=0.) ErrValue=1.;
-  if(mFitter->mOpt.err_e>0. ) mFitter->mOpt.err_e = ErrValue;
-  if(mFitter->mOpt.err_E>0. ) mFitter->mOpt.err_E = ErrValue;
-  if(saveErrValue!=ErrValue) {
-    if(lp) cout<<"ErrValue changed: "<<ErrValue<<endl;
+  sscanf(str,"%lf",&(mFitter->mOpt.err_scale));
+  if(saveErrScale!=mFitter->mOpt.err_scale) {
+    if(lp) cout<<"ErrScale changed: "<<mFitter->mOpt.err_scale<<endl;
     ReFillGData = true;
-    saveErrValue = ErrValue;
+    saveErrScale = mFitter->mOpt.err_scale;
   }
 dum=txt[1]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+  sscanf(str,"%lf",&(mFitter->mOpt.err_min));
+  if(saveErrMin!=mFitter->mOpt.err_min) {
+    if(lp) cout<<"ErrMin changed: "<<mFitter->mOpt.err_min<<endl;
+    ReFillGData = true;
+    saveErrMin = mFitter->mOpt.err_min;
+  }
+dum=txt[2]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
   sscanf(str,"%d,%d",&(mFitter->mOpt.lp),&(mFitter->mOpt.lpg));
-dum=txt[2]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+dum=txt[3]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
   sscanf(str,"%lf",&(mFitter->mOpt.stc2));
-dum=txt[3]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+dum=txt[4]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
   sscanf(str,"%d",&(mFitter->mOpt.nstep));
 // Attention si les valeurs de mOpt.i1/.i2/.j1/.j2 ont ete changees
-dum=txt[4]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+dum=txt[5]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
   sscanf(str,"%d",&(mFitter->mOpt.i1));
-dum=txt[5]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+dum=txt[6]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
   sscanf(str,"%d",&(mFitter->mOpt.i2));
-dum=txt[6]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+dum=txt[7]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
   sscanf(str,"%d",&(mFitter->mOpt.j1));
-dum=txt[7]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+dum=txt[8]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
   sscanf(str,"%d",&(mFitter->mOpt.j2));
   if(saveI1!=mFitter->mOpt.i1 || saveI2!=mFitter->mOpt.i2 ||
@@ -1615,12 +1514,12 @@
     saveJ1=mFitter->mOpt.j1; saveJ2=mFitter->mOpt.j2;
   }
-dum=txt[8]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+dum=txt[9]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
   sscanf(str,"%lf",&(mFitter->mOpt.xc));
-dum=txt[9]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+dum=txt[10]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
   sscanf(str,"%lf",&(mFitter->mOpt.yc));
   if(saveXC!=mFitter->mOpt.xc || saveYC!=mFitter->mOpt.yc) {
     if(lp) cout<<"mOpt.xc,yc changed: "<<mFitter->mOpt.xc
                <<" , "<<mFitter->mOpt.xc<<endl;
-    ReFillGData = true; ReDecodeFunc = true;
+    ReDecodeFunc = true;
     saveXC = mFitter->mOpt.xc; saveYC = mFitter->mOpt.yc;
   }
@@ -1628,11 +1527,11 @@
 if(npar>0) {
   for(int i=0;i<npar;i++) {
-    dum=txt[10+4*i+0]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+    dum=txt[15+4*i+0]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
       sscanf(str,"%lf",&(mFitter->mPar(i)));
-    dum=txt[10+4*i+1]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+    dum=txt[15+4*i+1]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
       sscanf(str,"%lf",&(mFitter->mStep(i)));
-    dum=txt[10+4*i+2]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+    dum=txt[15+4*i+2]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
       sscanf(str,"%lf",&(mFitter->mMin(i)));
-    dum=txt[10+4*i+3]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+    dum=txt[15+4*i+3]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
       sscanf(str,"%lf",&(mFitter->mMax(i)));
   }
@@ -1645,12 +1544,13 @@
   if(ReFillGData) mFitter->FillGData();
   ReFillGData = false;
+  if(ReDecodeFunc) mFitter->DecodeFunction(mFunc);
+  ReDecodeFunc = false;
 }
 else if(msg ==111) {
   if(lp) cout<<"Update from last"<<endl;
-  mFitter->ResetOptions();
   mFitter->mOpt = mFitter->mOptSave;
   mFitter->ReSetParam();
   mFitter->InitParFromLastFit();
-  ReFillGData = true;
+  ReFillGData = ReDecodeFunc = true;
 }
 else if(msg ==222) {
@@ -1658,13 +1558,10 @@
   mFitter->ResetOptions();
   mFitter->ReSetParam();
-  ReFillGData = true;
+  ReFillGData = ReDecodeFunc = true;
 }
 else if(msg ==333) {
   if(lp) cout<<"Do the fit"<<endl;
   mFitter->CheckOptions();
-  if(ReFillGData) {
-    if(lp) cout<<"ReFill Data"<<endl;
-    mFitter->FillGData();
-  }
+  if(ReFillGData) mFitter->FillGData();
   ReFillGData = false;
   if(ReDecodeFunc) mFitter->DecodeFunction(mFunc);
@@ -1695,11 +1592,16 @@
   }
 }
-else if(2101<=msg && msg<=2103) {
-  mFitter->mOpt.err_e = mFitter->mOpt.err_E = -1.;
-  if(msg==2102)      mFitter->mOpt.err_e = ErrValue;
-  else if(msg==2103) mFitter->mOpt.err_E = ErrValue;
-  if(lp) cout<<"Err_cste="<<mFitter->mOpt.err_e
-             <<" Err_sqrt="<<mFitter->mOpt.err_E
-             <<" ErrValue="<<ErrValue<<endl;
+else if(2101<=msg && msg<=2104) {
+  if(msg==2101)
+    {mFitter->mOpt.err_type = GeneralFitData::DefaultError; dum="DefaultError";}
+  if(msg==2102)
+    {mFitter->mOpt.err_type = GeneralFitData::ConstantError; dum="ConstantError";}
+  if(msg==2103)
+    {mFitter->mOpt.err_type = GeneralFitData::SqrtError; dum="SqrtError";}
+  if(msg==2104)
+    {mFitter->mOpt.err_type = GeneralFitData::ProporError; dum="ProporError";}
+  if(lp) cout<<"Err_type="<<dum
+             <<" Err_scale="<<mFitter->mOpt.err_scale
+             <<" Err_min="<<mFitter->mOpt.err_min<<endl;
   ReFillGData = true;
 }
@@ -1708,5 +1610,6 @@
   if(lp) cout<<"Centrage X polcx="<<mFitter->mOpt.polcx
              <<" xc="<<mFitter->mOpt.xc<<endl;
-  ReFillGData = true; ReDecodeFunc = true;
+  mFitter->GetCentering();
+  ReDecodeFunc = true;
 }
 else if(2011<=msg && msg<=2013) {
@@ -1714,5 +1617,6 @@
   if(lp) cout<<"Centrage Y polcy="<<mFitter->mOpt.polcy
              <<" yc="<<mFitter->mOpt.yc<<endl;
-  ReFillGData = true; ReDecodeFunc = true;
+  mFitter->GetCentering();
+  ReDecodeFunc = true;
 }
 else if(msg>=1500 && msg<2000) {
