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