1 | #include <stdio.h>
|
---|
2 | #include <stdlib.h>
|
---|
3 | #include <ctype.h>
|
---|
4 |
|
---|
5 | #include <iostream.h>
|
---|
6 |
|
---|
7 | #include <typeinfo>
|
---|
8 |
|
---|
9 | #include "piafitting.h"
|
---|
10 | #include "strutil.h"
|
---|
11 |
|
---|
12 | #include "generalfit.h"
|
---|
13 |
|
---|
14 | #include "fct1dfit.h"
|
---|
15 | #include "fct2dfit.h"
|
---|
16 |
|
---|
17 | #include "matrix.h"
|
---|
18 | #include "cvector.h"
|
---|
19 | #include "ntuple.h"
|
---|
20 | #include "cimage.h"
|
---|
21 |
|
---|
22 | #include "histos.h"
|
---|
23 | #include "histos2.h"
|
---|
24 | #include "ntuple.h"
|
---|
25 | #include "hisprof.h"
|
---|
26 |
|
---|
27 | #include "nobjmgr.h"
|
---|
28 | #include "pistdimgapp.h"
|
---|
29 |
|
---|
30 | //// ---------- Classe de fenetre de fit interactive ------------
|
---|
31 | class PIAFitterWind : public PIWindow {
|
---|
32 | public :
|
---|
33 | PIAFitterWind(PIStdImgApp* par, PIAFitter* fiter);
|
---|
34 | virtual ~PIAFitterWind();
|
---|
35 | virtual void Show();
|
---|
36 | virtual void Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
|
---|
37 | inline void SetObjName(string& nom) { oname = nom; }
|
---|
38 | protected :
|
---|
39 | PIStdImgApp* dap;
|
---|
40 | PIAFitter* fitter;
|
---|
41 | PIOptMenu* pom[2];
|
---|
42 | PILabel* lab[2]; // Maximum 20 parametres
|
---|
43 | PIText* txt[2]; // " " "
|
---|
44 | PIButton* but[2];
|
---|
45 | PICheckBox* ckb[2];
|
---|
46 | string oname;
|
---|
47 | };
|
---|
48 |
|
---|
49 | ///////////////////// Fit 1D et 2D //////////////////////////
|
---|
50 |
|
---|
51 | PIAFitterWind* fwind = NULL;
|
---|
52 |
|
---|
53 | /* --Methode-- */
|
---|
54 | PIAFitter::PIAFitter(PIACmd *piac, PIStdImgApp* app)
|
---|
55 | {
|
---|
56 | string kw, usage;
|
---|
57 |
|
---|
58 | kw = "fit";
|
---|
59 | usage = "Fitting function to DataObjects (Histo, Histo2D, Vector, ...)";
|
---|
60 | usage += "\n Usage: fit nomobj func [Options]";
|
---|
61 | usage += "\n [p:p1,...,pn s:s1,...,sn m:m1,...,mn M:M1,...,Mn o:... o:...]";
|
---|
62 | piac->RegisterCommand(kw, usage, this, "Fitting");
|
---|
63 |
|
---|
64 | kw = "fitw";
|
---|
65 | usage = "Interactive Window Fit";
|
---|
66 | usage += "\n Usage: fit nomobj ";
|
---|
67 | piac->RegisterCommand(kw, usage, this, "Fitting");
|
---|
68 |
|
---|
69 | // Je cree une seule copie de PIAFitterWind
|
---|
70 | // Attention, ca ne marchera pas si on detruit this
|
---|
71 | if (fwind == NULL) fwind = new PIAFitterWind(app, this);
|
---|
72 | }
|
---|
73 |
|
---|
74 | /* --Methode-- */
|
---|
75 | PIAFitter::~PIAFitter()
|
---|
76 | {
|
---|
77 | }
|
---|
78 |
|
---|
79 | int PIAFitter::Execute(string& kw, vector<string>& tokens)
|
---|
80 | {
|
---|
81 | // Fit 1D sur objets 1D. Egalement Fit 2D sur objets 2D.
|
---|
82 | if (kw == "fit") {
|
---|
83 | if (tokens.size() < 2) {
|
---|
84 | cout <<"Usage:fit nomobj func \n"
|
---|
85 | <<" [p:p1,...,pn s:s1,...,sn m:m1,...,mn M:M1,...,Mn o:... o:...]\n";
|
---|
86 | return(0);
|
---|
87 | }
|
---|
88 | string p=""; string s=""; string m=""; string M=""; string O="";
|
---|
89 | if (tokens.size()>2)
|
---|
90 | for(int ip=2;ip<tokens.size();ip++) {
|
---|
91 | if(tokens[ip].length()<=2) continue;
|
---|
92 | const char *c = tokens[ip].c_str();
|
---|
93 | if(c[1]!=':') continue;
|
---|
94 | if(c[0]=='p') p=c+2;
|
---|
95 | else if(c[0]=='s') s=c+2;
|
---|
96 | else if(c[0]=='m') m=c+2;
|
---|
97 | else if(c[0]=='M') M=c+2;
|
---|
98 | else if(c[0]=='o') {O += ","; O += c+2;}
|
---|
99 | }
|
---|
100 | Fit12D(tokens[0],tokens[1],p,s,m,M,O);
|
---|
101 | }
|
---|
102 | else if (kw == "fitw") {
|
---|
103 | cout << " *DBG* Affichage PIAFitterWind ** " << endl;
|
---|
104 | fwind->Show();
|
---|
105 | }
|
---|
106 |
|
---|
107 | return(0);
|
---|
108 | }
|
---|
109 |
|
---|
110 | /* --Methode-- cmv 13/10/98 */
|
---|
111 | void PIAFitter::Fit12D(string& nom, string& func,
|
---|
112 | string par,string step,string min,string max,
|
---|
113 | string opt)
|
---|
114 | //| --------------- Fit d'objets a 1 et 2 dimensions ---------------
|
---|
115 | //| nom : nom de l'objet qui peut etre:
|
---|
116 | //| fit-1D: Vector,Histo1D,HProf ou GeneraFitData(1D)
|
---|
117 | //| fit-2D: Matrix,Histo2D,Image<T> ou GeneraFitData(2D)
|
---|
118 | //| func : pnn : fit polynome degre nn avec classe Poly (lineaire) 1D ou 2D
|
---|
119 | //| : Pnn : fit polynome degre nn avec GeneralFit (non-lineaire) 1D ou 2D
|
---|
120 | //| : gnn : fit gaussienne (hauteur) + polynome de degre nn 1D
|
---|
121 | //| : g : fit gaussienne (hauteur) 1D
|
---|
122 | //| : enn : fit exponentielle + polynome de degre nn 1D
|
---|
123 | //| : e : fit exponentielle 1D
|
---|
124 | //| : Gnn : fit gaussienne (volume) + polynome de degre nn 1D
|
---|
125 | //| : G : fit gaussienne (volume) 1D
|
---|
126 | //| : : fit gaussienne+fond (volume) 2D
|
---|
127 | //| : Gi : fit gaussienne+fond integree (volume) 2D
|
---|
128 | //| : d : fit DL de gaussienne+fond (volume) 2D
|
---|
129 | //| : di : fit DL de gaussienne+fond integree (volume) 2D
|
---|
130 | //| : D : fit DL de gaussienne+fond avec coeff variable p6 (volume) 2D
|
---|
131 | //| : Di : fit DL de gaussienne+fond integree avec coeff variable p6 (volume) 2D
|
---|
132 | //| : M : fit Moffat+fond (expos=p6) (volume) 2D
|
---|
133 | //| : Mi : fit Moffat+fond integree (expos=p6) (volume) 2D
|
---|
134 | //| par : p1,...,pn : valeur d'initialisation des parametres (def=0)
|
---|
135 | //| step : s1,...,sn : valeur des steps de depart (def=1)
|
---|
136 | //| min : m1,...,mn : valeur des minima (def=1)
|
---|
137 | //| max : M1,...,Mn : valeur des maxima (def=-1) (max<=min : pas de limite)
|
---|
138 | //| opt : options "Eaa.b,eaa.b,f,r,caa.b,Xaa.b"
|
---|
139 | //| f : generation d'un Objet identique contenant la fonction fittee
|
---|
140 | //| r : generation d'un Objet identique contenant les residus
|
---|
141 | //| Xaa.b : aa.b valeur du DXi2 d'arret (def=1.e-3)
|
---|
142 | //| Naa : aa nombre maximum d'iterations (def=100)
|
---|
143 | //| la.b : niveau "a.b" de print: a=niveau de print Fit1/2D
|
---|
144 | //| b=niveau de debug GeneralFit
|
---|
145 | //| Ii1/i2 numeros des bins X de l'histos utilises pour le fit [i1,i2]
|
---|
146 | //|2D Jj1/j2 numeros des bins Y de l'histos utilises pour le fit [j1,j2]
|
---|
147 | //| - L'erreur est celle associee a l'objet (si elle existe),
|
---|
148 | //| elle est mise a 1 sinon, sauf si E... ou e... est precise:
|
---|
149 | //| Eaa.b : si |val|>=1 erreur = aa.b*sqrt(|val|)
|
---|
150 | //| si |val|<1 erreur = aa.b
|
---|
151 | //| si aa.b <=0 alors aa.b=1.0
|
---|
152 | //| E seul est equivalent a E1.0
|
---|
153 | //| eaa.b : erreur = aa.b
|
---|
154 | //| si aa.b <=0 alors aa.b=1.0
|
---|
155 | //| e seul est equivalent a e1.0
|
---|
156 | //| xaa.b : demande de centrage: on fit x-aa.b au lieu de x)
|
---|
157 | //| x : demande de centrage: on fit x-xc au lieu de x
|
---|
158 | //| avec xc=abscisse du milieu de l'histogramme
|
---|
159 | //| Actif pour exp+poly 1D, poly 1D
|
---|
160 | //| pour gauss+poly 1D, xc est le centre de la gaussienne.
|
---|
161 | //|2D yaa.b et y : idem "xaa.b et x" mais pour y
|
---|
162 | {
|
---|
163 |
|
---|
164 | NamedObjMgr omg;
|
---|
165 | AnyDataObj* obj = omg.GetObj(nom);
|
---|
166 | if (obj == NULL) {
|
---|
167 | cout<<"PIAFitter::Fit12D() Error , Pas d'objet de nom "<<nom<<endl;
|
---|
168 | return;
|
---|
169 | }
|
---|
170 | if(func.length()<=0)
|
---|
171 | {cout<<"PIAFitter::Fit12D() Donnez un nom de fonction a fitter."<<endl;
|
---|
172 | return;}
|
---|
173 | string ctyp = typeid(*obj).name();
|
---|
174 |
|
---|
175 | int ndim = 0, nbinx=0, nbiny=0, ndata = 0;
|
---|
176 | Vector* v = NULL; Histo* h = NULL;
|
---|
177 | Matrix* m = NULL; Histo2D* h2 = NULL; RzImage* im = NULL;
|
---|
178 | GeneralFitData* g = NULL;
|
---|
179 |
|
---|
180 | // 1D
|
---|
181 | if (typeid(*obj) == typeid(Vector)) {
|
---|
182 | ndim = 1;
|
---|
183 | v = (Vector*) obj; nbinx = v->NElts(); nbiny = 1;
|
---|
184 | }
|
---|
185 | else if ( (typeid(*obj) == typeid(HProf)) || (typeid(*obj) == typeid(Histo)) ) {
|
---|
186 | ndim = 1;
|
---|
187 | h = (Histo*) obj; nbinx = h->NBins(); nbiny = 1;
|
---|
188 | }
|
---|
189 | else if (typeid(*obj) == typeid(Matrix)) {
|
---|
190 | ndim = 2;
|
---|
191 | m = (Matrix*) obj; nbinx = m->NCol(); nbiny = m->NRows();
|
---|
192 | }
|
---|
193 | else if (typeid(*obj) == typeid(Histo2D)) {
|
---|
194 | ndim = 2;
|
---|
195 | h2 = (Histo2D*) obj; nbinx = h2->NBinX(); nbiny = h2->NBinY();
|
---|
196 | }
|
---|
197 | else if (typeid(*obj) == typeid(GeneralFitData)) {
|
---|
198 | g = (GeneralFitData*) obj; nbinx = g->NData(); nbiny = 1;
|
---|
199 | if( g->NVar()==1) ndim = 1;
|
---|
200 | else if(g->NVar()==2) ndim = 2;
|
---|
201 | else {
|
---|
202 | cout<<"GeneralFitData ne peut avoir que 1 ou 2 variables d'abscisse: "
|
---|
203 | <<((GeneralFitData*) obj)->NVar()<<endl; return; }
|
---|
204 | }
|
---|
205 | else if (dynamic_cast<RzImage*>(obj)) {
|
---|
206 | ndim = 2;
|
---|
207 | im = (RzImage*) obj; nbinx = im->XSize(); nbiny = im->YSize();
|
---|
208 | }
|
---|
209 | else {
|
---|
210 | cout<<"PIAFitter::Fit12D() Error , Objet n'est pas un "
|
---|
211 | <<"Histo1D/HProf/Vector/Histo2D/Image/Matrix/GeneralFitData "<<ctyp<<endl;
|
---|
212 | return;
|
---|
213 | }
|
---|
214 |
|
---|
215 | ndata = nbinx*nbiny;
|
---|
216 | if(ndata<=0)
|
---|
217 | {cout<<"L'objet a "<<nbinx<<","<<nbiny<<" bins ("<<ndata<<")"<<endl; return;}
|
---|
218 |
|
---|
219 | // Decodage des options et des parametres, mise en forme
|
---|
220 | Vector Par(1); Vector Step(1); Vector Min(1); Vector Max(1); DFOPTIONS O;
|
---|
221 | DecodeFitsOptions(par,step,min,max,opt,Par,Step,Min,Max,O);
|
---|
222 | O.i1 = (O.i1<0||O.i1>=nbinx)? 0: O.i1;
|
---|
223 | O.i2 = (O.i2<0||O.i2>=nbinx||O.i2<O.i1)? nbinx-1: O.i2;
|
---|
224 | if(ndim>=2) {
|
---|
225 | O.j1 = (O.j1<0||O.j1>=nbiny)? 0: O.j1;
|
---|
226 | O.j2 = (O.j2<0||O.j2>=nbiny||O.j2<O.j1)? nbiny-1: O.j2;
|
---|
227 | } else O.j2 = O.j1 = 0;
|
---|
228 | if(O.polcx==2) {
|
---|
229 | if(v||m) O.xc = (O.i2-O.i1+1)/2.;
|
---|
230 | else if(h) O.xc = (h->XMin()+h->XMax())/2.;
|
---|
231 | else if(h2) O.xc = (h2->XMin()+h2->XMax())/2.;
|
---|
232 | else if(g) {double mini,maxi; g->GetMinMax(2,mini,maxi); O.xc=(mini+maxi)/2.;}
|
---|
233 | else if(im) {O.xc = im->XOrg() * im->XPxSize()*(O.i2-O.i1+1)/2.;}
|
---|
234 | }
|
---|
235 | if(O.polcy==2 && ndim>=2) {
|
---|
236 | if(m) O.yc = (O.j2-O.j1+1)/2.;
|
---|
237 | if(h2) O.yc = (h2->YMin()+h2->YMax())/2.;
|
---|
238 | if(g) {double mini,maxi; g->GetMinMax(12,mini,maxi); O.yc=(mini+maxi)/2.;}
|
---|
239 | if(im) {O.yc = im->YOrg() * im->YPxSize()*(O.j2-O.j1+1)/2.;}
|
---|
240 | }
|
---|
241 | if(O.lp>0)
|
---|
242 | cout<<"Fit["<<nbinx<<","<<nbiny<<"] ("<<ndata<<") dim="<<ndim<<":"
|
---|
243 | <<" Int=["<<O.i1<<","<<O.i2<<"],["<<O.j1<<","<<O.j2<<"]"<<endl
|
---|
244 | <<" Cent="<<O.polcx<<","<<O.polcy<<","<<O.xc<<"+x"<<","<<O.yc<<"+y"
|
---|
245 | <<" TypE="<<O.err_e<<","<<O.err_E
|
---|
246 | <<" StpX2="<<O.stc2<<" Nstep="<<O.nstep
|
---|
247 | <<" lp,lpg="<<O.lp<<","<<O.lpg<<endl;
|
---|
248 |
|
---|
249 | ///////////////////////////////////
|
---|
250 | // Remplissage de GeneralFitData //
|
---|
251 | ///////////////////////////////////
|
---|
252 | GeneralFitData mydata(ndim,ndata,0);
|
---|
253 | {for(int i=O.i1;i<=O.i2;i++) for(int j=O.j1;j<=O.j2;j++) {
|
---|
254 | double x,y,f,e;
|
---|
255 |
|
---|
256 | if(v)
|
---|
257 | {x= (double) i; f=(*v)(i); e=1.;}
|
---|
258 | else if(h)
|
---|
259 | {x=h->BinCenter(i); f=(*h)(i); e=(h->HasErrors())?h->Error(i):1.;}
|
---|
260 | else if(m)
|
---|
261 | {x=(double) i; y=(double) j; f=(*m)(j,i); e=1.;}
|
---|
262 | else if(h2)
|
---|
263 | {float xf,yf; h2->BinCenter(i,j,xf,yf); x=(double)xf; y=(double)yf;
|
---|
264 | f=(*h2)(i,j); e=(h2->HasErrors())?h2->Error(i,j):1.;}
|
---|
265 | else if(im)
|
---|
266 | {x=im->XOrg()+(i+0.5)*im->XPxSize(); y=im->YOrg()+(j+0.5)*im->YPxSize();
|
---|
267 | f=im->DValue(i,j); e=1.;}
|
---|
268 | else if(g&&ndim==1) {x= g->X(i); f=g->Val(i); e=g->EVal(i);}
|
---|
269 | else if(g&&ndim==2) {x= g->X(i); y= g->Y(i); f=g->Val(i); e=g->EVal(i);}
|
---|
270 | else x=y=f=e=0.;
|
---|
271 |
|
---|
272 | // Gestion des erreurs a utiliser
|
---|
273 | if(O.err_e>0.) e=O.err_e;
|
---|
274 | else if(O.err_E>0.) {e=(f<-1.||f>1.)?O.err_E*sqrt(fabs(f)):O.err_E;}
|
---|
275 |
|
---|
276 | // Remplissage de generalfit
|
---|
277 | if(func[0]=='p') {x -= O.xc; if(ndim>=2) y -= O.yc;}
|
---|
278 | if(ndim==1) mydata.AddData1(x,f,e);
|
---|
279 | else if(ndim==2) mydata.AddData2(x,y,f,e);
|
---|
280 | }}
|
---|
281 | if(mydata.NData()<=0)
|
---|
282 | {cout<<"Pas de donnees dans GeneralFitData: "<<mydata.NData()<<endl;
|
---|
283 | return;}
|
---|
284 | if(O.lpg>1) {
|
---|
285 | mydata.PrintStatus();
|
---|
286 | mydata.PrintData(0);
|
---|
287 | mydata.PrintData(mydata.NData()-1);
|
---|
288 | }
|
---|
289 |
|
---|
290 | ////////////////////////////////////////////
|
---|
291 | // Identification de la fonction a fitter //
|
---|
292 | ////////////////////////////////////////////
|
---|
293 | GeneralFunction* myfunc = NULL;
|
---|
294 | if(func[0]=='p' && ndim==1) {
|
---|
295 | // Fit de polynome sans passer par les GeneralFit
|
---|
296 | int degre = 0;
|
---|
297 | if(func.length()>1) sscanf(func.c_str()+1,"%d",°re);
|
---|
298 | cout<<"Fit (lineaire) 1D polynome de degre "<<degre<<endl;
|
---|
299 | Poly p1(0);
|
---|
300 | double c2rl = mydata.PolFit(0,p1,degre);
|
---|
301 | cout<<"C2r_lineaire = "<<c2rl<<endl;
|
---|
302 | if(O.lp>0) cout<<p1<<endl;
|
---|
303 | return;
|
---|
304 |
|
---|
305 | } else if(func[0]=='P' && ndim==1) {
|
---|
306 | // Fit de polynome
|
---|
307 | int degre = 0;
|
---|
308 | if(func.length()>1) sscanf(func.c_str()+1,"%d",°re);
|
---|
309 | cout<<"Fit polynome 1D de degre "<<degre<<endl;
|
---|
310 | Polyn1D* myf = new Polyn1D(degre,O.xc);
|
---|
311 | myfunc = myf;
|
---|
312 |
|
---|
313 | } else if(func[0]=='e' && ndim==1) {
|
---|
314 | // Fit d'exponentielle
|
---|
315 | int degre =-1;
|
---|
316 | if(func.length()>1) sscanf(func.c_str()+1,"%d",°re);
|
---|
317 | cout<<"Fit d'exponentielle+polynome 1D de degre "<<degre<<endl;
|
---|
318 | Exp1DPol* myf;
|
---|
319 | if(degre>=0) myf = new Exp1DPol((unsigned int)degre,O.xc);
|
---|
320 | else myf = new Exp1DPol(O.xc);
|
---|
321 | myfunc = myf;
|
---|
322 |
|
---|
323 | } else if(func[0]=='g' && ndim==1) {
|
---|
324 | // Fit de gaussienne en hauteur
|
---|
325 | int degre =-1;
|
---|
326 | if(func.length()>1) sscanf(func.c_str()+1,"%d",°re);
|
---|
327 | cout<<"Fit de Gaussienne_en_hauteur+polynome 1D de degre "<<degre<<endl;
|
---|
328 | Gauss1DPol* myf;
|
---|
329 | if(degre>=0) myf = new Gauss1DPol((unsigned int)degre,((O.polcx)?true:false));
|
---|
330 | else { bool bfg = (O.polcx)?true:false; myf = new Gauss1DPol(bfg); }
|
---|
331 | myfunc = myf;
|
---|
332 |
|
---|
333 | } else if(func[0]=='G' && ndim==1) {
|
---|
334 | // Fit de gaussienne en volume
|
---|
335 | int degre =-1;
|
---|
336 | if(func.length()>1) sscanf(func.c_str()+1,"%d",°re);
|
---|
337 | cout<<"Fit de Gaussienne_en_volume+polynome 1D de degre "<<degre<<endl;
|
---|
338 | GaussN1DPol* myf;
|
---|
339 | if(degre>=0) myf = new GaussN1DPol((unsigned int)degre,((O.polcx)?true:false));
|
---|
340 | else { bool bfg = (O.polcx)?true:false; myf = new GaussN1DPol(bfg); }
|
---|
341 | myfunc = myf;
|
---|
342 |
|
---|
343 | } else if(func[0]=='p' && ndim==2) {
|
---|
344 | // Fit de polynome 2D sans passer par les GeneralFit
|
---|
345 | int degre = 0;
|
---|
346 | if(func.length()>1) sscanf(func.c_str()+1,"%d",°re);
|
---|
347 | cout<<"Fit (lineaire) polynome 2D de degre "<<degre<<endl;
|
---|
348 | Poly2 p2(0);
|
---|
349 | double c2rl = mydata.PolFit(0,1,p2,degre);
|
---|
350 | cout<<"C2r_lineaire = "<<c2rl<<endl;
|
---|
351 | if(O.lp>0) cout<<p2<<endl;
|
---|
352 | return;
|
---|
353 |
|
---|
354 | } else if(func[0]=='P' && ndim==2) {
|
---|
355 | // Fit de polynome 2D
|
---|
356 | int degre = 0;
|
---|
357 | if(func.length()>1) sscanf(func.c_str()+1,"%d",°re);
|
---|
358 | cout<<"Fit polynome 2D de degre "<<degre<<endl;
|
---|
359 | Polyn2D* myf = new Polyn2D(degre,O.xc,O.yc);
|
---|
360 | myfunc = myf;
|
---|
361 |
|
---|
362 | } else if(func[0]=='G' && ndim==2) {
|
---|
363 | // Fit de gaussienne+fond en volume
|
---|
364 | int integ = 0;
|
---|
365 | if(func.length()>1) if(func[1]=='i') integ=1;
|
---|
366 | cout<<"Fit de Gaussienne+Fond 2D integ="<<integ<<endl;
|
---|
367 | if(integ) {GauRhInt2D* myf = new GauRhInt2D; myfunc = myf;}
|
---|
368 | else {GauRho2D* myf = new GauRho2D; myfunc = myf;}
|
---|
369 |
|
---|
370 | } else if(func[0]=='d' && ndim==2) {
|
---|
371 | // Fit de DL gaussienne+fond en volume
|
---|
372 | int integ = 0;
|
---|
373 | if(func.length()>1) if(func[1]=='i') integ=1;
|
---|
374 | cout<<"Fit de DL de Gaussienne+Fond 2D integ="<<integ<<endl;
|
---|
375 | if(integ) {GdlRhInt2D* myf = new GdlRhInt2D; myfunc = myf;}
|
---|
376 | else {GdlRho2D* myf = new GdlRho2D; myfunc = myf;}
|
---|
377 |
|
---|
378 | } else if(func[0]=='D' && ndim==2) {
|
---|
379 | // Fit de DL gaussienne+fond avec coeff variable p6 en volume
|
---|
380 | int integ = 0;
|
---|
381 | if(func.length()>1) if(func[1]=='i') integ=1;
|
---|
382 | cout<<"Fit de DL de Gaussienne+Fond avec coeff variable (p6) 2D integ="<<integ<<endl;
|
---|
383 | if(integ) {Gdl1RhInt2D* myf = new Gdl1RhInt2D; myfunc = myf;}
|
---|
384 | else {Gdl1Rho2D* myf = new Gdl1Rho2D; myfunc = myf;}
|
---|
385 |
|
---|
386 | } else if(func[0]=='M' && ndim==2) {
|
---|
387 | // Fit de Moffat+fond (volume)
|
---|
388 | int integ = 0;
|
---|
389 | if(func.length()>1) if(func[1]=='i') integ=1;
|
---|
390 | cout<<"Fit de Moffat+Fond (expos=p6) 2D integ="<<integ<<endl;
|
---|
391 | if(integ) {MofRhInt2D* myf = new MofRhInt2D; myfunc = myf;}
|
---|
392 | else {MofRho2D* myf = new MofRho2D; myfunc = myf;}
|
---|
393 |
|
---|
394 | } else {
|
---|
395 | cout<<"Fonction "<<func<<" inconnue pour la dim "<<ndim<<endl;
|
---|
396 | return;
|
---|
397 | }
|
---|
398 |
|
---|
399 | /////////////////////////
|
---|
400 | // Fit avec generalfit //
|
---|
401 | /////////////////////////
|
---|
402 | if(myfunc->NPar()>Par.NElts())
|
---|
403 | {cout<<"Trop de parametres: "<<myfunc->NPar()<<">"<<Par.NElts()<<endl;
|
---|
404 | if(myfunc) delete myfunc; return;}
|
---|
405 | GeneralFit myfit(myfunc);
|
---|
406 | myfit.SetDebug(O.lpg);
|
---|
407 | myfit.SetData(&mydata);
|
---|
408 | myfit.SetStopChi2(O.stc2);
|
---|
409 | myfit.SetMaxStep(O.nstep);
|
---|
410 | {for(int i=0;i<myfunc->NPar();i++) {
|
---|
411 | char str[10];
|
---|
412 | sprintf(str,"P%d",i);
|
---|
413 | myfit.SetParam(i,str,Par(i),Step(i),Min(i),Max(i));
|
---|
414 | }}
|
---|
415 | if(O.lp>1) myfit.PrintFit();
|
---|
416 | double c2r = -1.;
|
---|
417 | int rcfit = (double) myfit.Fit();
|
---|
418 | if(O.lp>0) myfit.PrintFit();
|
---|
419 | if(rcfit>0) {
|
---|
420 | c2r = myfit.GetChi2Red();
|
---|
421 | cout<<"C2r_Reduit = "<<c2r<<" nstep="<<myfit.GetNStep()<<" rc="<<rcfit<<endl;
|
---|
422 | Vector ParFit(myfunc->NPar());
|
---|
423 | for(int i=0;i<myfunc->NPar();i++) ParFit(i)=myfit.GetParm(i);
|
---|
424 | } else {
|
---|
425 | cout<<"echec Fit, rc = "<<rcfit<<" nstep="<<myfit.GetNStep()<<endl;
|
---|
426 | myfit.PrintFitErr(rcfit);
|
---|
427 | }
|
---|
428 |
|
---|
429 | // Mise a disposition des resultats
|
---|
430 | if(rcfit>=0 && myfunc && (O.okres>0||O.okfun>0)) {
|
---|
431 | string nomres = nom + "res";
|
---|
432 | string nomfun = nom + "fun";
|
---|
433 | if(v) {
|
---|
434 | if(O.okres) {Vector* ob = v->FitResidus(myfit); if(ob) omg.AddObj(ob,nomres);}
|
---|
435 | if(O.okfun) {Vector* ob = v->FitFunction(myfit); if(ob) omg.AddObj(ob,nomfun);}
|
---|
436 | } else if(h) {
|
---|
437 | if(O.okres) {Histo* ob = h->FitResidus(myfit); if(ob) omg.AddObj(ob,nomres);}
|
---|
438 | if(O.okfun) {Histo* ob = h->FitFunction(myfit); if(ob) omg.AddObj(ob,nomfun);}
|
---|
439 | } else if(m) {
|
---|
440 | if(O.okres) {Matrix* ob = m->FitResidus(myfit); if(ob) omg.AddObj(ob,nomres);}
|
---|
441 | if(O.okfun) {Matrix* ob = m->FitFunction(myfit); if(ob) omg.AddObj(ob,nomfun);}
|
---|
442 | } else if(h2) {
|
---|
443 | if(O.okres) {Histo2D* ob = h2->FitResidus(myfit); if(ob) omg.AddObj(ob,nomres);}
|
---|
444 | if(O.okfun) {Histo2D* ob = h2->FitFunction(myfit); if(ob) omg.AddObj(ob,nomfun);}
|
---|
445 | } else if(im) {
|
---|
446 | if(O.okres) {RzImage* ob = im->FitResidus(myfit); if(ob) omg.AddObj(ob,nomres);}
|
---|
447 | if(O.okfun) {RzImage* ob = im->FitFunction(myfit); if(ob) omg.AddObj(ob,nomfun);}
|
---|
448 | } else if(g) {
|
---|
449 | if(O.okres) {GeneralFitData* ob = g->FitResidus(myfit); if(ob) omg.AddObj(ob,nomres);}
|
---|
450 | if(O.okfun) {GeneralFitData* ob = g->FitFunction(myfit); if(ob) omg.AddObj(ob,nomfun);}
|
---|
451 | }
|
---|
452 | }
|
---|
453 |
|
---|
454 | // Nettoyage
|
---|
455 | if(myfunc) delete myfunc;
|
---|
456 | return;
|
---|
457 | }
|
---|
458 |
|
---|
459 |
|
---|
460 | /* --Function static propre aux routines de fit 1D et 2D-- cmv 13/10/98 */
|
---|
461 | void PIAFitter::DecodeFitsOptions(string par,string step,string min,string max,string opt
|
---|
462 | ,Vector& Par,Vector& Step,Vector& Min,Vector& Max,DFOPTIONS& O)
|
---|
463 | //| Pour decoder les "string" et remplir les vecteurs du fit (cf commentaires dans Fit1D)
|
---|
464 | {
|
---|
465 | // set des vecteurs et decodage des string correspondantes
|
---|
466 | int NParMax = 100;
|
---|
467 | Par.Realloc(NParMax); Step.Realloc(NParMax);
|
---|
468 | Min.Realloc(NParMax); Max.Realloc(NParMax);
|
---|
469 | {
|
---|
470 | Vector* v=NULL; string* s=NULL;
|
---|
471 | {for(int i=0;i<NParMax;i++) {Par(i)=0.; Step(i)=1.; Min(i)=1.; Max(i)=-1.;}}
|
---|
472 | for(int j=0;j<4;j++) {
|
---|
473 | if(j==0) {v=&Par; s=∥}
|
---|
474 | else if(j==1) {v=&Step; s=&step;}
|
---|
475 | else if(j==2) {v=&Min; s=&min;}
|
---|
476 | else if(j==3) {v=&Max; s=&max;}
|
---|
477 | if(s->length()>0) *s += ",";
|
---|
478 | for(int i=0;i<NParMax;i++) {
|
---|
479 | if(s->length()<=0) break;
|
---|
480 | sscanf(s->c_str(),"%lf",&(*v)(i));
|
---|
481 | size_t p = s->find_first_of(',') + 1;
|
---|
482 | if(p>=s->length()) *s = ""; else *s = s->substr(p);
|
---|
483 | }
|
---|
484 | }
|
---|
485 | }
|
---|
486 |
|
---|
487 | // Decodage de options de opt
|
---|
488 | O.okres = O.okfun = 0;
|
---|
489 | O.polcx = O.polcy = 0;
|
---|
490 | O.xc = O.yc = 0.;
|
---|
491 | O.stc2 = 1.e-3;
|
---|
492 | O.nstep = 100;
|
---|
493 | O.err_e = O.err_E = -1.;
|
---|
494 | O.lp = 1; O.lpg = 0;
|
---|
495 | O.i1 = O.j1 = O.i2 = O.j2 = -1;
|
---|
496 |
|
---|
497 | if(opt.length()<=0) return;
|
---|
498 | opt = "," + opt + ",";
|
---|
499 |
|
---|
500 | if(strstr(opt.c_str(),",r,")) O.okres = 1; // residus
|
---|
501 | if(strstr(opt.c_str(),",f,")) O.okfun = 1; // fonction fittee
|
---|
502 | if(strstr(opt.c_str(),",x")) { // Demande de centrage (fit X=x-xc)
|
---|
503 | O.polcx = 2; // Le centrage est calcule automatiquement
|
---|
504 | size_t p = opt.find(",x");
|
---|
505 | size_t q = opt.find_first_of(',',p+1);
|
---|
506 | string dum = opt.substr(p,q-p);
|
---|
507 | if(dum.length()>2) {
|
---|
508 | sscanf(dum.c_str(),",x%lf",&O.xc);
|
---|
509 | O.polcx = 1; // Le centrage est fixe par la valeur lue
|
---|
510 | }
|
---|
511 | }
|
---|
512 | if(strstr(opt.c_str(),",y")) { // Demande de centrage (fit Y=y-yc)
|
---|
513 | O.polcy = 2; // Le centrage est calcule automatiquement
|
---|
514 | size_t p = opt.find(",y");
|
---|
515 | size_t q = opt.find_first_of(',',p+1);
|
---|
516 | string dum = opt.substr(p,q-p);
|
---|
517 | if(dum.length()>2) {
|
---|
518 | sscanf(dum.c_str(),",y%lf",&O.yc);
|
---|
519 | O.polcy = 1; // Le centrage est fixe par la valeur lue
|
---|
520 | }
|
---|
521 | }
|
---|
522 | if(strstr(opt.c_str(),",E")) { // Erreurs imposees a "sqrt(val)" ou "aa.b*sqrt(val)"
|
---|
523 | size_t p = opt.find(",E");
|
---|
524 | size_t q = opt.find_first_of(',',p+1);
|
---|
525 | string dum = opt.substr(p,q-p);
|
---|
526 | if(dum.length()>2) sscanf(dum.c_str(),",E%lf",&O.err_E);
|
---|
527 | if(O.err_E<=0.) O.err_E = 1.;
|
---|
528 | O.err_e=-1.;
|
---|
529 | }
|
---|
530 | if(strstr(opt.c_str(),",e")) { // Erreurs imposees a "1" ou "aa.b"
|
---|
531 | size_t p = opt.find(",e");
|
---|
532 | size_t q = opt.find_first_of(',',p+1);
|
---|
533 | string dum = opt.substr(p,q-p);
|
---|
534 | if(dum.length()>2) sscanf(dum.c_str(),",e%lf",&O.err_e);
|
---|
535 | if(O.err_e<=0.) O.err_e = 1.;
|
---|
536 | O.err_E=-1.;
|
---|
537 | }
|
---|
538 | if(strstr(opt.c_str(),",X")) { // Valeur du StopChi2
|
---|
539 | size_t p = opt.find(",X");
|
---|
540 | size_t q = opt.find_first_of(',',p+1);
|
---|
541 | string dum = opt.substr(p,q-p);
|
---|
542 | if(dum.length()>2) sscanf(dum.c_str(),",X%lf",&O.stc2);
|
---|
543 | if(O.stc2<=0.) O.stc2 = 1.e-3;
|
---|
544 | }
|
---|
545 | if(strstr(opt.c_str(),",N")) { // Nombre maximum d'iterations
|
---|
546 | size_t p = opt.find(",N");
|
---|
547 | size_t q = opt.find_first_of(',',p+1);
|
---|
548 | string dum = opt.substr(p,q-p);
|
---|
549 | if(dum.length()>2) sscanf(dum.c_str(),",N%d",&O.nstep);
|
---|
550 | if(O.nstep<2) O.nstep = 100;
|
---|
551 | }
|
---|
552 | if(strstr(opt.c_str(),",l")) { // niveau de print
|
---|
553 | size_t p = opt.find(",l");
|
---|
554 | size_t q = opt.find_first_of(',',p+1);
|
---|
555 | string dum = opt.substr(p,q-p);
|
---|
556 | float ab;
|
---|
557 | if(dum.length()>2) sscanf(dum.c_str(),",l%f",&ab);
|
---|
558 | if(ab<0) ab = 0.;
|
---|
559 | O.lp = (int) ab; O.lpg = int(10.*(ab-(float)O.lp+0.01));
|
---|
560 | }
|
---|
561 | if(strstr(opt.c_str(),",I")) { // intervalle de fit selon X
|
---|
562 | size_t p = opt.find(",I");
|
---|
563 | size_t q = opt.find_first_of(',',p+1);
|
---|
564 | string dum = opt.substr(p,q-p);
|
---|
565 | if(dum.length()>2) sscanf(dum.c_str(),",I%d/%d",&O.i1,&O.i2);
|
---|
566 | }
|
---|
567 | if(strstr(opt.c_str(),",J")) { // intervalle de fit selon Y
|
---|
568 | size_t p = opt.find(",J");
|
---|
569 | size_t q = opt.find_first_of(',',p+1);
|
---|
570 | string dum = opt.substr(p,q-p);
|
---|
571 | if(dum.length()>2) sscanf(dum.c_str(),",J%d/%d",&O.j1,&O.j2);
|
---|
572 | }
|
---|
573 | return;
|
---|
574 | }
|
---|
575 |
|
---|
576 |
|
---|
577 | // ---------------- Fenetre de fit interactive -------
|
---|
578 |
|
---|
579 |
|
---|
580 | /* --Methode-- */
|
---|
581 | PIAFitterWind::PIAFitterWind(PIStdImgApp* par, PIAFitter* fiter)
|
---|
582 | : PIWindow((PIMsgHandler*)par, "PIAFitter", PIWK_normal, 240, 240, 150, 150)
|
---|
583 | {
|
---|
584 | dap = par;
|
---|
585 | fitter = fiter;
|
---|
586 | int bsx, bsy, spx, spy;
|
---|
587 |
|
---|
588 | // On definit la taille a partir de la taille par defaut des composantes
|
---|
589 | // PIApplicationPrefCompSize(bsx, bsy);
|
---|
590 | par->PrefCompSz(bsx, bsy);
|
---|
591 | spx = bsx/10;
|
---|
592 | spy = bsy/4;
|
---|
593 |
|
---|
594 | int wszx = 5*spx+3*bsx;
|
---|
595 | int wszy = 5*bsy+6*spy;
|
---|
596 | SetSize(wszx, wszy);
|
---|
597 | int cpx = spx;
|
---|
598 | int cpy = spy;
|
---|
599 | int csx = cpx;
|
---|
600 | int csy = cpy;
|
---|
601 | lab[0] = new PILabel(this, "Object", 1.5*bsx, bsy, cpx, cpy);
|
---|
602 | cpy += spy+bsy;
|
---|
603 | lab[1] = new PILabel(this, "Params", 1.5*bsx, bsy, cpx, cpy);
|
---|
604 | cpx += bsx*1.5+spx;
|
---|
605 |
|
---|
606 | cpy = spy;
|
---|
607 | txt[0] = new PIText(this, "", 3.5*bsx, bsy, cpx, cpy);
|
---|
608 | cpy += spy+bsy;
|
---|
609 | txt[1] = new PIText(this, "1.", 3.5*bsx, bsy, cpx, cpy);
|
---|
610 |
|
---|
611 | cpy += spy+bsy;
|
---|
612 | ckb[0] = new PICheckBox(this,"Gen.Func", 1001, 2.5*bsx, bsy, cpx, cpy);
|
---|
613 | cpx += bsx*1.5+spx;
|
---|
614 | ckb[1] = new PICheckBox(this,"Gen.Resid", 1002, 2.5*bsx, bsy, cpx, cpy);
|
---|
615 |
|
---|
616 | cpy += spy+bsy;
|
---|
617 | pom[0] = new PIOptMenu(this, "FitFunc", 2.5*bsx, bsy, cpx, cpy);
|
---|
618 | pom[0]->AppendItem("Poly0", 100);
|
---|
619 | pom[0]->AppendItem("Poly1", 101);
|
---|
620 | pom[0]->AppendItem("Poly2", 102);
|
---|
621 | pom[0]->AppendItem("Gaussienne", 103);
|
---|
622 | pom[0]->AppendItem("Gauss+Poly0",104);
|
---|
623 | pom[0]->AppendItem("Gauss+Poly1",105);
|
---|
624 | pom[0]->AppendItem("Gauss+Poly2",106);
|
---|
625 |
|
---|
626 | cpx += bsx*1.5+spx;
|
---|
627 | pom[1] = new PIOptMenu(this, "Bidon", 2.5*bsx, bsy, cpx, cpy);
|
---|
628 | pom[1]->AppendItem("Un", 150);
|
---|
629 | pom[1]->AppendItem("Deux",250);
|
---|
630 | pom[1]->AppendItem("Trois",350);
|
---|
631 |
|
---|
632 | cpy += spy+bsy;
|
---|
633 | cpx = 0.5*spx;
|
---|
634 | but[0] = new PIButton(this, "DoFit", 555, bsx*2, bsy, cpx, cpy);
|
---|
635 | cpx += 3*spx;
|
---|
636 | but[1] = new PIButton(this, "Dismiss", 777, bsx*2, bsy, cpx, cpy);
|
---|
637 |
|
---|
638 | }
|
---|
639 | /* --Methode-- */
|
---|
640 | PIAFitterWind::~PIAFitterWind()
|
---|
641 | {
|
---|
642 | for(int i=0; i<2; i++) {
|
---|
643 | delete lab[i];
|
---|
644 | delete txt[i];
|
---|
645 | delete pom[i];
|
---|
646 | delete ckb[i];
|
---|
647 | delete but[i];
|
---|
648 | }
|
---|
649 | }
|
---|
650 | /* --Methode-- */
|
---|
651 | void PIAFitterWind::Show()
|
---|
652 | {
|
---|
653 | // Si on veut initialiser des trucs au moment ou apparait la fenetre
|
---|
654 | txt[0]->SetText(oname);
|
---|
655 | PIWindow::Show();
|
---|
656 | }
|
---|
657 |
|
---|
658 | /* --Methode-- */
|
---|
659 | void PIAFitterWind::Process(PIMessage msg, PIMsgHandler* sender, void* data)
|
---|
660 | {
|
---|
661 |
|
---|
662 | char *mf[7] = {"p0","p1","p2","g","g0","g1","g2"};
|
---|
663 | msg = UserMsg(msg);
|
---|
664 | if (msg == 777) { Hide(); return; } // On cache la fenetre
|
---|
665 |
|
---|
666 | if (msg == 555) { // On fait le fit
|
---|
667 | vector<string> args;
|
---|
668 | string cmd = oname;
|
---|
669 | string a;
|
---|
670 | args.push_back(oname);
|
---|
671 | int imf = pom[0]->GetValue()-100;
|
---|
672 | if ((imf < 0) || (imf > 6)) imf = 0;
|
---|
673 | a = mf[imf];
|
---|
674 | cmd += " " + a + " ";
|
---|
675 | args.push_back(a);
|
---|
676 | a = txt[1]->GetText(); // Definition des parametres
|
---|
677 | cmd += a;
|
---|
678 | args.push_back(a);
|
---|
679 | if (ckb[0]->GetState() || ckb[1]->GetState()) {
|
---|
680 | a = "o:";
|
---|
681 | if (ckb[0]->GetState()) a += "f";
|
---|
682 | if (ckb[1]->GetState()) a += "r";
|
---|
683 | cmd += " " + a;
|
---|
684 | args.push_back(a);
|
---|
685 | }
|
---|
686 | cout << "FitComm= fit " << cmd << endl;
|
---|
687 | string kw = "fit";
|
---|
688 | fitter->Execute(kw, args);
|
---|
689 | }
|
---|
690 |
|
---|
691 | }
|
---|