1 | #include "sopnamsp.h"
|
---|
2 | #include "machdefs.h"
|
---|
3 | #include <iostream>
|
---|
4 | #include <stdlib.h>
|
---|
5 | #include <stdio.h>
|
---|
6 | #include <string.h>
|
---|
7 | #include <math.h>
|
---|
8 | #include <unistd.h>
|
---|
9 |
|
---|
10 | #include "fioarr.h"
|
---|
11 | #include "ntuple.h"
|
---|
12 |
|
---|
13 | #include "Minuit2/FunctionMinimum.h"
|
---|
14 | #include "Minuit2/MnMigrad.h"
|
---|
15 | #include "Minuit2/MnUserParameters.h"
|
---|
16 | #include "Minuit2/MnPrint.h"
|
---|
17 | #include "Minuit2/MnMinos.h"
|
---|
18 | #include "Minuit2/MinosError.h"
|
---|
19 | #include "Minuit2/FCNBase.h"
|
---|
20 | using namespace ROOT::Minuit2;
|
---|
21 |
|
---|
22 | //--------------------------------------------------
|
---|
23 | namespace ROOT { namespace Minuit2 {
|
---|
24 | class MyFCN : public FCNBase {
|
---|
25 | public:
|
---|
26 | MyFCN(TVector<r_4>& FreqMHz,TVector<r_4>& V,TVector<r_4>& EV);
|
---|
27 | void SetNu0(double nu0Mhz) {_nu0 = nu0Mhz;}
|
---|
28 | void SetTyp(bool law2 = false) {_law2 = law2;}
|
---|
29 | void InitFit(MnUserParameters& upar);
|
---|
30 | double Func(double fr,const vector<double>& par) const;
|
---|
31 | double operator()(const vector<double>& par) const;
|
---|
32 | double Up(void) const {return 1.;}
|
---|
33 | //protected:
|
---|
34 | double _nu0;
|
---|
35 | bool _law2;
|
---|
36 | mutable int _ndata;
|
---|
37 | TVector<r_4> _F;
|
---|
38 | TVector<r_4> _V;
|
---|
39 | TVector<r_4> _EV;
|
---|
40 | };
|
---|
41 | } } // namespace ROOT + Minuit2
|
---|
42 |
|
---|
43 | //--------------------------------------------------
|
---|
44 | int main(int narg,char *arg[])
|
---|
45 | {
|
---|
46 | int nslicemax = -1;
|
---|
47 | int typfit = 0;
|
---|
48 | if(narg<=1) {
|
---|
49 | cout<<"cmvgsmcfit cubefile.ppf [nslicemax] [typfit=0,1]"<<endl;
|
---|
50 | return -1;
|
---|
51 | }
|
---|
52 |
|
---|
53 | if(narg>2) nslicemax = atoi(arg[2]);
|
---|
54 | if(narg>3) typfit = atoi(arg[3]);
|
---|
55 | cout<<"Fitting "<<arg[1]<<" , nslicemax="<<nslicemax<<" , typfit="<<typfit<<endl;
|
---|
56 |
|
---|
57 | int rc = 0;
|
---|
58 | try {
|
---|
59 |
|
---|
60 | POutPersist pos("cmvgsmcfit.ppf");
|
---|
61 | PInPersist pis(arg[1]);
|
---|
62 | TArray<r_4> Cube;
|
---|
63 | pis>>PPFNameTag("cube")>>Cube;
|
---|
64 | TVector<r_4> Freq;
|
---|
65 | pis>>PPFNameTag("freq")>>Freq;
|
---|
66 |
|
---|
67 | const int nvar = 10;
|
---|
68 | const char *vname[nvar] = {"x2r","ok","ph","th","v0","vn","A","N","B","DN"};
|
---|
69 | NTuple nt(nvar,vname);
|
---|
70 | double xnt[nvar]; for(int i=0;i<nvar;i++) xnt[i] = 0.;
|
---|
71 |
|
---|
72 | int nfit = 0;
|
---|
73 | for(int j=0;j<Cube.SizeY();j++) {
|
---|
74 | cout<<"...j = "<<j<<endl;
|
---|
75 | for(int k=0;k<Cube.SizeZ();k++) {
|
---|
76 | //cout<<"...k = "<<k<<endl;
|
---|
77 |
|
---|
78 | TVector<r_4> V(Cube.SizeX()), EV(Cube.SizeX());
|
---|
79 | for(int i=0;i<Cube.SizeX();i++) {
|
---|
80 | V(i) = Cube(i,j,k);
|
---|
81 | EV(i) = V(i) * 0.05;
|
---|
82 | }
|
---|
83 |
|
---|
84 | MyFCN myfcn(Freq,V,EV);
|
---|
85 | myfcn.SetNu0(Freq(0));
|
---|
86 | //myfcn.SetNu0((Freq(0)+Freq(Freq.Size()-1))/2.);
|
---|
87 | myfcn.SetTyp( ((typfit==1)? true: false) );
|
---|
88 | MnUserParameters upar;
|
---|
89 | myfcn.InitFit(upar);
|
---|
90 | if(nfit==0) cout<<upar;
|
---|
91 |
|
---|
92 | unsigned int nfcall = 10000;
|
---|
93 | double tolerance = 0.0001;
|
---|
94 | MnMigrad migrad(myfcn,upar,MnStrategy(1));
|
---|
95 | FunctionMinimum fmini = migrad(nfcall,tolerance);
|
---|
96 |
|
---|
97 | MnUserParameterState ustate = fmini.UserState();
|
---|
98 | bool okfit = fmini.IsValid();
|
---|
99 | double xi2r = ustate.Fval()/(V.Size()-ustate.VariableParameters());
|
---|
100 | vector<double> par = ustate.Params();
|
---|
101 | if(nfit==0) {
|
---|
102 | cout<<ustate;
|
---|
103 | // cout<<ustate.Parameters(); cout<<ustate.Covariance(); cout<<ustate.GlobalCC();
|
---|
104 | cout<<"nFCN = "<<ustate.NFcn()<<", FVal = "<<ustate.Fval()<<", Edm = "<<ustate.Edm()<<endl;
|
---|
105 | cout<<"xi2r = "<<xi2r<<" ndata="<<myfcn._ndata<<" nvarp="<<ustate.VariableParameters()<<endl;
|
---|
106 | }
|
---|
107 |
|
---|
108 | xnt[0] = xi2r; xnt[1] = (okfit)? 1.: 0.;
|
---|
109 | xnt[2] = j; xnt[3] = k;
|
---|
110 | xnt[4] = V(0); xnt[5] = V(V.Size()-1);
|
---|
111 | for(int i=6;i<6+par.size() && i<nvar;i++) xnt[i] = par[i-6];
|
---|
112 | nt.Fill(xnt);
|
---|
113 | //vector<double> err = ustate.Errors();
|
---|
114 | for(int i=0;i<Cube.SizeX();i++) Cube(i,j,k) -= myfcn.Func(Freq(i),par);
|
---|
115 |
|
---|
116 | if(nfit<10) {
|
---|
117 | TVector<r_8> F(Cube.SizeX()), R(Cube.SizeX());
|
---|
118 | for(int i=0;i<Cube.SizeX();i++) {
|
---|
119 | F(i) = myfcn.Func(Freq(i),par);
|
---|
120 | R(i) = V(i) - F(i);
|
---|
121 | }
|
---|
122 | char str[64];
|
---|
123 | sprintf(str,"v_%d_%d",j,k);
|
---|
124 | pos<<PPFNameTag(str)<<V;
|
---|
125 | sprintf(str,"f_%d_%d",j,k);
|
---|
126 | pos<<PPFNameTag(str)<<F;
|
---|
127 | sprintf(str,"r_%d_%d",j,k);
|
---|
128 | pos<<PPFNameTag(str)<<R;
|
---|
129 | }
|
---|
130 |
|
---|
131 | nfit++;
|
---|
132 |
|
---|
133 | }
|
---|
134 | if(nslicemax>0 && j>=nslicemax) break;
|
---|
135 | }
|
---|
136 |
|
---|
137 | cout<<"nfit = "<<nfit<<endl;
|
---|
138 | pos<<PPFNameTag("nt")<<nt;
|
---|
139 | pos<<PPFNameTag("cublis")<<Cube;
|
---|
140 |
|
---|
141 | //-----------------------------------------------------------------
|
---|
142 | } catch (PException& exc) {
|
---|
143 | cerr<<"cmvgsmcfit.cc catched PException"<<exc.Msg()<<endl;
|
---|
144 | rc = 77;
|
---|
145 | } catch (std::exception& sex) {
|
---|
146 | cerr << "cmvgsmcfit.cc std::exception :"
|
---|
147 | << (string)typeid(sex).name() << "\n msg= " << sex.what() << endl;
|
---|
148 | rc = 78;
|
---|
149 | } catch (...) {
|
---|
150 | cerr << "cmvgsmcfit.cc catched unknown (...) exception " << endl;
|
---|
151 | rc = 79;
|
---|
152 | }
|
---|
153 |
|
---|
154 | return rc;
|
---|
155 | }
|
---|
156 |
|
---|
157 | //--------------------------------------------------
|
---|
158 | MyFCN::MyFCN(TVector<r_4>& FreqMHz,TVector<r_4>& V,TVector<r_4>& EV)
|
---|
159 | : _F(FreqMHz,false), _V(V,false), _EV(EV,false)
|
---|
160 | {
|
---|
161 | if(_F.Size()==0 || _F.Size()!=_V.Size() || _F.Size()!=_EV.Size())
|
---|
162 | throw SzMismatchError("MyFCN::MyFCN_Error: incompatible F / V / EV sizes");
|
---|
163 | _nu0 = _F(0);
|
---|
164 | _law2 = false;
|
---|
165 | _ndata =_V.Size();
|
---|
166 | }
|
---|
167 |
|
---|
168 | void MyFCN::InitFit(MnUserParameters& upar)
|
---|
169 | {
|
---|
170 | int n = _F.Size() - 1;
|
---|
171 | double a = _V(0);
|
---|
172 | double ni = log(_V(n)/a) / log(_F(n)/_nu0);
|
---|
173 |
|
---|
174 | upar.Add("A",a,a/50.);
|
---|
175 | upar.Add("Nu",ni,fabs(ni/50.));
|
---|
176 |
|
---|
177 | if(!_law2) return;
|
---|
178 | upar.Add("B",0.,a/200.);
|
---|
179 | upar.Add("DNu",0.,fabs(ni/200.));
|
---|
180 |
|
---|
181 | }
|
---|
182 |
|
---|
183 | double MyFCN::Func(double fr,const vector<double>& par) const
|
---|
184 | // v = A*(nu/nu0)^Nu
|
---|
185 | // v = A*(nu/nu0)^Nu + B/A*(nu/nu0)^(Nu+DNu) = A*(nu/nu0)^Nu * (1 + B*(nu/nu0)^DNu)
|
---|
186 | {
|
---|
187 | double f = par[0]*pow(fr/_nu0,par[1]);
|
---|
188 | if(_law2) f *= 1. + par[2]*pow(fr/_nu0,par[3]);
|
---|
189 | return f;
|
---|
190 | }
|
---|
191 |
|
---|
192 | double MyFCN::operator()(const vector<double>& par) const
|
---|
193 | {
|
---|
194 | double xi2 = 0.;
|
---|
195 | _ndata = 0;
|
---|
196 | for(int i=0;i<_V.Size();i++) {
|
---|
197 | double e2 = _EV(i)*_EV(i);
|
---|
198 | if(e2<=0.) continue;
|
---|
199 | double v = _V(i);
|
---|
200 | double f = Func(_F(i),par);
|
---|
201 | xi2 += (v-f)*(v-f)/e2;
|
---|
202 | _ndata++;
|
---|
203 | }
|
---|
204 | //cout<<"par: "<<par[0]<<" "<<par[1]<<endl;
|
---|
205 | return xi2;
|
---|
206 | }
|
---|
207 |
|
---|
208 | /*
|
---|
209 | openppf cmvgsmcfit.ppf
|
---|
210 |
|
---|
211 | set j 0
|
---|
212 | set k 0
|
---|
213 | zone 1 2
|
---|
214 | n/plot v_${j}_${k}.val%n ! ! "nsta cpts"
|
---|
215 | n/plot f_${j}_${k}.val%n ! ! "nsta cpts same red"
|
---|
216 | n/plot r_${j}_${k}.val%n ! ! "nsta cpts"
|
---|
217 |
|
---|
218 | zone 1 2
|
---|
219 | n/plot nt.ok%_nl ! ! "crossmarker3"
|
---|
220 | n/plot nt.x2r%_nl ! ! "crossmarker3"
|
---|
221 |
|
---|
222 | zone 1 2
|
---|
223 | n/plot nt.v0%_nl ! ! "crossmarker3"
|
---|
224 | n/plot nt.vn%_nl ! ! "plusmarker3 same red"
|
---|
225 | n/plot nt.log10(v0/vn)%v0 ! ! "crossmarker3"
|
---|
226 |
|
---|
227 | zone
|
---|
228 | n/plot nt.A%_nl ok>0 ! "crossmarker3"
|
---|
229 | n/plot nt.N%_nl ok>0 ! "crossmarker3"
|
---|
230 | n/plot nt.B%_nl ok>0 ! "crossmarker3"
|
---|
231 | n/plot nt.DN%_nl ok>0 ! "crossmarker3"
|
---|
232 |
|
---|
233 | n/plot nt.A%v0 ok>0 ! "crossmarker3"
|
---|
234 | n/plot nt.(A-v0)/v0%_nl ok>0 ! "crossmarker3"
|
---|
235 |
|
---|
236 | n/plot nt.N%A ok>0 ! "crossmarker3"
|
---|
237 | n/plot nt.B%A ok>0 ! "crossmarker3"
|
---|
238 | n/plot nt.DN%N ok>0 ! "crossmarker3"
|
---|
239 |
|
---|
240 | set n 0
|
---|
241 | objaoper cublis slicexz $n
|
---|
242 | disp slicexz_$n
|
---|
243 |
|
---|
244 | n/plot cublis.val%x fabs(y-5)<0.1&&fabs(z-5)<0.1
|
---|
245 | */
|
---|