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

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

suite fit fenetre cmv 10/8/99

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