Index: trunk/SophyaPI/PIext/exclude
===================================================================
--- trunk/SophyaPI/PIext/exclude	(revision 384)
+++ trunk/SophyaPI/PIext/exclude	(revision 385)
@@ -1,1 +1,2 @@
 modrecst.cc
+userfitfunex.c
Index: trunk/SophyaPI/PIext/piafitting.cc
===================================================================
--- trunk/SophyaPI/PIext/piafitting.cc	(revision 384)
+++ trunk/SophyaPI/PIext/piafitting.cc	(revision 385)
@@ -56,4 +56,5 @@
   bool ReFillGData;
   int saveI1,saveI2, saveJ1, saveJ2;
+  double ErrValue;
 };
 
@@ -103,4 +104,5 @@
 //|      : M   : fit Moffat+fond (expos=p6) (volume) 2D
 //|      : Mi  : fit Moffat+fond integree (expos=p6) (volume) 2D
+//|      : Autre : fonction definie par l'utilisateur (cf commentaires ci apres)
 //|
 //|----- INIT PARAMETRES ET ETAT DU FIT -----
@@ -139,4 +141,28 @@
 //|          Pour gauss+poly 1D, xc est le centre de la gaussienne.
 //|2D    yaa.b et y : idem "xaa.b et x" mais pour y
+//|
+////////////////////////////////////////////////////////////////////////
+//| --------------- Def des fcts de fit par l'utilisateur ---------------
+//| Pour definir une fonction parametree utilisateur:
+//| Un exemple de fichier contenant des fonctions a fitter: PIext/userfitfunex.c
+//| > crfitfil nom_fichier nom_fonction nvar npar
+//|     pour creer un squelette de fichier C contenant la fonction a fitter
+//|            nom_fichier : nom du fichier ou est le code de la fonction
+//|                          c'est un fichier C de nom blabla.c
+//|            nom_fonction : nom de la fonction ex: gauss2
+//|            nvar : nombre de variables x[] (1D=1, 2D=2, etc...)
+//|            npar : nombre de parametre p[]
+//|   - La fonction est donc F(x[];p[]), soit par ex:
+//|            double gauss2(double const* x,double const* p)
+//|   - L'utilisateur a la possibilite de donner egalement la fonction
+//|     retournant les derivees de la fonction par rapport aux parametres
+//|            double gauss2_der(double const* x,double const* p,double* dp)
+//|     ou dp[i] = dF(x[];p[])/dp[i]
+//|     Par convention, cette fonction a le meme nom suivi de "_der"
+//| > crfitfun nom_fichier nom_fonction nvar npar
+//|     Permet de compiler le fichier "nom_fichier" et de linker
+//|     la fonction "nom_fonction"
+//|   - Un meme fichier peut contenir plusieurs fonctions a fitter
+//|
 ////////////////////////////////////////////////////////////////////////
 
@@ -144,5 +170,5 @@
 PIAFitter::PIAFitter(PIACmd *piac, PIStdImgApp* app)
 : mApp(app), FWindFit(NULL)
-, mNObj(""), mObj(NULL), mFunc(NULL), mFName(""), mGData(NULL)
+, mNObj(""), mObj(NULL), mGData(NULL)
 , mNPar(0), mNVar(0),  mNBinX(0), mNBinY(0), mNData(0)
 , mPar(1), mStep(1), mMin(1), mMax(1), mFix(1)
@@ -150,4 +176,5 @@
 , mFit(NULL)
 , mV(NULL), mH(NULL), mM(NULL), mH2(NULL), mIm(NULL), mG(NULL)
+, mFunction(NULL), mFName(""), mFunc(NULL)
 , mDlUFunc(NULL), mNameFitFunc(""), mFitFunc(NULL), mFitFuncDer(NULL)
 , mUFNVar(0), mUFNPar(0)
@@ -180,7 +207,12 @@
 
 kw = "crfitfun";
-usage = "Creation de user function ";
+usage = "Creation et link de function utilisateur pour le fit";
 usage += "\n Usage: crfitfun file func nvar npar";
 piac->RegisterCommand(kw,usage,this,"Fitting");
+
+kw = "crfitfil";
+usage = "Creation de fichier C pour function utilisateur du fit";
+usage += "\n Usage: crfitfil file func nvar npar";
+piac->RegisterCommand(kw,usage,this,"Fitting");
 }
 
@@ -188,9 +220,10 @@
 PIAFitter::~PIAFitter()
 {
-if(mFit != NULL) {delete mFit; mFit=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;
+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;}
 }
 
@@ -402,5 +435,6 @@
     <<" Cent="<<mOpt.polcx<<","<<mOpt.polcy<<","<<mOpt.xc<<"+x"<<","<<mOpt.yc<<"+y"
     <<" TypE="<<mOpt.err_e<<","<<mOpt.err_E
-    <<" StpX2="<<mOpt.stc2<<" Nstep="<<mOpt.nstep<<" Init.LFit="<<mOpt.fromlastfit
+    <<" StpX2="<<mOpt.stc2<<" Nstep="<<mOpt.nstep<<endl
+    <<" Init.LFit="<<mOpt.fromlastfit
     <<" lp,lpg="<<mOpt.lp<<","<<mOpt.lpg<<endl;
 return;
@@ -464,89 +498,80 @@
 // ATTENTION: cette methode a besoin que les donnees soient lues
 {
-if(func.length()<=0) {
-  cout<<"PIAFitter::DecodeFunction Donnez un nom de fonction a fitter."<<endl;
-  return;
-}
-if(mFunc!=NULL) {delete mFunc; mFunc=NULL;}
-
+if(func.length()<=0)
+  {cout<<"PIAFitter::DecodeFunction Donnez un nom de fonction a fitter."<<endl;
+   return;}
+if(mFunction!=NULL) {delete mFunction; mFunction=NULL;}
+if(mFunc!=NULL)     {delete mFunc;     mFunc=NULL;}
 mNPar=0;
-mFName = func;
-
-if(func[0]=='p' && mNVar==1) { //polynome
-  int degre = 0;
-  if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
+
+if(func == mNameFitFunc) { // Fonction utilisateur
+  mFunc = new GeneralFunc(mUFNVar,mUFNPar,mFitFunc,mFitFuncDer);
+  mNPar = mUFNPar;
+} else if(func[0]=='p' && mNVar==1) { //polynome
+  int degre=0; if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
   cout<<"Fit polynome 1D de degre "<<degre<<endl;
   Polyn1D* myf = new Polyn1D(degre,mOpt.xc);
-  mFunc = myf; mNPar = mFunc->NPar();
+  mFunction = myf; mNPar = mFunction->NPar(); mFName = func;
 
 } else if(func[0]=='e' && mNVar==1) { //exponentielle
-  int degre =-1;
-  if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
+  int degre=-1; if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
   cout<<"Fit d'exponentielle+polynome 1D de degre "<<degre<<endl;
   Exp1DPol* myf;
   if(degre>=0) myf = new Exp1DPol((unsigned int)degre,mOpt.xc);
        else    myf = new Exp1DPol(mOpt.xc);
-  mFunc = myf; mNPar = mFunc->NPar();
+  mFunction = myf; mNPar = mFunction->NPar(); mFName = func;
 
 } else if(func[0]=='g' && mNVar==1) { //gaussienne en hauteur
-  int degre =-1;
-  if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
+  int degre=-1; if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
   cout<<"Fit de Gaussienne_en_hauteur+polynome 1D de degre "<<degre<<endl;
   Gauss1DPol* myf;
   if(degre>=0) myf = new Gauss1DPol((unsigned int)degre,((mOpt.polcx)?true:false));
   else { bool bfg = (mOpt.polcx)?true:false;   myf = new Gauss1DPol(bfg); }
-  mFunc = myf; mNPar = mFunc->NPar();
+  mFunction = myf; mNPar = mFunction->NPar(); mFName = func;
 
 } else if(func[0]=='G' && mNVar==1) { //gaussienne en volume
-  int degre =-1;
-  if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
+  int degre=-1; if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
   cout<<"Fit de Gaussienne_en_volume+polynome 1D de degre "<<degre<<endl;
   GaussN1DPol* myf;
   if(degre>=0) myf = new GaussN1DPol((unsigned int)degre,((mOpt.polcx)?true:false));
   else  { bool bfg = (mOpt.polcx)?true:false;   myf = new GaussN1DPol(bfg); }
-  mFunc = myf; mNPar = mFunc->NPar();
+  mFunction = myf; mNPar = mFunction->NPar(); mFName = func;
 
 } else if(func[0]=='p' && mNVar==2) { //polynome 2D
-  int degre = 0;
-  if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
+  int degre=0; if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
   cout<<"Fit polynome 2D de degre "<<degre<<endl;
   Polyn2D* myf = new Polyn2D(degre,mOpt.xc,mOpt.yc);
-  mFunc = myf; mNPar = mFunc->NPar();
+  mFunction = myf; mNPar = mFunction->NPar(); mFName = func;
 
 } else if(func[0]=='G' && mNVar==2) { //gaussienne+fond en volume
-  int integ = 0;
-  if(func.length()>1) if(func[1]=='i') integ=1;
+  int integ=0; if(func.length()>1) if(func[1]=='i') integ=1;
   cout<<"Fit de Gaussienne+Fond 2D integ="<<integ<<endl;
-  if(integ) {GauRhInt2D* myf = new GauRhInt2D; mFunc = myf;}
-    else    {GauRho2D* myf = new GauRho2D; mFunc = myf;}
-  mNPar = mFunc->NPar();
+  if(integ) {GauRhInt2D* myf = new GauRhInt2D; mFunction = myf;}
+    else    {GauRho2D* myf = new GauRho2D; mFunction = myf;}
+  mNPar = mFunction->NPar(); mFName = func;
 
 } else if(func[0]=='d' && mNVar==2) { //DL gaussienne+fond en volume
-  int integ = 0;
-  if(func.length()>1) if(func[1]=='i') integ=1;
+  int integ=0; if(func.length()>1) if(func[1]=='i') integ=1;
   cout<<"Fit de DL de Gaussienne+Fond 2D integ="<<integ<<endl;
-  if(integ) {GdlRhInt2D* myf = new GdlRhInt2D; mFunc = myf;}
-    else    {GdlRho2D* myf = new GdlRho2D; mFunc = myf;}
-  mNPar = mFunc->NPar();
+  if(integ) {GdlRhInt2D* myf = new GdlRhInt2D; mFunction = myf;}
+    else    {GdlRho2D*   myf = new GdlRho2D; mFunction = myf;}
+  mNPar = mFunction->NPar(); mFName = func;
 
 } else if(func[0]=='D' && mNVar==2) { //DL gaussienne+fond avec coeff variable p6 en volume
-  int integ = 0;
-  if(func.length()>1) if(func[1]=='i') integ=1;
+  int integ=0; if(func.length()>1) if(func[1]=='i') integ=1;
   cout<<"Fit de DL de Gaussienne+Fond avec coeff variable (p6) 2D integ="<<integ<<endl;
-  if(integ) {Gdl1RhInt2D* myf = new Gdl1RhInt2D; mFunc = myf;}
-    else    {Gdl1Rho2D* myf = new Gdl1Rho2D; mFunc = myf;}
-  mNPar = mFunc->NPar();
+  if(integ) {Gdl1RhInt2D* myf = new Gdl1RhInt2D; mFunction = myf;}
+    else    {Gdl1Rho2D*   myf = new Gdl1Rho2D; mFunction = myf;}
+  mNPar = mFunction->NPar(); mFName = func;
 
 } else if(func[0]=='M' && mNVar==2) { //Moffat+fond (volume)
-  int integ = 0;
-  if(func.length()>1) if(func[1]=='i') integ=1;
+  int integ=0; if(func.length()>1) if(func[1]=='i') integ=1;
   cout<<"Fit de Moffat+Fond (expos=p6) 2D integ="<<integ<<endl;
-  if(integ) {MofRhInt2D* myf = new MofRhInt2D; mFunc = myf;}
-    else    {MofRho2D* myf = new MofRho2D; mFunc = myf;}
-  mNPar = mFunc->NPar();
+  if(integ) {MofRhInt2D* myf = new MofRhInt2D; mFunction = myf;}
+    else    {MofRho2D*   myf = new MofRho2D; mFunction = myf;}
+   mNPar = mFunction->NPar(); mFName = func;
 
 } else {
   cout<<"Fonction "<<func<<" inconnue pour la dim "<<mNVar<<endl;
-  mNPar = 0;
   return;
 }
@@ -621,11 +646,13 @@
 {
 if(mNPar==0) return -1000;
-if(mFunc==NULL || mGData==NULL) {
-  cout<<"PIAFitter::DoFit error: mFunc="<<mFunc<<" mGData="<<mGData<<endl;
+if((mFunction==NULL && mFunc==NULL) || mGData==NULL) {
+  cout<<"PIAFitter::DoFit error: mFunction,mFunc="<<mFunction<<","<<mFunc
+      <<" mGData="<<mGData<<endl;
   return -1001;
 }
 // classe GeneraFit
 if(mFit != NULL) {delete mFit; mFit= NULL;}
-mFit= new GeneralFit(mFunc);
+if(mFunction) mFit= new GeneralFit(mFunction);
+  else        mFit= new GeneralFit(mFunc);
 // Options et Set de GeneralFit
 mFit->SetDebug(mOpt.lpg);
@@ -633,5 +660,5 @@
 mFit->SetStopChi2(mOpt.stc2);
 mFit->SetMaxStep(mOpt.nstep);
-{for(int i=0;i<mFunc->NPar();i++) {
+{for(int i=0;i<mNPar;i++) {
   char str[10];
   sprintf(str,"P%d",i);
@@ -651,5 +678,5 @@
   c2r = mFit->GetChi2Red();
   cout<<"C2r_Reduit = "<<c2r<<" nstep="<<mFit->GetNStep()<<" rc="<<rcfit<<endl;
-  for(int i=0;i<mFunc->NPar();i++) mParSave(i)=mFit->GetParm(i);
+  for(int i=0;i<mNPar;i++) mParSave(i)=mFit->GetParm(i);
 } else {
   cout<<"echec Fit, rc = "<<rcfit<<"  nstep="<<mFit->GetNStep()<<endl;
@@ -664,5 +691,5 @@
 // Mise a disposition des resultats (fonction fitee et residus)
 {
-if(mFunc && (mOpt.okres||mOpt.okfun)) {
+if(mFit && (mOpt.okres||mOpt.okfun)) {
   NamedObjMgr omg;
   string nomres = mNObj + "_res";
@@ -730,52 +757,77 @@
 
 /* --Methode-- */
-void PIAFitter::LinkFitFunc(string const & fname, string const & funcname, int nvar, int npar)
-{
-
-if ((nvar < 1) || (npar < 1)) return;
-
-if (mDlUFunc != NULL) delete mDlUFunc;  // Nous en avons deja un, on nettoie
-
-mDlUFunc = NULL;
-mFitFunc = NULL; 
-mFitFuncDer = NULL; 
-mUFNVar= mUFNPar = 0;
-mNameFitFunc = "";
+void PIAFitter::LinkFitFunc(string const& fname, string const& funcname
+                           ,int nvar,int npar)
+// Compilation et link dynamique de la fonction a fitter
+{
+if(nvar<1 || npar<1) return;
+if(mDlUFunc != NULL) {delete mDlUFunc;  mDlUFunc=NULL;}
+mFitFunc = NULL; mFitFuncDer = NULL; 
+mUFNVar= mUFNPar = 0; mNameFitFunc = "";
 
 // On compile le fichier C, on fabrique un .so et on l'ouvre
 mDlUFunc = PDynLinkMgr::BuildFromCFile(fname);
-if (mDlUFunc == NULL) {
-  cerr << "PIAFitter::LinkFitFunc() Erreur building .so " << endl;
-  return;
-  }
+if(mDlUFunc == NULL)
+  {cerr<<"PIAFitter::LinkFitFunc() Erreur building .so "<<endl; return;}
 
 // On recupere la fonction de fit
 mFitFunc = (DlUserFitFunc) mDlUFunc->GetFunction(funcname);
-if (mFitFunc == NULL) { // Probleme, on n'a pas trouve etc ... 
-  cerr << "PIAFitter::LinkFitFunc() Erreur linking function " << funcname << endl;
-  delete mDlUFunc;
-  mDlUFunc = NULL;
-  return;
-  }
-
-// On recupere la fonction de derives
+if(mFitFunc == NULL)  // Probleme, on n'a pas trouve etc ... 
+  {cerr<<"PIAFitter::LinkFitFunc() Erreur linking function"<<funcname<<endl;
+   delete mDlUFunc; mDlUFunc = NULL; return;}
+
+// On recupere la fonction des derivees
 string fnameder = funcname+"_der";
 mFitFuncDer = (DlUserFitFuncDer) mDlUFunc->GetFunction(fnameder);
-if (mFitFunc == NULL) { 
-  cout << "PIAFitter::LinkFitFunc() No derive for " << fnameder << endl;
-  }
-
+if(mFitFuncDer == NULL)
+  {cout<<"PIAFitter::LinkFitFunc() No derive for"<<fnameder<<endl;}
+
+// Variables et pointeurs definissant le link a la fonction utilisateur
 mNameFitFunc = funcname;
 mUFNVar = nvar;
 mUFNPar = npar;
-
-cout << "PIAFitter::LinkFitFunc() UserFitFunc" << funcname
-     << " NVar=" << nvar << " NPar=" << npar << endl;
-
-}
-/* --Methode-- */
-void PIAFitter::PrepareFitFuncCFile(string const & fname, string const & funcname, int nvar, int npar)
-{
-// A Faire 
+cout<<"PIAFitter::LinkFitFunc() UserFitFunc="<<mNameFitFunc
+    <<" NVar="<<mUFNVar<<" NPar="<<mUFNPar<<endl;
+
+return;
+}
+
+/* --Methode-- */
+void PIAFitter::PrepareFitFuncCFile(string const& fname, string const& funcname
+                                   , int nvar, int npar)
+// Pour ecrire un squelette des fichier C avec pour une fonction a fitter
+{
+if(fname.length()<=0 || funcname.length()<=0 || nvar<=0 || npar <=0) {
+  cerr<<"PIAFitter::PrepareFitFuncCFile: error "
+      <<" nvar="<<nvar<<" npar="<<npar<<endl
+      <<" file_name="<<fname<<" func_name="<<funcname<<endl
+      <<" ---- No File Created ! ----"<<endl;
+  return;
+}
+
+FILE* fip = fopen(fname.c_str(),"w");
+if(fip==NULL)
+  {cerr<<"PIAFitter::PrepareFitFuncCFile: error opening file for writing\n"
+       <<fname<<endl; return;}
+
+fprintf(fip,"#include <stdio.h>\n#include <stdlib.h>\n#include <math.h>\n\n");
+fprintf(fip,"/* - many functions can be written in this file: */\n");
+fprintf(fip,"/*   here is an exemple for creation of function %s */\n\n"
+       ,funcname.c_str());
+fprintf(fip,"double %s(double const* x,double const* p)\n",funcname.c_str());
+fprintf(fip,"/* Function : F(x[0-%d];p[0-%d]) */\n",nvar-1,npar-1);
+fprintf(fip,"/* variables  x1=x[0],x2=x[1],...,x%d=x[%d] */\n",nvar,nvar-1);
+fprintf(fip,"/* parameters p1=p[0],p2=p[1],...,p%d=p[%d] */\n",nvar,nvar-1);
+fprintf(fip,"{\n  val = F(x[];p[]);\n  return(val);\n}\n\n");
+string fder = funcname + "_der";
+fprintf(fip,"/* That function is optional */\n");
+fprintf(fip,"/*\n");
+fprintf(fip,"double %s(double const* x,double const* p,double* dp)\n",fder.c_str());
+fprintf(fip,"{\n");
+for(int i=0;i<npar;i++) fprintf(fip,"  dp[%d] = dF(x[];p[])/dp[%d]\n",i,i);
+fprintf(fip,"  val = F(x[];p[]);\n  return(val);\n}\n\n");
+fprintf(fip,"*/\n");
+
+fclose(fip);
 }
 
@@ -784,4 +836,20 @@
 // Execution des commandes de fit : "fit" et "fitw"
 {
+////// Les commandes pour creer les fonctions de fit utilisateur
+if(kw == "crfitfil") {
+  if (tokens.size() < 4)
+    {cout<<"Usage:crfitfil filename funcname nvar npar"<<endl;return(-1);}
+  int nvar = atoi(tokens[2].c_str()), npar = atoi(tokens[3].c_str());
+  PrepareFitFuncCFile(tokens[0],tokens[1],nvar,npar);
+  return(0);
+} else if (kw == "crfitfun") {
+  if (tokens.size() < 4)
+    {cout<<"Usage:crfitfun filename funcname nvar npar"<<endl;return(-1);}
+  int nvar = atoi(tokens[2].c_str()), npar = atoi(tokens[3].c_str());
+  LinkFitFunc(tokens[0],tokens[1],nvar,npar);
+  return(0);
+}
+
+////// Les commandes pour fitter
 if(tokens.size() < 2) {
   cout
@@ -825,13 +893,5 @@
   FWindFit = new PIAFitterWind(mApp,this);
   FWindFit->Show();
-} else if (kw == "crfitfun") {
-  if (tokens.size() < 4) { 
-    cout <<"Usage:crfitfun ... " << endl; return(0); }
-    LinkFitFunc(tokens[0], tokens[1], 1, 7);
-    double par[7]={1000,0.,0.,1.,1.,0.1,100.};
-    double x[2]={1.,1.};
-    cout<<"Salut:"<<mFitFunc(x,par)<<endl;
-}
-
+}
 
 return(0);
@@ -844,20 +904,16 @@
 /* --Methode-- */
 PIAFitterWind::PIAFitterWind(PIStdImgApp* par, PIAFitter* fiter)
- : PIWindow((PIMsgHandler*)par, "PIAFitter", PIWK_normal, 240, 240, 150, 150)
-{
-ReFillGData = false;
-saveI1 = saveI2 = saveJ1 = saveJ2 = 0;
-mDap = par;
-mFitter = fiter;
-string obj = mFitter->mNObj;
-string fun = mFitter->mFName;
+: PIWindow((PIMsgHandler*)par, "PIAFitter", PIWK_normal, 240, 240, 150, 150)
+, mDap(par), mFitter(fiter), ReFillGData(false)
+, saveI1(0), saveI2(0), saveJ1(0), saveJ2(0), ErrValue(1.)
+{
 int npar = mFitter->mNPar;
 
 // Alloc de la taille
-nlab = 20+npar;   lab = new PILabel*[nlab];    {for(int i=0;i<nlab;i++) lab[i]=NULL;}
-ntxt = 20+4*npar; txt = new PIText*[ntxt];     {for(int i=0;i<ntxt;i++) txt[i]=NULL;}
-nbut = 20;        but = new PIButton*[nbut];   {for(int i=0;i<nbut;i++) but[i]=NULL;}
-nckb = 20+npar;   ckb = new PICheckBox*[nckb]; {for(int i=0;i<nckb;i++) ckb[i]=NULL;}
-npom = 10;        pom = new PIOptMenu*[npom];  {for(int i=0;i<npom;i++) pom[i]=NULL;}
+nlab = 14+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;}
+nbut = 5;         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;}
+npom = 3;         pom = new PIOptMenu*[npom];  {for(int i=0;i<npom;i++) pom[i]=NULL;}
 
 // On definit la taille a partir de la taille par defaut des composantes
@@ -869,10 +925,15 @@
 
 int wszx = (5*bsx+5*spx)+spx;
-int wszy = 9*(bsy+spy)+npar*(bsy+spy)+spy;
+int wszy = 8*(bsy+spy)+npar*(bsy+spy)+spy;
 SetSize(wszx, wszy);
 int cpx,cpy;
 
 // new ligne
-cpx=spx; cpy=spy;
+cpx = spx; cpy = spy;
+lab[0] = new PILabel(this,mFitter->mNObj.c_str(),4*bsx,bsy,cpx,cpy);
+lab[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+// new ligne
+cpx = spx; cpy += bsy+spy;
 but[0] = new PIButton(this,"Fr.Last",111,bsx,bsy,cpx,cpy);
 but[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
@@ -880,5 +941,5 @@
 but[1] = new PIButton(this,"Default",222,bsx,bsy,cpx,cpy);
 but[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx+=bsx+spx;
+cpx += bsx+spx;
 ckb[0] = new PICheckBox(this,"Gen Fun",1001,bsx,bsy,cpx,cpy);
 ckb[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
@@ -888,141 +949,127 @@
 
 // new ligne
-cpx=spx; cpy += bsy+spy -spy;
-lab[0] = new PILabel(this,"- Center X -",2*bsx,bsy,cpx,cpy);
-lab[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx += 2*bsx+spx;
-lab[1] = new PILabel(this,"- Center Y -",2*bsx,bsy,cpx,cpy);
-lab[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-
-// new ligne
-cpx=spx; cpy += bsy+spy -spy;
-pom[0] = new PIOptMenu(this,"No",bsx,bsy,cpx,cpy);
-  pom[0]->AppendItem("No",2001);
-  pom[0]->AppendItem("Value",2002);
-  pom[0]->AppendItem("Auto",2003);
+cpx = spx; cpy += bsy+spy;
+pom[0] = new PIOptMenu(this,"Err def",1.5*bsx,bsy,cpx,cpy);
+  pom[0]->AppendItem("Err def",2101);
+  pom[0]->AppendItem("Err cste",2102);
+  pom[0]->AppendItem("Err sqrt",2103);
 pom[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx+=bsx+spx;
+cpx += int(1.5*bsx+spx);
 txt[0] = new PIText(this,"",bsx,bsy,cpx,cpy);
 txt[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx+=bsx+2*spx;
-pom[1] = new PIOptMenu(this,"No",bsx,bsy,cpx,cpy);
-  pom[1]->AppendItem("No",2011);
-  pom[1]->AppendItem("Value",2012);
-  pom[1]->AppendItem("Auto",2013);
-pom[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx+=bsx+spx;
+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);
 txt[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 
 // new ligne
-cpx=spx; cpy += bsy+spy;
-lab[2] = new PILabel(this,"Err cste",1.25*bsx,bsy,cpx,cpy);
+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+=1.25*bsx+spx;
+cpx += int(1.25*bsx+spx);
 txt[2] = new PIText(this,"",bsx,bsy,cpx,cpy);
 txt[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx+=bsx+2*spx;
-lab[3] = new PILabel(this,"sqrt",bsx,bsy,cpx,cpy);
+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+=bsx+spx;
+cpx += bsx+spx;
 txt[3] = new PIText(this,"",bsx,bsy,cpx,cpy);
 txt[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 
 // new ligne
-cpx=spx; cpy += bsy+spy;
-lab[4] = new PILabel(this,"Stop Xi2",1.25*bsx,bsy,cpx,cpy);
+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);
-cpx+=1.25*bsx+spx;
-txt[4] = new PIText(this,"",bsx,bsy,cpx,cpy);
+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+=bsx+spx;
-lab[5] = new PILabel(this,"Iter",bsx, bsy, cpx, cpy);
+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+=bsx+spx;
-txt[5] = new PIText(this,"",bsx,bsy,cpx,cpy);
-txt[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);
+txt[7] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
+txt[7]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 
 // new ligne
-cpx=spx; cpy += bsy+spy;
-lab[6] = new PILabel(this,"Print",bsx,bsy,cpx,cpy);
+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);
-cpx+=bsx+spx;
-txt[6] = new PIText(this,"",bsx/2,bsy,cpx,cpy);
-txt[6]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx+=bsx/2+spx;
-lab[7] = new PILabel(this,"Debug",bsx,bsy,cpx,cpy);
-lab[7]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx+=bsx+spx;
-txt[7] = new PIText(this,"",bsx/2,bsy,cpx,cpy);
-txt[7]->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);
+  pom[1]->AppendItem("X.No",2001);
+  pom[1]->AppendItem("X.Value",2002);
+  pom[1]->AppendItem("X.Auto",2003);
+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);
+cpx += bsx+spx;
+pom[2] = new PIOptMenu(this,"Y.No",1.25*bsx,bsy,cpx,cpy);
+  pom[2]->AppendItem("Y.No",2011);
+  pom[2]->AppendItem("Y.Value",2012);
+  pom[2]->AppendItem("Y.Auto",2013);
+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);
 
 // new ligne
-cpx=spx; cpy += bsy+spy;
-lab[8] = new PILabel(this,"Range X",bsx,bsy,cpx,cpy);
-lab[8]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx+=bsx+spx;
-txt[8] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
-txt[8]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx+=0.75*bsx+spx;
-txt[9] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
-txt[9]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx+=0.75*bsx+spx;
-lab[9] = new PILabel(this,"Y",bsx/2,bsy,cpx,cpy);
-lab[9]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx+=bsx/2+spx;
-txt[10] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
-txt[10]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx+=0.75*bsx+spx;
-txt[11] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
-txt[11]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-
-// new ligne
-cpx=spx; cpy+=bsy+spy;
+cpx = spx; cpy += bsy+spy;
 but[2] = new PIButton(this, "Dismiss",777,bsx,bsy,cpx,cpy);
 but[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 cpx += bsx+spx;
-but[3] = new PIButton(this, "Refesh",666,bsx,bsy,cpx,cpy);
+but[3] = new PIButton(this, "Check",666,bsx,bsy,cpx,cpy);
 but[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 cpx += bsx+spx;
 but[4] = new PIButton(this, "Fit",333,bsx,bsy,cpx,cpy);
 but[4]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx+=bsx+spx;
-lab[10] = new PILabel(this,fun.c_str(),bsx/2,bsy,cpx,cpy);
+cpx += bsx+spx;
+lab[7] = new PILabel(this,mFitter->mFName.c_str(),2*bsx,bsy,cpx,cpy);
+lab[7]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+
+// new ligne
+cpx = spx; cpy += bsy+spy;
+lab[8] = new PILabel(this,"Par",bsx/2,bsy,cpx,cpy);
+lab[8]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(bsx/2.+spx);
+lab[9] = new PILabel(this,"Fx",bsx/3,bsy,cpx,cpy);
+lab[9]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += int(bsx/3.+spx);
+lab[10] = new PILabel(this,"Init",bsx,bsy,cpx,cpy);
 lab[10]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+lab[11] = new PILabel(this,"Step",bsx,bsy,cpx,cpy);
+lab[11]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+lab[12] = new PILabel(this,"Min",bsx,bsy,cpx,cpy);
+lab[12]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+cpx += bsx+spx;
+lab[13] = new PILabel(this,"Max",bsx,bsy,cpx,cpy);
+lab[13]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 
 // new lines: Parametres (npar lignes)
-cpx=spx; cpy+=bsy+spy;
-lab[11] = new PILabel(this,"Par",bsx/2,bsy,cpx,cpy);
-lab[11]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx+=bsx/2+spx;
-lab[12] = new PILabel(this,"F",bsx/3,bsy,cpx,cpy);
-lab[12]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx+=bsx/3+spx;
-lab[13] = new PILabel(this,"Init",bsx,bsy,cpx,cpy);
-lab[13]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx+=bsx+spx;
-lab[14] = new PILabel(this,"Step",bsx,bsy,cpx,cpy);
-lab[14]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx+=bsx+spx;
-lab[15] = new PILabel(this,"Min",bsx,bsy,cpx,cpy);
-lab[15]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-cpx+=bsx+spx;
-lab[16] = new PILabel(this,"Max",bsx,bsy,cpx,cpy);
-lab[16]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
 if(npar>0) {
   for(int i=0;i<npar;i++) {
-    cpx=spx; cpy+=bsy+spy;
+    cpx = spx; cpy += bsy+spy;
     char str[8]; sprintf(str,"P%d",i);
-    lab[20+i] = new PILabel(this,str,bsx/2,bsy,cpx,cpy);
-    lab[20+i]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-    cpx+=bsx/2+spx;
+    lab[14+i] = new PILabel(this,str,bsx/2,bsy,cpx,cpy);
+    lab[14+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!)
-    ckb[20+i] = new PICheckBox(this,"",1500+i,bsx/3,bsy,cpx,cpy);
-    ckb[20+i]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-    cpx+=bsx/3+spx;
+    ckb[2+i] = new PICheckBox(this,"",1500+i,bsx/3,bsy,cpx,cpy+bsy/2);
+    ckb[2+i]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
+    cpx+=int(bsx/3.+spx);
     for(int j=0;j<4;j++) {
-      txt[20+4*i+j] = new PIText(this,"",bsx,bsy,cpx,cpy);
-      txt[20+4*i+j]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
-      cpx+=bsx+spx;
+      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);
+      cpx += bsx+spx;
     }
   }
@@ -1067,26 +1114,24 @@
 ckb[1]->SetState(mFitter->mOpt.okres);
 if(npar>0)
-  for(int i=0;i<npar;i++) ckb[20+i]->SetState((mFitter->mFix(i)>=1.)?true:false);
+  for(int i=0;i<npar;i++) ckb[2+i]->SetState((mFitter->mFix(i)>=1.)?true:false);
 
 // Les champs textes
 char str[128]; string dum;
-sprintf(str,"%f",mFitter->mOpt.xc);    dum=str; txt[0]->SetText(dum);
-sprintf(str,"%f",mFitter->mOpt.yc);    dum=str; txt[1]->SetText(dum);
-sprintf(str,"%f",mFitter->mOpt.err_e); dum=str; txt[2]->SetText(dum);
-sprintf(str,"%f",mFitter->mOpt.err_E); dum=str; txt[3]->SetText(dum);
-sprintf(str,"%f",mFitter->mOpt.stc2);  dum=str; txt[4]->SetText(dum);
-sprintf(str,"%d",mFitter->mOpt.nstep); dum=str; txt[5]->SetText(dum);
-sprintf(str,"%d",mFitter->mOpt.lp);    dum=str; txt[6]->SetText(dum);
-sprintf(str,"%d",mFitter->mOpt.lpg);   dum=str; txt[7]->SetText(dum);
-sprintf(str,"%d",mFitter->mOpt.i1);    dum=str; txt[8]->SetText(dum);
-sprintf(str,"%d",mFitter->mOpt.i2);    dum=str; txt[9]->SetText(dum);
-sprintf(str,"%d",mFitter->mOpt.j1);    dum=str; txt[10]->SetText(dum);
-sprintf(str,"%d",mFitter->mOpt.j2);    dum=str; txt[11]->SetText(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);
 if(npar>0) {
   for(int i=0;i<npar;i++) {
-    sprintf(str,"%f",mFitter->mPar(i));  dum=str; txt[20+4*i+0]->SetText(dum);
-    sprintf(str,"%f",mFitter->mStep(i)); dum=str; txt[20+4*i+1]->SetText(dum);
-    sprintf(str,"%f",mFitter->mMin(i));  dum=str; txt[20+4*i+2]->SetText(dum);
-    sprintf(str,"%f",mFitter->mMax(i));  dum=str; txt[20+4*i+3]->SetText(dum);
+    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);
   }
 }
@@ -1100,4 +1145,13 @@
 int lp = (mFitter->mOpt.lp>2)?1:0;;
 int npar = mFitter->mNPar;
+
+// Decodage des messages, init et dismiss
+msg = UserMsg(msg);
+if(msg ==777) {
+  if(lp) cout<<"Dismiss"<<endl;
+  //mDap->SetReady();
+  Hide();
+  return;
+}
 
 // L'objet existe t-il encore?
@@ -1111,65 +1165,57 @@
 // On recupere les champs textes
 string dum; char str[128];
+// Attention gestion du type d'erreur
 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;
+dum=txt[1]->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',' ');
+  sscanf(str,"%lf",&(mFitter->mOpt.stc2));
+dum=txt[3]->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',' ');
+  sscanf(str,"%d",&(mFitter->mOpt.i1));
+dum=txt[5]->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',' ');
+  sscanf(str,"%d",&(mFitter->mOpt.j1));
+dum=txt[7]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+  sscanf(str,"%d",&(mFitter->mOpt.j2));
+  if(saveI1!=mFitter->mOpt.i1 || saveI2!=mFitter->mOpt.i2 ||
+     saveJ1!=mFitter->mOpt.j1 || saveJ2!=mFitter->mOpt.j2 ) {
+    if(lp)
+      cout<<"Range changed: I("<<saveI1<<","<<saveI2
+          <<") -> I("<<mFitter->mOpt.i1<<","<<mFitter->mOpt.i2
+          <<")  ou   J("<<saveJ1<<","<<saveJ2
+          <<") -> J("<<mFitter->mOpt.j1<<","<<mFitter->mOpt.j2
+          <<")"<<endl;
+    ReFillGData = true;
+    saveI1=mFitter->mOpt.i1; saveI2=mFitter->mOpt.i2;
+    saveJ1=mFitter->mOpt.j1; saveJ2=mFitter->mOpt.j2;
+  }
+dum=txt[8]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
   sscanf(str,"%lf",&(mFitter->mOpt.xc));
-dum=txt[1]->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.yc));
-dum=txt[2]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
-  sscanf(str,"%lf",&(mFitter->mOpt.err_e));
-dum=txt[3]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
-  sscanf(str,"%lf",&(mFitter->mOpt.err_E));
-dum=txt[4]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
-  sscanf(str,"%lf",&(mFitter->mOpt.stc2));
-dum=txt[5]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
-  sscanf(str,"%d",&(mFitter->mOpt.nstep));
-dum=txt[6]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
-  sscanf(str,"%d",&(mFitter->mOpt.lp));
-dum=txt[7]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
-  sscanf(str,"%d",&(mFitter->mOpt.lpg));
-dum=txt[8]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
-// Attention si les valeurs de mOpt.i1/.i2/.j1/.j2 ont ete changees
-  sscanf(str,"%d",&(mFitter->mOpt.i1));
-dum=txt[9]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
-  sscanf(str,"%d",&(mFitter->mOpt.i2));
-dum=txt[10]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
-  sscanf(str,"%d",&(mFitter->mOpt.j1));
-dum=txt[11]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
-  sscanf(str,"%d",&(mFitter->mOpt.j2));
-if(saveI1!=mFitter->mOpt.i1 || saveI2!=mFitter->mOpt.i2 ||
-   saveJ1!=mFitter->mOpt.j1 || saveJ2!=mFitter->mOpt.j2 ) {
-  if(lp)
-    cout<<"Range changed: I("<<saveI1<<","<<saveI2
-        <<") -> I("<<mFitter->mOpt.i1<<","<<mFitter->mOpt.i2
-        <<")  ou   J("<<saveJ1<<","<<saveJ2
-        <<") -> J("<<mFitter->mOpt.j1<<","<<mFitter->mOpt.j2
-        <<")"<<endl;
-  ReFillGData = true;
-  saveI1=mFitter->mOpt.i1; saveI2=mFitter->mOpt.i2;
-  saveJ1=mFitter->mOpt.j1; saveJ2=mFitter->mOpt.j2;
-}
 
 if(npar>0) {
   for(int i=0;i<npar;i++) {
-    dum=txt[20+4*i+0]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+    dum=txt[10+4*i+0]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
       sscanf(str,"%lf",&(mFitter->mPar(i)));
-    dum=txt[20+4*i+1]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+    dum=txt[10+4*i+1]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
       sscanf(str,"%lf",&(mFitter->mStep(i)));
-    dum=txt[20+4*i+2]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+    dum=txt[10+4*i+2]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
       sscanf(str,"%lf",&(mFitter->mMin(i)));
-    dum=txt[20+4*i+3]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
+    dum=txt[10+4*i+3]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
       sscanf(str,"%lf",&(mFitter->mMax(i)));
   }
 }
 
-// Decodage des messages
-msg = UserMsg(msg);
-if(msg ==777) {
-  if(lp) cout<<"Dismiss"<<endl;
-  //mDap->SetReady();
-  Hide();
-  return;
-}
-else if(msg ==666) {
-  if(lp) cout<<"Refresh"<<endl;
+// Decodage des messages, suite
+if(msg ==666) {
+  if(lp) cout<<"Check"<<endl;
   mFitter->CheckOptions();
   if(ReFillGData) mFitter->FillGData();
@@ -1216,4 +1262,13 @@
   }
 }
+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;
+  ReFillGData = true;
+}
 else if(2001<=msg && msg<=2003) {
   mFitter->mOpt.polcx = msg-2001;
@@ -1230,8 +1285,8 @@
 else if(msg>=1500 && msg<2000) {
   int ip = msg-1500;
-  if(ckb[20+ip]->GetState()) {
+  if(ckb[2+ip]->GetState()) {
     if(lp) cout<<"Fix Param "<<ip<<endl;
     mFitter->mFix(ip) = 1.001;
-  } else if(!ckb[20+ip]->GetState()) {
+  } else if(!ckb[2+ip]->GetState()) {
     if(lp) cout<<"Not Fix Param "<<ip<<endl;
     mFitter->mFix(ip) = 0.;
Index: trunk/SophyaPI/PIext/piafitting.h
===================================================================
--- trunk/SophyaPI/PIext/piafitting.h	(revision 384)
+++ trunk/SophyaPI/PIext/piafitting.h	(revision 385)
@@ -24,9 +24,7 @@
 class PIStdImgApp;
 class PIAFitterWind;
-class GeneralFunction;
+class GeneralFunction; class GeneralFunc; class GeneralFit;
 class GeneralFitData;
-class GeneralFit;
-class Histo;
-class Matrix; class Histo2D; class RzImage;
+class Histo; class Matrix; class Histo2D; class RzImage;
 
 class PIAFitter : public CmdExecutor {
@@ -35,6 +33,8 @@
   virtual ~PIAFitter();
   virtual int Execute(string& keyw, vector<string>& args);
-  virtual void  LinkFitFunc(string const & fname, string const & funcname, int nvar, int npar);
-  virtual void  PrepareFitFuncCFile(string const & fname, string const & funcname, int nvar, int npar);
+  virtual void LinkFitFunc(string const& fname, string const& funcname
+                          ,int nvar,int npar);
+  virtual void PrepareFitFuncCFile(string const& fname, string const& funcname
+                                  ,int nvar,int npar);
 
 friend class PIAFitterWind;
@@ -68,8 +68,10 @@
 void LinFit(void);
 
+// Graphique
 PIStdImgApp* mApp; // Do not delete
-PIAFitterWind* FWindFit;
+PIAFitterWind* FWindFit; // Fenetre de config interactive
+// Objet a fitter
 string mNObj; AnyDataObj* mObj; // Do not delete
-GeneralFunction* mFunc; string mFName;
+// Structure de data pour le fit, parametres et options
 GeneralFitData* mGData;
 int mNPar,mNVar,mNBinX,mNBinY,mNData;
@@ -79,10 +81,12 @@
 DFOPTIONS mOpt;
 DFOPTIONS mOptSave;
-// Objets a fitter
+// Possibles objets a fitter
 Vector* mV; Histo* mH; // Do not delete
 Matrix* mM; Histo2D* mH2; RzImage* mIm; // Do not delete
 GeneralFitData* mG; // Do not delete
-
-// Gestion de fonction de fit user
+// Gestion des fonctions de fit predefinies
+GeneralFunction* mFunction; string mFName;
+// Gestion de fonction de fit definie par l'utilisateur
+GeneralFunc* mFunc;
 PDynLinkMgr* mDlUFunc;
 string mNameFitFunc;
Index: trunk/SophyaPI/PIext/userfitfunex.c
===================================================================
--- trunk/SophyaPI/PIext/userfitfunex.c	(revision 385)
+++ trunk/SophyaPI/PIext/userfitfunex.c	(revision 385)
@@ -0,0 +1,72 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+/********************************************************************/
+/* fonction de fit "f(x;h,x0,sig,c) = h*exp(-0.5*((x-x0)/sig)^2)+c" */
+/* avec nvar=1 npar=4                                               */
+/*      x = x[0]                                                    */
+/*      p[0]=h, p[1]=x0, p[2]=sig, p[3]=c                           */
+/********************************************************************/
+double gauss1(double const* x,double const* p)
+{
+double xc;
+xc = (x[0]-p[1])/p[2]; xc *= -xc/2.;
+return((xc>=-80.) ? p[0]*exp(xc)+p[3] : p[3]);
+}
+
+/* la definition de cette fonction n'est pas obligatoire */
+/* dp[0] = df(x;h,x0,sig,c)/dh, dp[1] = etc...           */
+double gauss1_der(double const* x,double const* p,double* dp)
+{
+double xc,xc2,e,f;
+xc = (x[0]-p[1])/p[2];
+xc2 = xc*xc;
+e = -xc2/2.;
+if(e>=-80.) e = exp(e); else e = 0.;
+f = p[0]*e;
+dp[0] = e;
+dp[1] = xc  / p[2] *f;
+dp[2] = xc2 / p[2] *f;
+dp[3] = 1.;
+return(f+p[3]);
+}
+
+/********************************************************/
+/* fonction de fit gaussienne 2D avec correlation       */
+/* f(x,y;h,x0,y0,sx,sy,rho,c) =                         */
+/*   h * exp{ -0.5*[ (x-x0)^2/sx^2 + (y-y0)^2/s^2       */
+/*                   -2*rho*(x-x0)*(y-y0)/(sx*sy) ]}    */
+/* avec nvar=2 npar=7                                   */
+/*      x = x[0] et y=x[2]                              */
+/*      p[0]=h, p[1]=x0, p[2]=y0                        */
+/*      p[3]=sx, p[4]=sy, p[5]=rho, p[6]=fond           */
+/********************************************************/
+double gauss2(double const* x,double const* p)
+{
+double ax,ay,a;
+ax = (x[0]-p[1])/p[3];
+ay = (x[1]-p[2])/p[4];
+a  = -(ax*ax+ay*ay-2.*p[5]*ax*ay)/2.;
+return((a>=-80.) ? p[0]*exp(a)+p[6] : p[6]);
+}
+
+/* la definition de cette fonction n'est pas obligatoire */
+/* dp[0] = f(x,y;h,x0,y0,sx,sy,rho,c)/dh, dp[1] = etc... */
+double gauss2_der(double const* x,double const* p,double* dp)
+{
+double ax,ay,a,p0ea;
+ax   = (x[0]-p[1])/p[3];
+ay   = (x[1]-p[2])/p[4];
+a    = -(ax*ax+ay*ay-2.*p[5]*ax*ay)/2.;
+p0ea = (a>=-80.) ? exp(a) : 0.;
+dp[0] = p0ea;
+  p0ea *= p[0];
+dp[1] = (ax-p[5]*ay)/p[3] *p0ea;
+dp[2] = (ay-p[5]*ax)/p[4] *p0ea;
+dp[3] = ax*dp[1];
+dp[4] = ay*dp[2];
+dp[5] = ax*ay *p0ea;
+dp[6] = 1.;
+return(p0ea+p[6]);
+}
