| 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(double nu0,double dnu,TVector<r_8>& V,TVector<r_8>& EV); | 
|---|
| 27 | void InitFit(MnUserParameters& upar); | 
|---|
| 28 | double Func(int ix,const vector<double>& par) const; | 
|---|
| 29 | double operator()(const vector<double>& par) const; | 
|---|
| 30 | double Up(void) const {return 1.;} | 
|---|
| 31 | //protected: | 
|---|
| 32 | mutable int _ndata; | 
|---|
| 33 | double _nu0, _dnu; | 
|---|
| 34 | TVector<r_8> _V; | 
|---|
| 35 | TVector<r_8> _EV; | 
|---|
| 36 | }; | 
|---|
| 37 | } }  // namespace ROOT + Minuit2 | 
|---|
| 38 |  | 
|---|
| 39 | //-------------------------------------------------- | 
|---|
| 40 | int main(int narg,char *arg[]) | 
|---|
| 41 | { | 
|---|
| 42 | double nu0 = 820.0, dnu = 0.5; // MHz | 
|---|
| 43 | if(narg<=1) { | 
|---|
| 44 | cout<<"cmvgsmcfit cubefile.ppf"<<endl; | 
|---|
| 45 | return -1; | 
|---|
| 46 | } | 
|---|
| 47 |  | 
|---|
| 48 | POutPersist pos("cmvgsmcfit.ppf"); | 
|---|
| 49 | PInPersist pis(arg[1]); | 
|---|
| 50 | TArray<r_4> Cube; | 
|---|
| 51 | pis>>PPFNameTag("cube")>>Cube; | 
|---|
| 52 | TVector<r_8> V(Cube.SizeX()), EV(Cube.SizeX()); | 
|---|
| 53 |  | 
|---|
| 54 | const int nvar = 6; | 
|---|
| 55 | const char *vname[nvar] = {"x2r","ok","ph","th","A","N"}; | 
|---|
| 56 | NTuple nt(nvar,vname); | 
|---|
| 57 | double xnt[nvar]; for(int i=0;i<nvar;i++) xnt[i] = 0.; | 
|---|
| 58 |  | 
|---|
| 59 | int nfit = 0; | 
|---|
| 60 | for(int j=0;j<Cube.SizeY();j++) { | 
|---|
| 61 | cout<<"..."<<j<<endl; | 
|---|
| 62 | for(int k=0;k<Cube.SizeZ();k++) { | 
|---|
| 63 | for(int i=0;i<Cube.SizeX();i++) { | 
|---|
| 64 | V(i) = Cube(i,j,k); | 
|---|
| 65 | EV(i) = V(i) * 0.05; | 
|---|
| 66 | } | 
|---|
| 67 |  | 
|---|
| 68 | MyFCN myfcn(nu0,dnu,V,EV); | 
|---|
| 69 | MnUserParameters upar; | 
|---|
| 70 | myfcn.InitFit(upar); | 
|---|
| 71 | if(nfit==0) cout<<upar; | 
|---|
| 72 |  | 
|---|
| 73 | unsigned int nfcall = 10000; | 
|---|
| 74 | double tolerance = 0.0001; | 
|---|
| 75 | MnMigrad migrad(myfcn,upar,MnStrategy(1)); | 
|---|
| 76 | FunctionMinimum fmini = migrad(nfcall,tolerance); | 
|---|
| 77 |  | 
|---|
| 78 | MnUserParameterState ustate = fmini.UserState(); | 
|---|
| 79 | bool okfit = fmini.IsValid(); | 
|---|
| 80 | double xi2r = ustate.Fval()/(V.Size()-ustate.VariableParameters()); | 
|---|
| 81 | vector<double> par = ustate.Params(); | 
|---|
| 82 | if(nfit==0) { | 
|---|
| 83 | cout<<ustate; | 
|---|
| 84 | // cout<<ustate.Parameters(); cout<<ustate.Covariance(); cout<<ustate.GlobalCC(); | 
|---|
| 85 | cout<<"nFCN = "<<ustate.NFcn()<<", FVal = "<<ustate.Fval()<<", Edm = "<<ustate.Edm()<<endl; | 
|---|
| 86 | cout<<"xi2r = "<<xi2r<<" ndata="<<myfcn._ndata<<" nvarp="<<ustate.VariableParameters()<<endl; | 
|---|
| 87 | } | 
|---|
| 88 |  | 
|---|
| 89 | xnt[0] = xi2r; xnt[1] = (okfit)? 1.: 0.; | 
|---|
| 90 | xnt[2] = j; xnt[3] = k; | 
|---|
| 91 | for(unsigned int i=0;i<par.size();i++) xnt[4+i] = par[i]; | 
|---|
| 92 | nt.Fill(xnt); | 
|---|
| 93 | //vector<double> err = ustate.Errors(); | 
|---|
| 94 | for(int i=0;i<Cube.SizeX();i++) Cube(i,j,k) -= myfcn.Func(i,par); | 
|---|
| 95 |  | 
|---|
| 96 | if(nfit<10) { | 
|---|
| 97 | TVector<r_8> F(Cube.SizeX()), R(Cube.SizeX()); | 
|---|
| 98 | for(int i=0;i<Cube.SizeX();i++) { | 
|---|
| 99 | F(i) = myfcn.Func(i,par); | 
|---|
| 100 | R(i) = V(i) - F(i); | 
|---|
| 101 | } | 
|---|
| 102 | char str[64]; | 
|---|
| 103 | sprintf(str,"v_%d_%d",j,k); | 
|---|
| 104 | pos<<PPFNameTag(str)<<V; | 
|---|
| 105 | sprintf(str,"f_%d_%d",j,k); | 
|---|
| 106 | pos<<PPFNameTag(str)<<F; | 
|---|
| 107 | sprintf(str,"r_%d_%d",j,k); | 
|---|
| 108 | pos<<PPFNameTag(str)<<R; | 
|---|
| 109 | } | 
|---|
| 110 | nfit++; | 
|---|
| 111 | if(nfit>10) break; | 
|---|
| 112 | } | 
|---|
| 113 | } | 
|---|
| 114 |  | 
|---|
| 115 | pos<<PPFNameTag("nt")<<nt; | 
|---|
| 116 | pos<<PPFNameTag("cublis")<<Cube; | 
|---|
| 117 |  | 
|---|
| 118 | } | 
|---|
| 119 |  | 
|---|
| 120 | //-------------------------------------------------- | 
|---|
| 121 | MyFCN::MyFCN(double nu0, double dnu,TVector<r_8>& V,TVector<r_8>& EV) | 
|---|
| 122 | : _V(V,false), _EV(EV,false) | 
|---|
| 123 | { | 
|---|
| 124 | _ndata =_V.Size(); | 
|---|
| 125 | _nu0 = nu0; | 
|---|
| 126 | _dnu = dnu; | 
|---|
| 127 | } | 
|---|
| 128 |  | 
|---|
| 129 | void MyFCN::InitFit(MnUserParameters& upar) | 
|---|
| 130 | { | 
|---|
| 131 | int n = _V.Size()-1; | 
|---|
| 132 | double a = _V(0); | 
|---|
| 133 | double ni = log(_V(n)/a) / log(1.+n*_dnu/_nu0); | 
|---|
| 134 |  | 
|---|
| 135 | upar.Add("A",a,a/50.); | 
|---|
| 136 | upar.Add("N",ni,fabs(ni/50.)); | 
|---|
| 137 | } | 
|---|
| 138 |  | 
|---|
| 139 | double MyFCN::Func(int ix,const vector<double>& par) const | 
|---|
| 140 | // f = A*(nu/nu0)^N   avec  nu = nu0 + i*dnu | 
|---|
| 141 | { | 
|---|
| 142 | double x = (_nu0 + ix*_dnu)/_nu0; | 
|---|
| 143 | double f = par[0]*pow(x,par[1]); | 
|---|
| 144 | return f; | 
|---|
| 145 | } | 
|---|
| 146 |  | 
|---|
| 147 | double MyFCN::operator()(const vector<double>& par) const | 
|---|
| 148 | { | 
|---|
| 149 | double xi2 = 0.; | 
|---|
| 150 | _ndata = 0; | 
|---|
| 151 | for(int i=0;i<_V.Size();i++) { | 
|---|
| 152 | double e2 = _EV(i)*_EV(i); | 
|---|
| 153 | if(e2<=0.) continue; | 
|---|
| 154 | double v = _V(i); | 
|---|
| 155 | double f = Func(i,par); | 
|---|
| 156 | xi2 += (v-f)*(v-f)/e2; | 
|---|
| 157 | _ndata++; | 
|---|
| 158 | } | 
|---|
| 159 | //cout<<"par: "<<par[0]<<" "<<par[1]<<endl; | 
|---|
| 160 | return xi2; | 
|---|
| 161 | } | 
|---|
| 162 |  | 
|---|
| 163 | /* | 
|---|
| 164 | openppf cmvgsmcfit.ppf | 
|---|
| 165 |  | 
|---|
| 166 | set j 0 | 
|---|
| 167 | set k 0 | 
|---|
| 168 | n/plot v_${j}_${k}.val%n ! ! "nsta cpts" | 
|---|
| 169 | n/plot f_${j}_${k}.val%n ! ! "nsta cpts same red" | 
|---|
| 170 | n/plot r_${j}_${k}.val%n ! ! "nsta cpts" | 
|---|
| 171 |  | 
|---|
| 172 | n/plot nt.ok%_nl ! ! "cpts" | 
|---|
| 173 | n/plot nt.x2r%_nl ! ! "cpts" | 
|---|
| 174 |  | 
|---|
| 175 | n/plot nt.A%_nl ! ! "cpts" | 
|---|
| 176 | n/plot nt.N%_nl ! ! "cpts" | 
|---|
| 177 |  | 
|---|
| 178 | set n 0 | 
|---|
| 179 | objaoper cublis slicexz $n | 
|---|
| 180 | disp slicexz_$n | 
|---|
| 181 |  | 
|---|
| 182 | n/plot cublis.val%x fabs(y-5)<0.1&&fabs(z-5)<0.1 | 
|---|
| 183 | */ | 
|---|