source: Sophya/trunk/SophyaPI/PIext/piafitting.cc@ 384

Last change on this file since 384 was 384, checked in by ercodmgr, 26 years ago

Diverses modifs + Fonc. Link Dyn pour fitting - Reza+cmv 12/8/99

File size: 42.3 KB
Line 
1//CMVBUG reste pb suivant sous Linux-egcs (OSF1-cxx c'est ok):
2//openppf cmvwppf.ppf
3//fitw h1g g2 p:4500,45,10,900
4//delobjs h1g
5//clic sur FIT -> OK
6//clic sur FIT 2sd fois -> core dump!!!
7//
8//
9#include <stdio.h>
10#include <stdlib.h>
11#include <ctype.h>
12
13#include <iostream.h>
14
15#include <typeinfo>
16
17#include "piafitting.h"
18#include "strutil.h"
19
20#include "generalfit.h"
21
22#include "fct1dfit.h"
23#include "fct2dfit.h"
24
25#include "matrix.h"
26#include "cvector.h"
27#include "ntuple.h"
28#include "cimage.h"
29
30#include "histos.h"
31#include "histos2.h"
32#include "ntuple.h"
33#include "hisprof.h"
34
35#include "nobjmgr.h"
36#include "pistdimgapp.h"
37
38////////////////////////////////////////////////////////////////////
39////---------- Classe de fenetre de fit interactive ------------////
40////////////////////////////////////////////////////////////////////
41class PIAFitterWind : public PIWindow {
42public :
43 PIAFitterWind(PIStdImgApp* par, PIAFitter* fiter);
44 virtual ~PIAFitterWind();
45 virtual void Show();
46 virtual void Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
47 void SetState(void);
48protected :
49 PIStdImgApp* mDap;
50 PIAFitter* mFitter;
51 PILabel** lab; int nlab;
52 PIText** txt; int ntxt;
53 PIButton** but; int nbut;
54 PICheckBox** ckb; int nckb;
55 PIOptMenu** pom; int npom;
56 bool ReFillGData;
57 int saveI1,saveI2, saveJ1, saveJ2;
58};
59
60////////////////////////////////////////////////////////////////////////
61//| --------------- Fit Lineaire a 1 et 2 dimensions ---------------
62//| Syntaxe:
63//| fitlin nom pnn [o:.aa,bb,cc, o;dd,ee,ff o:gg,hh,jj,kk etc...]
64//| avec:
65//| nom : cf commentaire ordre "fit"
66//| pnn : fit polynome degre nn avec classe Poly (lineaire) 1D ou 2D
67//| o:aa,...,bb : cf commentaires ordre "fit"
68//|
69////////////////////////////////////////////////////////////////////////
70//| --------------- Fit d'objets a 1 et 2 dimensions ---------------
71//| avec interface d'aide graphique
72//| Syntaxe:
73//| fitw nom func
74//| [p:p1,p2,...,pn s:s1,s2,...,sn m:m1,m2,...,mn M:M1,mM2,...,Mn f:f1,...,fn]
75//| [o:.aa,bb,cc, o;dd,ee,ff o:gg,hh,jj,kk etc...]
76//| cf commentaire ordre "fit"
77//|
78////////////////////////////////////////////////////////////////////////
79//| --------------- Fit d'objets a 1 et 2 dimensions ---------------
80//| Syntaxe:
81//| fit nom func
82//| [p:p1,p2,...,pn s:s1,s2,...,sn m:m1,m2,...,mn M:M1,mM2,...,Mn f:f1,...,fn]
83//| [o:.aa,bb,cc, o;dd,ee,ff o:gg,hh,jj,kk etc...]
84//|----- OBJET -----
85//| nom : nom de l'objet qui peut etre:
86//| fit-1D: Vector,Histo1D,HProf ou GeneraFitData(1D)
87//| fit-2D: Matrix,Histo2D,Image<T> ou GeneraFitData(2D)
88//|
89//|----- FUNCTION -----
90//| func : pnn : fit polynome degre nn avec GeneralFit (non-lineaire) 1D ou 2D
91//| : gnn : fit gaussienne (hauteur) + polynome de degre nn 1D
92//| : g : fit gaussienne (hauteur) 1D
93//| : enn : fit exponentielle + polynome de degre nn 1D
94//| : e : fit exponentielle 1D
95//| : Gnn : fit gaussienne (volume) + polynome de degre nn 1D
96//| : G : fit gaussienne (volume) 1D
97//| : : fit gaussienne+fond (volume) 2D
98//| : Gi : fit gaussienne+fond integree (volume) 2D
99//| : d : fit DL de gaussienne+fond (volume) 2D
100//| : di : fit DL de gaussienne+fond integree (volume) 2D
101//| : D : fit DL de gaussienne+fond avec coeff variable p6 (volume) 2D
102//| : Di : fit DL de gaussienne+fond integree avec coeff variable p6 (volume) 2D
103//| : M : fit Moffat+fond (expos=p6) (volume) 2D
104//| : Mi : fit Moffat+fond integree (expos=p6) (volume) 2D
105//|
106//|----- INIT PARAMETRES ET ETAT DU FIT -----
107//| p : p1,...,pn : valeur d'initialisation des parametres (def=0)
108//| s : s1,...,sn : valeur des steps de depart (def=1)
109//| m : m1,...,mn : valeur des minima (def=1)
110//| M : M1,...,Mn : valeur des maxima (def=-1) (max<=min : pas de limite)
111//| f : f1,...,fn : si >=1 parametre fixe sinon libre (def=0)
112//| - Remarque: si pi,si,mi ou Mi = '!' la valeur correspondante n'est pas changee
113//|
114//|----- OPTIONS -----
115//| o : options "o:Eaa.b,eaa.b,f,r,caa.b,Xaa.b"
116//| F : initialisation a partir des resultats et de l'etat du fit precedent
117//| (option non prioritaire sur les definitions p:,s:,m:,M:,f:o:)
118//| f : generation d'un Objet identique contenant la fonction fittee
119//| r : generation d'un Objet identique contenant les residus
120//| Xaa.b : aa.b valeur du DXi2 d'arret (def=1.e-3)
121//| Naa : aa nombre maximum d'iterations (def=100)
122//| la : niveau "a" de print: a=niveau de print Fit1/2D
123//| da : niveau "a" de debug: a=niveau de GeneralFit
124//| Ii1/i2 : numeros des bins X de l'histos utilises pour le fit [i1,i2]
125//|2D Jj1/j2 : numeros des bins Y de l'histos utilises pour le fit [j1,j2]
126//| - L'erreur est celle associee a l'objet (si elle existe),
127//| elle est mise a 1 sinon, sauf si E... ou e... est precise:
128//| Eaa.b : si |val|>=1 erreur = aa.b*sqrt(|val|)
129//| si |val|<1 erreur = aa.b
130//| si aa.b <=0 alors aa.b=1.0
131//| E seul est equivalent a E1.0
132//| eaa.b : erreur = aa.b
133//| si aa.b <=0 alors aa.b=1.0
134//| e seul est equivalent a e1.0
135//| xaa.b : demande de centrage: on fit x-aa.b au lieu de x)
136//| x : demande de centrage: on fit x-xc au lieu de x
137//| avec xc=abscisse du milieu de l'histogramme
138//| Actif pour exp+poly 1D, poly 1D
139//| Pour gauss+poly 1D, xc est le centre de la gaussienne.
140//|2D yaa.b et y : idem "xaa.b et x" mais pour y
141////////////////////////////////////////////////////////////////////////
142
143/* --Methode-- */
144PIAFitter::PIAFitter(PIACmd *piac, PIStdImgApp* app)
145: mApp(app), FWindFit(NULL)
146, mNObj(""), mObj(NULL), mFunc(NULL), mFName(""), mGData(NULL)
147, mNPar(0), mNVar(0), mNBinX(0), mNBinY(0), mNData(0)
148, mPar(1), mStep(1), mMin(1), mMax(1), mFix(1)
149, mParSave(1), mStepSave(1), mMinSave(1), mMaxSave(1), mFixSave(1)
150, mFit(NULL)
151, mV(NULL), mH(NULL), mM(NULL), mH2(NULL), mIm(NULL), mG(NULL)
152, mDlUFunc(NULL), mNameFitFunc(""), mFitFunc(NULL), mFitFuncDer(NULL)
153, mUFNVar(0), mUFNPar(0)
154{
155// Init et Set des options
156mPar=0.; mStep=1.; mMin=1.; mMax=-1.; mFix=0.;
157mParSave=0.; mStepSave=1.; mMinSave=1.; mMaxSave=-1.; mFixSave=0.;
158ResetOptions();
159mOptSave = mOpt;
160
161// enregistrement des ordres de fit
162string kw, usage;
163
164kw = "fit";
165usage = "Fitting function to DataObjects (Histo, Histo2D, Vector, ...)";
166usage += "\n Usage: fit nomobj func [Options]";
167usage += "\n [p:p1,...,pn s:s1,...,sn m:m1,...,mn M:M1,...,Mn o:... o:...]";
168piac->RegisterCommand(kw,usage,this,"Fitting");
169
170kw = "fitw";
171usage = "Fitting function to DataObjects with Interactive Window Help";
172usage += "\n Usage: fitw nomobj func [Options]";
173usage += "\n [p:p1,...,pn s:s1,...,sn m:m1,...,mn M:M1,...,Mn o:... o:...]";
174piac->RegisterCommand(kw,usage,this,"Fitting");
175
176kw = "fitlin";
177usage = "Linear Fitting of Polynoms to DataObjects";
178usage += "\n Usage: fitlin nomobj func [o:... o:...]";
179piac->RegisterCommand(kw,usage,this,"Fitting");
180
181kw = "crfitfun";
182usage = "Creation de user function ";
183usage += "\n Usage: crfitfun file func nvar npar";
184piac->RegisterCommand(kw,usage,this,"Fitting");
185}
186
187/* --Methode-- */
188PIAFitter::~PIAFitter()
189{
190if(mFit != NULL) {delete mFit; mFit=NULL;}
191if(mFunc != NULL) {delete mFunc; mFunc=NULL;}
192if(mGData != NULL) {delete mGData; mGData=NULL;}
193if(FWindFit != NULL) {delete FWindFit; FWindFit=NULL;}
194if (mDlUFunc != NULL) delete mDlUFunc;
195}
196
197/* --Methode-- */
198void PIAFitter::ResetDPointer(void)
199// Reset des pointeurs sur les donnees
200{
201mNObj = ""; mObj=NULL;
202mV=NULL; mH=NULL; mM=NULL; mH2=NULL; mIm=NULL; mG=NULL;
203}
204
205/* --Methode-- */
206void PIAFitter::ResetOptions(void)
207// Reset des options
208{
209mOpt.okres = mOpt.okfun = false;
210mOpt.polcx = mOpt.polcy = 0;
211mOpt.xc = mOpt.yc = 0.;
212mOpt.stc2 = 1.e-3;
213mOpt.nstep = 100;
214mOpt.err_e = mOpt.err_E = -1.;
215mOpt.lp = 1; mOpt.lpg = 0;
216mOpt.i1 = mOpt.j1 = mOpt.i2 = mOpt.j2 = -1;
217mOpt.fromlastfit = false;
218}
219
220/* --Methode-- */
221void PIAFitter::DecodeOptions(string opt)
222// Decodage des options a partir des chaines de caracteres
223{
224ResetOptions();
225if(opt.length()<=0) return;
226
227size_t p,q; string dum;
228opt = "," + opt + ",";
229
230if(strstr(opt.c_str(),",F,")) // init options/param a partir du fit precedent
231 {mOpt = mOptSave; mOpt.fromlastfit = true;}
232if(strstr(opt.c_str(),",r,")) mOpt.okres = true; // residus
233if(strstr(opt.c_str(),",f,")) mOpt.okfun = true; // fonction fittee
234if(strstr(opt.c_str(),",x")) { // Demande de centrage (fit X=x-xc)
235 mOpt.polcx = 2; // Le centrage est calcule automatiquement
236 p = opt.find(",x"); q = opt.find_first_of(',',p+1);
237 dum = opt.substr(p,q-p);
238 if(dum.length()>2) {
239 sscanf(dum.c_str(),",x%lf",&mOpt.xc);
240 mOpt.polcx = 1; // Le centrage est fixe par la valeur lue
241 }
242}
243if(strstr(opt.c_str(),",y")) { // Demande de centrage (fit Y=y-yc)
244 mOpt.polcy = 2; // Le centrage est calcule automatiquement
245 p = opt.find(",y"); q = opt.find_first_of(',',p+1);
246 dum = opt.substr(p,q-p);
247 if(dum.length()>2) {
248 sscanf(dum.c_str(),",y%lf",&mOpt.yc);
249 mOpt.polcy = 1; // Le centrage est fixe par la valeur lue
250 }
251}
252if(strstr(opt.c_str(),",E")) { // Erreurs imposees a "sqrt(val)" ou "aa.b*sqrt(val)"
253 p = opt.find(",E"); q = opt.find_first_of(',',p+1);
254 dum = opt.substr(p,q-p);
255 if(dum.length()>2) sscanf(dum.c_str(),",E%lf",&mOpt.err_E);
256 if(mOpt.err_E<=0.) mOpt.err_E = 1.; //mOpt.err_e=-1.;
257}
258if(strstr(opt.c_str(),",e")) { // Erreurs imposees a "1" ou "aa.b"
259 p = opt.find(",e"); q = opt.find_first_of(',',p+1);
260 dum = opt.substr(p,q-p);
261 if(dum.length()>2) sscanf(dum.c_str(),",e%lf",&mOpt.err_e);
262 if(mOpt.err_e<=0.) mOpt.err_e = 1.; //mOpt.err_E=-1.;
263}
264if(strstr(opt.c_str(),",X")) { // Valeur du StopChi2
265 p = opt.find(",X"); q = opt.find_first_of(',',p+1);
266 dum = opt.substr(p,q-p);
267 if(dum.length()>2) sscanf(dum.c_str(),",X%lf",&mOpt.stc2);
268}
269if(strstr(opt.c_str(),",N")) { // Nombre maximum d'iterations
270 p = opt.find(",N"); q = opt.find_first_of(',',p+1);
271 dum = opt.substr(p,q-p);
272 if(dum.length()>2) sscanf(dum.c_str(),",N%d",&mOpt.nstep);
273}
274if(strstr(opt.c_str(),",l")) { // niveau de print
275 p = opt.find(",l"); q = opt.find_first_of(',',p+1);
276 dum = opt.substr(p,q-p);
277 if(dum.length()>2) sscanf(dum.c_str(),",l%d",&mOpt.lp);
278}
279if(strstr(opt.c_str(),",d")) { // niveau de debug du fit
280 p = opt.find(",d"); q = opt.find_first_of(',',p+1);
281 dum = opt.substr(p,q-p);
282 if(dum.length()>2) sscanf(dum.c_str(),",d%d",&mOpt.lpg);
283}
284if(strstr(opt.c_str(),",I")) { // intervalle de fit selon X
285 p = opt.find(",I"); q = opt.find_first_of(',',p+1);
286 dum = opt.substr(p,q-p);
287 if(dum.length()>2) sscanf(dum.c_str(),",I%d/%d",&mOpt.i1,&mOpt.i2);
288}
289if(strstr(opt.c_str(),",J")) { // intervalle de fit selon Y
290 p = opt.find(",J"); q = opt.find_first_of(',',p+1);
291 dum = opt.substr(p,q-p);
292 if(dum.length()>2) sscanf(dum.c_str(),",J%d/%d",&mOpt.j1,&mOpt.j2);
293}
294
295return;
296}
297
298/* --Methode-- */
299void PIAFitter::DecodeObject(string obj)
300// Decodage de l'objet a fitter
301{
302NamedObjMgr omg;
303AnyDataObj* mobj = omg.GetObj(obj);
304if(mobj == NULL)
305 {cout<<"PIAFitter::DecodeObject Error , Pas d'objet de nom "<<obj<<endl;
306 return;}
307
308// Reset
309ResetDPointer();
310mNVar = mNBinX = mNBinY = mNData = 0;
311
312mObj = mobj; mNObj = obj;
313string ctyp = typeid(*mObj).name();
314
315// 1D
316if (typeid(*mObj) == typeid(Vector)) {
317 mNVar = 1;
318 mV = (Vector*) mObj; mNBinX = mV->NElts(); mNBinY = 1;
319 }
320else if ( (typeid(*mObj) == typeid(HProf)) || (typeid(*mObj) == typeid(Histo)) ) {
321 mNVar = 1;
322 mH = (Histo*) mObj; mNBinX = mH->NBins(); mNBinY = 1;
323 }
324// 2D
325else if (typeid(*mObj) == typeid(Matrix)) {
326 mNVar = 2;
327 mM = (Matrix*) mObj; mNBinX = mM->NCol(); mNBinY =mM->NRows();
328 }
329else if (typeid(*mObj) == typeid(Histo2D)) {
330 mNVar = 2;
331 mH2 = (Histo2D*) mObj; mNBinX = mH2->NBinX(); mNBinY = mH2->NBinY();
332 }
333else if (typeid(*mObj) == typeid(GeneralFitData)) {
334 mG = (GeneralFitData*) mObj; mNBinX = mG->NData(); mNBinY = 1;
335 if( mG->NVar()==1) mNVar = 1;
336 else if(mG->NVar()==2) mNVar = 2;
337 else
338 {cout<<"PIAFitter::DecodeObject Error: \n"
339 <<" GeneralFitData ne peut avoir que 1 ou 2 variables d'abscisse: "
340 <<((GeneralFitData*) mObj)->NVar()<<endl;
341 return;}
342 }
343else if (dynamic_cast<RzImage*>(mObj)) {
344 mNVar = 2;
345 mIm = (RzImage*) mObj; mNBinX = mIm->XSize(); mNBinY = mIm->YSize();
346 }
347else {
348 cout<<"PIAFitter::DecodeObject Error , Objet n'est pas un "
349 <<"Histo1D/HProf/Vector/Histo2D/Image/Matrix/GeneralFitData "<<ctyp<<endl;
350 return;
351 }
352
353mNData = mNBinX*mNBinY;
354if(mNData<=0) {
355 cout<<"L'objet a "<<mNBinX<<","<<mNBinY<<" bins ("<<mNData<<")"<<endl;
356 return;
357}
358
359return;
360}
361
362/* --Methode-- */
363void PIAFitter::CheckOptions(void)
364// Check consistence des choix des options
365// ATTENTION: cette methode a besoin que l'objet a fitter soit deja lu
366{
367if(mOpt.lp<0) mOpt.lp = 0;
368if(mOpt.lpg<0) mOpt.lpg = 0;
369mOpt.i1 = (mOpt.i1<0||mOpt.i1>=mNBinX)? 0: mOpt.i1;
370mOpt.i2 = (mOpt.i2<0||mOpt.i2>=mNBinX||mOpt.i2<=mOpt.i1)? mNBinX-1: mOpt.i2;
371if(mNVar>=2) {
372 mOpt.j1 = (mOpt.j1<0||mOpt.j1>=mNBinY)? 0: mOpt.j1;
373 mOpt.j2 = (mOpt.j2<0||mOpt.j2>=mNBinY||mOpt.j2<=mOpt.j1)? mNBinY-1: mOpt.j2;
374} else mOpt.j2 = mOpt.j1 = 0;
375if(mOpt.polcx==2) {
376 if(mV||mM) mOpt.xc = (mOpt.i2-mOpt.i1+1)/2.;
377 else if(mH) mOpt.xc = (mH->XMin()+mH->XMax())/2.;
378 else if(mH2) mOpt.xc = (mH2->XMin()+mH2->XMax())/2.;
379 else if(mG) {double mini,maxi; mG->GetMinMax(2,mini,maxi); mOpt.xc=(mini+maxi)/2.;}
380 else if(mIm) {mOpt.xc = mIm->XOrg() * mIm->XPxSize()*(mOpt.i2-mOpt.i1+1)/2.;}
381}
382if(mOpt.polcy==2 && mNVar>=2) {
383 if(mM) mOpt.yc = (mOpt.j2-mOpt.j1+1)/2.;
384 if(mH2) mOpt.yc = (mH2->YMin()+mH2->YMax())/2.;
385 if(mG) {double mini,maxi; mG->GetMinMax(12,mini,maxi); mOpt.yc=(mini+maxi)/2.;}
386 if(mIm) {mOpt.yc = mIm->YOrg() * mIm->YPxSize()*(mOpt.j2-mOpt.j1+1)/2.;}
387}
388if(mOpt.err_e>0.) mOpt.err_E=-1.;
389if(mOpt.err_E>0.) mOpt.err_e =-1.;
390if(mOpt.stc2<=0.) mOpt.stc2 = 1.e-3;
391if(mOpt.nstep<2) mOpt.nstep = 100;
392
393return;
394}
395
396/* --Methode-- */
397void PIAFitter::PrintOptions(void)
398// Print des options
399{
400cout<<"Fit["<<mNBinX<<","<<mNBinY<<"] ("<<mNData<<") dim="<<mNVar<<":"
401 <<" Int=["<<mOpt.i1<<","<<mOpt.i2<<"],["<<mOpt.j1<<","<<mOpt.j2<<"]"<<endl
402 <<" Cent="<<mOpt.polcx<<","<<mOpt.polcy<<","<<mOpt.xc<<"+x"<<","<<mOpt.yc<<"+y"
403 <<" TypE="<<mOpt.err_e<<","<<mOpt.err_E
404 <<" StpX2="<<mOpt.stc2<<" Nstep="<<mOpt.nstep<<" Init.LFit="<<mOpt.fromlastfit
405 <<" lp,lpg="<<mOpt.lp<<","<<mOpt.lpg<<endl;
406return;
407}
408
409/* --Methode-- */
410void PIAFitter::FillGData(void)
411// Fill generalfitdata pour le fit
412// ATTENTION: cette methode a besoin que les options soient decodees et checkees
413{
414if(mNData<=0) return;
415if(mGData!=NULL) {delete mGData; mGData=NULL;}
416mGData = new GeneralFitData(mNVar,mNData,0);
417
418for(int i=mOpt.i1;i<=mOpt.i2;i++) for(int j=mOpt.j1;j<=mOpt.j2;j++) {
419 double x,y=0.,f,e;
420
421 if(mV)
422 {x= (double) i; f=(*mV)(i); e=1.;}
423 else if(mH)
424 {x=mH->BinCenter(i); f=(*mH)(i); e=(mH->HasErrors())?mH->Error(i):1.;}
425 else if(mM)
426 {x=(double) i; y=(double) j; f=(*mM)(j,i); e=1.;}
427 else if(mH2)
428 {float xf,yf; mH2->BinCenter(i,j,xf,yf); x=(double)xf; y=(double)yf;
429 f=(*mH2)(i,j); e=(mH2->HasErrors())?mH2->Error(i,j):1.;}
430 else if(mIm)
431 {x=mIm->XOrg()+(i+0.5)*mIm->XPxSize(); y=mIm->YOrg()+(j+0.5)*mIm->YPxSize();
432 f=mIm->DValue(i,j); e=1.;}
433 else if(mG&&mNVar==1) {x= mG->X(i); f=mG->Val(i); e=mG->EVal(i);}
434 else if(mG&&mNVar==2) {x= mG->X(i); y=mG->Y(i); f=mG->Val(i); e=mG->EVal(i);}
435 else x=y=f=e=0.;
436
437 // Gestion des erreurs a utiliser
438 if(mOpt.err_e>0.) e=mOpt.err_e;
439 else if(mOpt.err_E>0.) {e=(f<-1.||f>1.)?mOpt.err_E*sqrt(fabs(f)):mOpt.err_E;}
440
441 // Remplissage de generalfitdata
442 if(mFName[0]=='p') {x -= mOpt.xc; if(mNVar>=2) y -= mOpt.yc;}
443 if(mNVar==1) mGData->AddData1(x,f,e);
444 else if(mNVar==2) mGData->AddData2(x,y,f,e);
445}
446
447if(mGData->NData()<=0) {
448 cout<<"Pas de donnees dans GeneralFitData: "<<mGData->NData()<<endl;
449 return;
450}
451
452if(mOpt.lpg>1) {
453 mGData->PrintStatus();
454 mGData->PrintData(0);
455 mGData->PrintData(mGData->NData()-1);
456}
457
458return;
459}
460
461/* --Methode-- */
462void PIAFitter::DecodeFunction(string func)
463// Fonction a fitter
464// ATTENTION: cette methode a besoin que les donnees soient lues
465{
466if(func.length()<=0) {
467 cout<<"PIAFitter::DecodeFunction Donnez un nom de fonction a fitter."<<endl;
468 return;
469}
470if(mFunc!=NULL) {delete mFunc; mFunc=NULL;}
471
472mNPar=0;
473mFName = func;
474
475if(func[0]=='p' && mNVar==1) { //polynome
476 int degre = 0;
477 if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
478 cout<<"Fit polynome 1D de degre "<<degre<<endl;
479 Polyn1D* myf = new Polyn1D(degre,mOpt.xc);
480 mFunc = myf; mNPar = mFunc->NPar();
481
482} else if(func[0]=='e' && mNVar==1) { //exponentielle
483 int degre =-1;
484 if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
485 cout<<"Fit d'exponentielle+polynome 1D de degre "<<degre<<endl;
486 Exp1DPol* myf;
487 if(degre>=0) myf = new Exp1DPol((unsigned int)degre,mOpt.xc);
488 else myf = new Exp1DPol(mOpt.xc);
489 mFunc = myf; mNPar = mFunc->NPar();
490
491} else if(func[0]=='g' && mNVar==1) { //gaussienne en hauteur
492 int degre =-1;
493 if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
494 cout<<"Fit de Gaussienne_en_hauteur+polynome 1D de degre "<<degre<<endl;
495 Gauss1DPol* myf;
496 if(degre>=0) myf = new Gauss1DPol((unsigned int)degre,((mOpt.polcx)?true:false));
497 else { bool bfg = (mOpt.polcx)?true:false; myf = new Gauss1DPol(bfg); }
498 mFunc = myf; mNPar = mFunc->NPar();
499
500} else if(func[0]=='G' && mNVar==1) { //gaussienne en volume
501 int degre =-1;
502 if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
503 cout<<"Fit de Gaussienne_en_volume+polynome 1D de degre "<<degre<<endl;
504 GaussN1DPol* myf;
505 if(degre>=0) myf = new GaussN1DPol((unsigned int)degre,((mOpt.polcx)?true:false));
506 else { bool bfg = (mOpt.polcx)?true:false; myf = new GaussN1DPol(bfg); }
507 mFunc = myf; mNPar = mFunc->NPar();
508
509} else if(func[0]=='p' && mNVar==2) { //polynome 2D
510 int degre = 0;
511 if(func.length()>1) sscanf(func.c_str()+1,"%d",&degre);
512 cout<<"Fit polynome 2D de degre "<<degre<<endl;
513 Polyn2D* myf = new Polyn2D(degre,mOpt.xc,mOpt.yc);
514 mFunc = myf; mNPar = mFunc->NPar();
515
516} else if(func[0]=='G' && mNVar==2) { //gaussienne+fond en volume
517 int integ = 0;
518 if(func.length()>1) if(func[1]=='i') integ=1;
519 cout<<"Fit de Gaussienne+Fond 2D integ="<<integ<<endl;
520 if(integ) {GauRhInt2D* myf = new GauRhInt2D; mFunc = myf;}
521 else {GauRho2D* myf = new GauRho2D; mFunc = myf;}
522 mNPar = mFunc->NPar();
523
524} else if(func[0]=='d' && mNVar==2) { //DL gaussienne+fond en volume
525 int integ = 0;
526 if(func.length()>1) if(func[1]=='i') integ=1;
527 cout<<"Fit de DL de Gaussienne+Fond 2D integ="<<integ<<endl;
528 if(integ) {GdlRhInt2D* myf = new GdlRhInt2D; mFunc = myf;}
529 else {GdlRho2D* myf = new GdlRho2D; mFunc = myf;}
530 mNPar = mFunc->NPar();
531
532} else if(func[0]=='D' && mNVar==2) { //DL gaussienne+fond avec coeff variable p6 en volume
533 int integ = 0;
534 if(func.length()>1) if(func[1]=='i') integ=1;
535 cout<<"Fit de DL de Gaussienne+Fond avec coeff variable (p6) 2D integ="<<integ<<endl;
536 if(integ) {Gdl1RhInt2D* myf = new Gdl1RhInt2D; mFunc = myf;}
537 else {Gdl1Rho2D* myf = new Gdl1Rho2D; mFunc = myf;}
538 mNPar = mFunc->NPar();
539
540} else if(func[0]=='M' && mNVar==2) { //Moffat+fond (volume)
541 int integ = 0;
542 if(func.length()>1) if(func[1]=='i') integ=1;
543 cout<<"Fit de Moffat+Fond (expos=p6) 2D integ="<<integ<<endl;
544 if(integ) {MofRhInt2D* myf = new MofRhInt2D; mFunc = myf;}
545 else {MofRho2D* myf = new MofRho2D; mFunc = myf;}
546 mNPar = mFunc->NPar();
547
548} else {
549 cout<<"Fonction "<<func<<" inconnue pour la dim "<<mNVar<<endl;
550 mNPar = 0;
551 return;
552}
553
554return;
555}
556
557/* --Methode-- */
558void PIAFitter::ReSetParam(void)
559// Pour (re)dimensionner les tableaux des parametres
560// ATTENTION: cette methode a besoin que la fonction soit connue
561{
562if(mNPar==0) return;
563mPar.Realloc(mNPar); mPar=0.;
564mStep.Realloc(mNPar); mStep=1.;
565mMin.Realloc(mNPar); mMin=1.;
566mMax.Realloc(mNPar); mMax=-1.;
567mFix.Realloc(mNPar); mFix=0.;
568return;
569}
570
571/* --Methode-- */
572void PIAFitter::InitParFromLastFit(void)
573// Initialisation du fit a partir des resultats du fit precedent
574// (Les arguments de la ligne de commande sont prioritaires)
575// ATTENTION: cette methode a besoin que la fonction soit connue
576{
577if(mNPar==0) return;
578int n = mParSave.NElts();
579if(n==0) return;
580
581for(int i=0;i<mNPar;i++) {
582 if(i>=n) break;
583 mPar(i) = mParSave(i);
584 mStep(i) = mStepSave(i);
585 mMin(i) = mMinSave(i);
586 mMax(i) = mMaxSave(i);
587 mFix(i) = mFixSave(i);
588}
589
590return;
591}
592
593/* --Methode-- */
594void PIAFitter::DecodeParam(string par,string step,string min,string max,string fix)
595// Decodage des parametres
596// ATTENTION: cette methode a besoin que la fonction soit connue
597// et que les options soient decodees
598{
599if(mNPar==0) return;
600ReSetParam();
601if(mOpt.fromlastfit) InitParFromLastFit();
602Vector* v=NULL; string* s=NULL;
603for(int j=0;j<5;j++) {
604 if(j==0) {v=&mPar; s=&par;} else if(j==1) {v=&mStep; s=&step;}
605 else if(j==2) {v=&mMin; s=&min;} else if(j==3) {v=&mMax; s=&max;}
606 else if(j==4) {v=&mFix; s=&fix;}
607 if(s->length()>0) *s += ",";
608 for(int i=0;i<mNPar;i++) {
609 if(s->length()<=0) break;
610 if((*s)[0]!='!') sscanf(s->c_str(),"%lf",&(*v)(i));
611 size_t p = s->find_first_of(',') + 1;
612 if(p>=s->length()) *s = ""; else *s = s->substr(p);
613 }
614}
615return;
616}
617
618/* --Methode-- */
619int PIAFitter::DoFit(void)
620// Fit avec generalfit
621{
622if(mNPar==0) return -1000;
623if(mFunc==NULL || mGData==NULL) {
624 cout<<"PIAFitter::DoFit error: mFunc="<<mFunc<<" mGData="<<mGData<<endl;
625 return -1001;
626}
627// classe GeneraFit
628if(mFit != NULL) {delete mFit; mFit= NULL;}
629mFit= new GeneralFit(mFunc);
630// Options et Set de GeneralFit
631mFit->SetDebug(mOpt.lpg);
632mFit->SetData(mGData);
633mFit->SetStopChi2(mOpt.stc2);
634mFit->SetMaxStep(mOpt.nstep);
635{for(int i=0;i<mFunc->NPar();i++) {
636 char str[10];
637 sprintf(str,"P%d",i);
638 mFit->SetParam(i,str,mPar(i),mStep(i),mMin(i),mMax(i));
639 if((int)(mFix(i)+0.001)>=1.) mFit->SetFix(i);
640}}
641if(mOpt.lp>1) mFit->PrintFit();
642
643// Fit
644mParSave = mPar;
645mStepSave = mStep; mMinSave = mMin; mMaxSave = mMax; mFixSave = mFix;
646mOptSave = mOpt;
647double c2r = -1.;
648int rcfit = mFit->Fit();
649if(mOpt.lp>0) mFit->PrintFit();
650if(rcfit>0) {
651 c2r = mFit->GetChi2Red();
652 cout<<"C2r_Reduit = "<<c2r<<" nstep="<<mFit->GetNStep()<<" rc="<<rcfit<<endl;
653 for(int i=0;i<mFunc->NPar();i++) mParSave(i)=mFit->GetParm(i);
654} else {
655 cout<<"echec Fit, rc = "<<rcfit<<" nstep="<<mFit->GetNStep()<<endl;
656 mFit->PrintFitErr(rcfit);
657}
658
659return rcfit;
660}
661
662/* --Methode-- */
663void PIAFitter::FitFunRes(void)
664// Mise a disposition des resultats (fonction fitee et residus)
665{
666if(mFunc && (mOpt.okres||mOpt.okfun)) {
667 NamedObjMgr omg;
668 string nomres = mNObj + "_res";
669 string nomfun = mNObj + "_fun";
670 if(mV) {
671 if(mOpt.okres) {Vector* ob = mV->FitResidus(*mFit); if(ob) omg.AddObj(ob,nomres);}
672 if(mOpt.okfun) {Vector* ob = mV->FitFunction(*mFit); if(ob) omg.AddObj(ob,nomfun);}
673 } else if(mH) {
674 if(mOpt.okres) {Histo* ob = mH->FitResidus(*mFit); if(ob) omg.AddObj(ob,nomres);}
675 if(mOpt.okfun) {Histo* ob = mH->FitFunction(*mFit); if(ob) omg.AddObj(ob,nomfun);}
676 } else if(mM) {
677 if(mOpt.okres) {Matrix* ob = mM->FitResidus(*mFit); if(ob) omg.AddObj(ob,nomres);}
678 if(mOpt.okfun) {Matrix* ob = mM->FitFunction(*mFit); if(ob) omg.AddObj(ob,nomfun);}
679 } else if(mH2) {
680 if(mOpt.okres) {Histo2D* ob = mH2->FitResidus(*mFit); if(ob) omg.AddObj(ob,nomres);}
681 if(mOpt.okfun) {Histo2D* ob = mH2->FitFunction(*mFit); if(ob) omg.AddObj(ob,nomfun);}
682 } else if(mIm) {
683 if(mOpt.okres) {
684 RzImage* ob = mIm->FitResidus(*mFit);
685 if(ob) {ImageR4* rob = new ImageR4(*ob); omg.AddObj(rob,nomres); delete ob;}
686 }
687 if(mOpt.okfun) {
688 RzImage* ob = mIm->FitFunction(*mFit);
689 if(ob) {ImageR4* rob = new ImageR4(*ob); omg.AddObj(rob,nomfun); delete ob;}
690 }
691 } else if(mG) {
692 if(mOpt.okres) {GeneralFitData* ob = mG->FitResidus(*mFit); if(ob) omg.AddObj(ob,nomres);}
693 if(mOpt.okfun) {GeneralFitData* ob = mG->FitFunction(*mFit); if(ob) omg.AddObj(ob,nomfun);}
694 }
695}
696return;
697}
698
699/* --Methode-- */
700void PIAFitter::LinFit(void)
701// Fit lineaire de polynomes
702{
703if(mFName.length()<=0)
704 {cout<<"PIAFitter::LinFit Donnez un nom de fonction a fitter."<<endl;
705 return;}
706if(!mGData)
707 {cout<<"PIAFitter::LinFit pas de Data."<<endl; return;}
708if(mFName[0]!='p')
709 {cout<<"PIAFitter::LinFit fonction non prevue "<<mFName<<endl;
710 return;}
711int degre = 0;
712if(mFName.length()>1) sscanf(mFName.c_str()+1,"%d",&degre);
713
714if(mNVar==1) { // Fit lineaire de polynome 1D
715 cout<<"Fit (lineaire) 1D polynome de degre "<<degre<<endl;
716 Poly p1(0);
717 double c2rl = mGData->PolFit(0,p1,degre);
718 cout<<"C2r_lineaire = "<<c2rl<<endl;
719 if(mOpt.lp>0) cout<<p1<<endl;
720} else if(mNVar==2) { // Fit lineaire de polynome 2D
721 cout<<"Fit (lineaire) polynome 2D de degre "<<degre<<endl;
722 Poly2 p2(0);
723 double c2rl = mGData->PolFit(0,1,p2,degre);
724 cout<<"C2r_lineaire = "<<c2rl<<endl;
725 if(mOpt.lp>0) cout<<p2<<endl;
726}
727
728return;
729}
730
731/* --Methode-- */
732void PIAFitter::LinkFitFunc(string const & fname, string const & funcname, int nvar, int npar)
733{
734
735if ((nvar < 1) || (npar < 1)) return;
736
737if (mDlUFunc != NULL) delete mDlUFunc; // Nous en avons deja un, on nettoie
738
739mDlUFunc = NULL;
740mFitFunc = NULL;
741mFitFuncDer = NULL;
742mUFNVar= mUFNPar = 0;
743mNameFitFunc = "";
744
745// On compile le fichier C, on fabrique un .so et on l'ouvre
746mDlUFunc = PDynLinkMgr::BuildFromCFile(fname);
747if (mDlUFunc == NULL) {
748 cerr << "PIAFitter::LinkFitFunc() Erreur building .so " << endl;
749 return;
750 }
751
752// On recupere la fonction de fit
753mFitFunc = (DlUserFitFunc) mDlUFunc->GetFunction(funcname);
754if (mFitFunc == NULL) { // Probleme, on n'a pas trouve etc ...
755 cerr << "PIAFitter::LinkFitFunc() Erreur linking function " << funcname << endl;
756 delete mDlUFunc;
757 mDlUFunc = NULL;
758 return;
759 }
760
761// On recupere la fonction de derives
762string fnameder = funcname+"_der";
763mFitFuncDer = (DlUserFitFuncDer) mDlUFunc->GetFunction(fnameder);
764if (mFitFunc == NULL) {
765 cout << "PIAFitter::LinkFitFunc() No derive for " << fnameder << endl;
766 }
767
768mNameFitFunc = funcname;
769mUFNVar = nvar;
770mUFNPar = npar;
771
772cout << "PIAFitter::LinkFitFunc() UserFitFunc" << funcname
773 << " NVar=" << nvar << " NPar=" << npar << endl;
774
775}
776/* --Methode-- */
777void PIAFitter::PrepareFitFuncCFile(string const & fname, string const & funcname, int nvar, int npar)
778{
779// A Faire
780}
781
782/* --Methode-- */
783int PIAFitter::Execute(string& kw, vector<string>& tokens)
784// Execution des commandes de fit : "fit" et "fitw"
785{
786if(tokens.size() < 2) {
787 cout
788 <<"Usage:fit nomobj func [Options]\n"
789 <<" ou fitw nomobj func [Options]\n"
790 <<" avec Options: [p:p1,...,pn s:s1,...,sn m:m1,...,mn \n"
791 <<" M:M1,...,Mn f:f1,...,fn o:.,.,. o:.,.,.]\n"
792 <<" ou fitlin nomobj func [o:.,.,. o:.,.,.]\n";
793 return(-1);
794}
795// decodage des arguments de la commande
796string mSp,mSs,mSm,mSM,mSf,mSo;
797mSp=""; mSs=""; mSm=""; mSM=""; mSf=""; mSo="";
798if(tokens.size()>2)
799 for(int ip=2;ip<(int)tokens.size();ip++) {
800 if(tokens[ip].length()<=2) continue;
801 const char *c = tokens[ip].c_str();
802 if(c[1]!=':') continue;
803 if(c[0]=='p') mSp=c+2;
804 else if(c[0]=='s') mSs=c+2;
805 else if(c[0]=='m') mSm=c+2;
806 else if(c[0]=='M') mSM=c+2;
807 else if(c[0]=='f') mSf=c+2;
808 else if(c[0]=='o') {mSo += ","; mSo += c+2;}
809 }
810// Execution des commandes
811DecodeOptions(mSo);
812DecodeObject(tokens[0]);
813CheckOptions();
814if(mOpt.lp>0) PrintOptions();
815FillGData();
816DecodeFunction(tokens[1]);
817DecodeParam(mSp,mSs,mSm,mSM,mSf);
818if (kw == "fit") {
819 int rc = DoFit();
820 if(rc>=0) FitFunRes();
821} else if (kw == "fitlin") {
822 LinFit();
823} else if (kw == "fitw") {
824 if(FWindFit!=NULL) {delete FWindFit; FWindFit=NULL;}
825 FWindFit = new PIAFitterWind(mApp,this);
826 FWindFit->Show();
827} else if (kw == "crfitfun") {
828 if (tokens.size() < 4) {
829 cout <<"Usage:crfitfun ... " << endl; return(0); }
830 LinkFitFunc(tokens[0], tokens[1], 1, 7);
831 double par[7]={1000,0.,0.,1.,1.,0.1,100.};
832 double x[2]={1.,1.};
833 cout<<"Salut:"<<mFitFunc(x,par)<<endl;
834}
835
836
837return(0);
838}
839
840////////////////////////////////////////////////////////////////////
841////---------- Classe de fenetre de fit interactive ------------////
842////////////////////////////////////////////////////////////////////
843
844/* --Methode-- */
845PIAFitterWind::PIAFitterWind(PIStdImgApp* par, PIAFitter* fiter)
846 : PIWindow((PIMsgHandler*)par, "PIAFitter", PIWK_normal, 240, 240, 150, 150)
847{
848ReFillGData = false;
849saveI1 = saveI2 = saveJ1 = saveJ2 = 0;
850mDap = par;
851mFitter = fiter;
852string obj = mFitter->mNObj;
853string fun = mFitter->mFName;
854int npar = mFitter->mNPar;
855
856// Alloc de la taille
857nlab = 20+npar; lab = new PILabel*[nlab]; {for(int i=0;i<nlab;i++) lab[i]=NULL;}
858ntxt = 20+4*npar; txt = new PIText*[ntxt]; {for(int i=0;i<ntxt;i++) txt[i]=NULL;}
859nbut = 20; but = new PIButton*[nbut]; {for(int i=0;i<nbut;i++) but[i]=NULL;}
860nckb = 20+npar; ckb = new PICheckBox*[nckb]; {for(int i=0;i<nckb;i++) ckb[i]=NULL;}
861npom = 10; pom = new PIOptMenu*[npom]; {for(int i=0;i<npom;i++) pom[i]=NULL;}
862
863// On definit la taille a partir de la taille par defaut des composantes
864// bsx,bsy = environ 6 lettres
865int bsx,bsy;
866par->PrefCompSz(bsx, bsy);
867int spx = (bsx>=10) ? bsx/10 : 1; // intervalle entre lettres X
868int spy = (bsy>=6) ? bsy/6 : 1; // intervalle entre lettres Y
869
870int wszx = (5*bsx+5*spx)+spx;
871int wszy = 9*(bsy+spy)+npar*(bsy+spy)+spy;
872SetSize(wszx, wszy);
873int cpx,cpy;
874
875// new ligne
876cpx=spx; cpy=spy;
877but[0] = new PIButton(this,"Fr.Last",111,bsx,bsy,cpx,cpy);
878but[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
879cpx += bsx+spx;
880but[1] = new PIButton(this,"Default",222,bsx,bsy,cpx,cpy);
881but[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
882cpx+=bsx+spx;
883ckb[0] = new PICheckBox(this,"Gen Fun",1001,bsx,bsy,cpx,cpy);
884ckb[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
885cpx += bsx+2*spx;
886ckb[1] = new PICheckBox(this,"Res",1002,bsx,bsy,cpx,cpy);
887ckb[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
888
889// new ligne
890cpx=spx; cpy += bsy+spy -spy;
891lab[0] = new PILabel(this,"- Center X -",2*bsx,bsy,cpx,cpy);
892lab[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
893cpx += 2*bsx+spx;
894lab[1] = new PILabel(this,"- Center Y -",2*bsx,bsy,cpx,cpy);
895lab[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
896
897// new ligne
898cpx=spx; cpy += bsy+spy -spy;
899pom[0] = new PIOptMenu(this,"No",bsx,bsy,cpx,cpy);
900 pom[0]->AppendItem("No",2001);
901 pom[0]->AppendItem("Value",2002);
902 pom[0]->AppendItem("Auto",2003);
903pom[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
904cpx+=bsx+spx;
905txt[0] = new PIText(this,"",bsx,bsy,cpx,cpy);
906txt[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
907cpx+=bsx+2*spx;
908pom[1] = new PIOptMenu(this,"No",bsx,bsy,cpx,cpy);
909 pom[1]->AppendItem("No",2011);
910 pom[1]->AppendItem("Value",2012);
911 pom[1]->AppendItem("Auto",2013);
912pom[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
913cpx+=bsx+spx;
914txt[1] = new PIText(this,"",bsx,bsy,cpx,cpy);
915txt[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
916
917// new ligne
918cpx=spx; cpy += bsy+spy;
919lab[2] = new PILabel(this,"Err cste",1.25*bsx,bsy,cpx,cpy);
920lab[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
921cpx+=1.25*bsx+spx;
922txt[2] = new PIText(this,"",bsx,bsy,cpx,cpy);
923txt[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
924cpx+=bsx+2*spx;
925lab[3] = new PILabel(this,"sqrt",bsx,bsy,cpx,cpy);
926lab[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
927cpx+=bsx+spx;
928txt[3] = new PIText(this,"",bsx,bsy,cpx,cpy);
929txt[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
930
931// new ligne
932cpx=spx; cpy += bsy+spy;
933lab[4] = new PILabel(this,"Stop Xi2",1.25*bsx,bsy,cpx,cpy);
934lab[4]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
935cpx+=1.25*bsx+spx;
936txt[4] = new PIText(this,"",bsx,bsy,cpx,cpy);
937txt[4]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
938cpx+=bsx+spx;
939lab[5] = new PILabel(this,"Iter",bsx, bsy, cpx, cpy);
940lab[5]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
941cpx+=bsx+spx;
942txt[5] = new PIText(this,"",bsx,bsy,cpx,cpy);
943txt[5]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
944
945// new ligne
946cpx=spx; cpy += bsy+spy;
947lab[6] = new PILabel(this,"Print",bsx,bsy,cpx,cpy);
948lab[6]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
949cpx+=bsx+spx;
950txt[6] = new PIText(this,"",bsx/2,bsy,cpx,cpy);
951txt[6]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
952cpx+=bsx/2+spx;
953lab[7] = new PILabel(this,"Debug",bsx,bsy,cpx,cpy);
954lab[7]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
955cpx+=bsx+spx;
956txt[7] = new PIText(this,"",bsx/2,bsy,cpx,cpy);
957txt[7]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
958
959// new ligne
960cpx=spx; cpy += bsy+spy;
961lab[8] = new PILabel(this,"Range X",bsx,bsy,cpx,cpy);
962lab[8]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
963cpx+=bsx+spx;
964txt[8] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
965txt[8]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
966cpx+=0.75*bsx+spx;
967txt[9] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
968txt[9]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
969cpx+=0.75*bsx+spx;
970lab[9] = new PILabel(this,"Y",bsx/2,bsy,cpx,cpy);
971lab[9]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
972cpx+=bsx/2+spx;
973txt[10] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
974txt[10]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
975cpx+=0.75*bsx+spx;
976txt[11] = new PIText(this,"",0.75*bsx,bsy,cpx,cpy);
977txt[11]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
978
979// new ligne
980cpx=spx; cpy+=bsy+spy;
981but[2] = new PIButton(this, "Dismiss",777,bsx,bsy,cpx,cpy);
982but[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
983cpx += bsx+spx;
984but[3] = new PIButton(this, "Refesh",666,bsx,bsy,cpx,cpy);
985but[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
986cpx += bsx+spx;
987but[4] = new PIButton(this, "Fit",333,bsx,bsy,cpx,cpy);
988but[4]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
989cpx+=bsx+spx;
990lab[10] = new PILabel(this,fun.c_str(),bsx/2,bsy,cpx,cpy);
991lab[10]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
992
993// new lines: Parametres (npar lignes)
994cpx=spx; cpy+=bsy+spy;
995lab[11] = new PILabel(this,"Par",bsx/2,bsy,cpx,cpy);
996lab[11]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
997cpx+=bsx/2+spx;
998lab[12] = new PILabel(this,"F",bsx/3,bsy,cpx,cpy);
999lab[12]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
1000cpx+=bsx/3+spx;
1001lab[13] = new PILabel(this,"Init",bsx,bsy,cpx,cpy);
1002lab[13]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
1003cpx+=bsx+spx;
1004lab[14] = new PILabel(this,"Step",bsx,bsy,cpx,cpy);
1005lab[14]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
1006cpx+=bsx+spx;
1007lab[15] = new PILabel(this,"Min",bsx,bsy,cpx,cpy);
1008lab[15]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
1009cpx+=bsx+spx;
1010lab[16] = new PILabel(this,"Max",bsx,bsy,cpx,cpy);
1011lab[16]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
1012if(npar>0) {
1013 for(int i=0;i<npar;i++) {
1014 cpx=spx; cpy+=bsy+spy;
1015 char str[8]; sprintf(str,"P%d",i);
1016 lab[20+i] = new PILabel(this,str,bsx/2,bsy,cpx,cpy);
1017 lab[20+i]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
1018 cpx+=bsx/2+spx;
1019 // Attention pas de message entre 1500 et 2000 (permet 500 parametres!)
1020 ckb[20+i] = new PICheckBox(this,"",1500+i,bsx/3,bsy,cpx,cpy);
1021 ckb[20+i]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
1022 cpx+=bsx/3+spx;
1023 for(int j=0;j<4;j++) {
1024 txt[20+4*i+j] = new PIText(this,"",bsx,bsy,cpx,cpy);
1025 txt[20+4*i+j]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
1026 cpx+=bsx+spx;
1027 }
1028 }
1029}
1030
1031return;
1032}
1033
1034/* --Methode-- */
1035PIAFitterWind::~PIAFitterWind()
1036{
1037int i;
1038for(i=0;i<nlab;i++) if(lab[i]) {delete lab[i]; lab[i]=NULL;}
1039for(i=0;i<ntxt;i++) if(txt[i]) {delete txt[i]; txt[i]=NULL;}
1040for(i=0;i<nbut;i++) if(but[i]) {delete but[i]; but[i]=NULL;}
1041for(i=0;i<nckb;i++) if(ckb[i]) {delete ckb[i]; ckb[i]=NULL;}
1042for(i=0;i<npom;i++) if(pom[i]) {delete pom[i]; pom[i]=NULL;}
1043if(lab) {delete lab; lab=NULL; nlab=0;}
1044if(txt) {delete txt; txt=NULL; ntxt=0;}
1045if(but) {delete but; but=NULL; nbut=0;}
1046if(ckb) {delete ckb; ckb=NULL; nckb=0;}
1047if(pom) {delete pom; pom=NULL; npom=0;}
1048}
1049
1050/* --Methode-- */
1051void PIAFitterWind::Show()
1052{
1053//mDap->SetBlocked();
1054SetState();
1055PIWindow::Show();
1056return;
1057}
1058
1059/* --Methode-- */
1060void PIAFitterWind::SetState(void)
1061// Ecriture et positionnement des ckb et txt
1062{
1063int npar = mFitter->mNPar;
1064
1065// Les check-boxes
1066ckb[0]->SetState(mFitter->mOpt.okfun);
1067ckb[1]->SetState(mFitter->mOpt.okres);
1068if(npar>0)
1069 for(int i=0;i<npar;i++) ckb[20+i]->SetState((mFitter->mFix(i)>=1.)?true:false);
1070
1071// Les champs textes
1072char str[128]; string dum;
1073sprintf(str,"%f",mFitter->mOpt.xc); dum=str; txt[0]->SetText(dum);
1074sprintf(str,"%f",mFitter->mOpt.yc); dum=str; txt[1]->SetText(dum);
1075sprintf(str,"%f",mFitter->mOpt.err_e); dum=str; txt[2]->SetText(dum);
1076sprintf(str,"%f",mFitter->mOpt.err_E); dum=str; txt[3]->SetText(dum);
1077sprintf(str,"%f",mFitter->mOpt.stc2); dum=str; txt[4]->SetText(dum);
1078sprintf(str,"%d",mFitter->mOpt.nstep); dum=str; txt[5]->SetText(dum);
1079sprintf(str,"%d",mFitter->mOpt.lp); dum=str; txt[6]->SetText(dum);
1080sprintf(str,"%d",mFitter->mOpt.lpg); dum=str; txt[7]->SetText(dum);
1081sprintf(str,"%d",mFitter->mOpt.i1); dum=str; txt[8]->SetText(dum);
1082sprintf(str,"%d",mFitter->mOpt.i2); dum=str; txt[9]->SetText(dum);
1083sprintf(str,"%d",mFitter->mOpt.j1); dum=str; txt[10]->SetText(dum);
1084sprintf(str,"%d",mFitter->mOpt.j2); dum=str; txt[11]->SetText(dum);
1085if(npar>0) {
1086 for(int i=0;i<npar;i++) {
1087 sprintf(str,"%f",mFitter->mPar(i)); dum=str; txt[20+4*i+0]->SetText(dum);
1088 sprintf(str,"%f",mFitter->mStep(i)); dum=str; txt[20+4*i+1]->SetText(dum);
1089 sprintf(str,"%f",mFitter->mMin(i)); dum=str; txt[20+4*i+2]->SetText(dum);
1090 sprintf(str,"%f",mFitter->mMax(i)); dum=str; txt[20+4*i+3]->SetText(dum);
1091 }
1092}
1093
1094return;
1095}
1096
1097/* --Methode-- */
1098void PIAFitterWind::Process(PIMessage msg, PIMsgHandler* sender, void* data)
1099{
1100int lp = (mFitter->mOpt.lp>2)?1:0;;
1101int npar = mFitter->mNPar;
1102
1103// L'objet existe t-il encore?
1104NamedObjMgr omg;
1105if(omg.GetObj(mFitter->mNObj) == NULL) {
1106 cout<<"PIAFitterWind::Process Error , Pas d'objet de nom "
1107 <<mFitter->mNObj<<endl;
1108 mFitter->ResetDPointer(); return;
1109}
1110
1111// On recupere les champs textes
1112string dum; char str[128];
1113dum=txt[0]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
1114 sscanf(str,"%lf",&(mFitter->mOpt.xc));
1115dum=txt[1]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
1116 sscanf(str,"%lf",&(mFitter->mOpt.yc));
1117dum=txt[2]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
1118 sscanf(str,"%lf",&(mFitter->mOpt.err_e));
1119dum=txt[3]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
1120 sscanf(str,"%lf",&(mFitter->mOpt.err_E));
1121dum=txt[4]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
1122 sscanf(str,"%lf",&(mFitter->mOpt.stc2));
1123dum=txt[5]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
1124 sscanf(str,"%d",&(mFitter->mOpt.nstep));
1125dum=txt[6]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
1126 sscanf(str,"%d",&(mFitter->mOpt.lp));
1127dum=txt[7]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
1128 sscanf(str,"%d",&(mFitter->mOpt.lpg));
1129dum=txt[8]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
1130// Attention si les valeurs de mOpt.i1/.i2/.j1/.j2 ont ete changees
1131 sscanf(str,"%d",&(mFitter->mOpt.i1));
1132dum=txt[9]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
1133 sscanf(str,"%d",&(mFitter->mOpt.i2));
1134dum=txt[10]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
1135 sscanf(str,"%d",&(mFitter->mOpt.j1));
1136dum=txt[11]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
1137 sscanf(str,"%d",&(mFitter->mOpt.j2));
1138if(saveI1!=mFitter->mOpt.i1 || saveI2!=mFitter->mOpt.i2 ||
1139 saveJ1!=mFitter->mOpt.j1 || saveJ2!=mFitter->mOpt.j2 ) {
1140 if(lp)
1141 cout<<"Range changed: I("<<saveI1<<","<<saveI2
1142 <<") -> I("<<mFitter->mOpt.i1<<","<<mFitter->mOpt.i2
1143 <<") ou J("<<saveJ1<<","<<saveJ2
1144 <<") -> J("<<mFitter->mOpt.j1<<","<<mFitter->mOpt.j2
1145 <<")"<<endl;
1146 ReFillGData = true;
1147 saveI1=mFitter->mOpt.i1; saveI2=mFitter->mOpt.i2;
1148 saveJ1=mFitter->mOpt.j1; saveJ2=mFitter->mOpt.j2;
1149}
1150
1151if(npar>0) {
1152 for(int i=0;i<npar;i++) {
1153 dum=txt[20+4*i+0]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
1154 sscanf(str,"%lf",&(mFitter->mPar(i)));
1155 dum=txt[20+4*i+1]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
1156 sscanf(str,"%lf",&(mFitter->mStep(i)));
1157 dum=txt[20+4*i+2]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
1158 sscanf(str,"%lf",&(mFitter->mMin(i)));
1159 dum=txt[20+4*i+3]->GetText(); strcpy(str,dum.c_str()); strip(str,'B',' ');
1160 sscanf(str,"%lf",&(mFitter->mMax(i)));
1161 }
1162}
1163
1164// Decodage des messages
1165msg = UserMsg(msg);
1166if(msg ==777) {
1167 if(lp) cout<<"Dismiss"<<endl;
1168 //mDap->SetReady();
1169 Hide();
1170 return;
1171}
1172else if(msg ==666) {
1173 if(lp) cout<<"Refresh"<<endl;
1174 mFitter->CheckOptions();
1175 if(ReFillGData) mFitter->FillGData();
1176 ReFillGData = false;
1177}
1178else if(msg ==111) {
1179 if(lp) cout<<"Update from last"<<endl;
1180 mFitter->ResetOptions();
1181 mFitter->mOpt = mFitter->mOptSave;
1182 mFitter->ReSetParam();
1183 mFitter->InitParFromLastFit();
1184 ReFillGData = true;
1185}
1186else if(msg ==222) {
1187 if(lp) cout<<"Default options/par"<<endl;
1188 mFitter->ResetOptions();
1189 mFitter->ReSetParam();
1190 ReFillGData = true;
1191}
1192else if(msg ==333) {
1193 if(lp) cout<<"Do the fit"<<endl;
1194 mFitter->CheckOptions();
1195 if(ReFillGData) mFitter->FillGData();
1196 ReFillGData = false;
1197 int rc = mFitter->DoFit();
1198 if(rc>=0) mFitter->FitFunRes();
1199}
1200else if(msg==1001) {
1201 if(ckb[0]->GetState()) {
1202 if(lp) cout<<"Gen fitted function"<<endl;
1203 mFitter->mOpt.okfun = true;
1204 } else if(!ckb[0]->GetState()) {
1205 if(lp) cout<<"No Gen fitted function"<<endl;
1206 mFitter->mOpt.okfun = false;
1207 }
1208}
1209else if(msg==1002) {
1210 if(ckb[1]->GetState()) {
1211 if(lp) cout<<"Gen fitted residus"<<endl;
1212 mFitter->mOpt.okres = true;
1213 } else if(!ckb[1]->GetState()) {
1214 if(lp) cout<<"No Gen fitted residus"<<endl;
1215 mFitter->mOpt.okres = false;
1216 }
1217}
1218else if(2001<=msg && msg<=2003) {
1219 mFitter->mOpt.polcx = msg-2001;
1220 if(lp) cout<<"Centrage X polcx="<<mFitter->mOpt.polcx
1221 <<" xc="<<mFitter->mOpt.xc<<endl;
1222 ReFillGData = true;
1223}
1224else if(2011<=msg && msg<=2013) {
1225 mFitter->mOpt.polcx = msg-2011;
1226 if(lp) cout<<"Centrage Y polcy="<<mFitter->mOpt.polcy
1227 <<" yc="<<mFitter->mOpt.yc<<endl;
1228 ReFillGData = true;
1229}
1230else if(msg>=1500 && msg<2000) {
1231 int ip = msg-1500;
1232 if(ckb[20+ip]->GetState()) {
1233 if(lp) cout<<"Fix Param "<<ip<<endl;
1234 mFitter->mFix(ip) = 1.001;
1235 } else if(!ckb[20+ip]->GetState()) {
1236 if(lp) cout<<"Not Fix Param "<<ip<<endl;
1237 mFitter->mFix(ip) = 0.;
1238 }
1239}
1240
1241mFitter->CheckOptions();
1242SetState();
1243if(mFitter->mOpt.lp>1) mFitter->PrintOptions();
1244
1245return;
1246}
Note: See TracBrowser for help on using the repository browser.