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

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

fit/fitw/fitlin cmv 9/8/99

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