[3790] | 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:
|
---|
[3983] | 26 | MyFCN(TVector<r_4>& FreqMHz,TVector<r_4>& V,TVector<r_4>& EV);
|
---|
[4008] | 27 | void SetNu0(double nu0Mhz) {_nu0 = nu0Mhz;}
|
---|
| 28 | void SetTyp(bool law2 = false) {_law2 = law2;}
|
---|
[3790] | 29 | void InitFit(MnUserParameters& upar);
|
---|
[3983] | 30 | double Func(double fr,const vector<double>& par) const;
|
---|
[3790] | 31 | double operator()(const vector<double>& par) const;
|
---|
| 32 | double Up(void) const {return 1.;}
|
---|
| 33 | //protected:
|
---|
[3983] | 34 | double _nu0;
|
---|
[4008] | 35 | bool _law2;
|
---|
[3790] | 36 | mutable int _ndata;
|
---|
[3983] | 37 | TVector<r_4> _F;
|
---|
| 38 | TVector<r_4> _V;
|
---|
| 39 | TVector<r_4> _EV;
|
---|
[3790] | 40 | };
|
---|
| 41 | } } // namespace ROOT + Minuit2
|
---|
| 42 |
|
---|
| 43 | //--------------------------------------------------
|
---|
| 44 | int main(int narg,char *arg[])
|
---|
| 45 | {
|
---|
[3983] | 46 | int nslicemax = -1;
|
---|
[4008] | 47 | int typfit = 0;
|
---|
[3790] | 48 | if(narg<=1) {
|
---|
[4008] | 49 | cout<<"cmvgsmcfit cubefile.ppf [nslicemax] [typfit=0,1]"<<endl;
|
---|
[3790] | 50 | return -1;
|
---|
| 51 | }
|
---|
| 52 |
|
---|
[3983] | 53 | if(narg>2) nslicemax = atoi(arg[2]);
|
---|
[4008] | 54 | if(narg>3) typfit = atoi(arg[3]);
|
---|
| 55 | cout<<"Fitting "<<arg[1]<<" , nslicemax="<<nslicemax<<" , typfit="<<typfit<<endl;
|
---|
[3983] | 56 |
|
---|
| 57 | int rc = 0;
|
---|
| 58 | try {
|
---|
| 59 |
|
---|
[3790] | 60 | POutPersist pos("cmvgsmcfit.ppf");
|
---|
| 61 | PInPersist pis(arg[1]);
|
---|
| 62 | TArray<r_4> Cube;
|
---|
| 63 | pis>>PPFNameTag("cube")>>Cube;
|
---|
[3983] | 64 | TVector<r_4> Freq;
|
---|
| 65 | pis>>PPFNameTag("freq")>>Freq;
|
---|
[3790] | 66 |
|
---|
[4008] | 67 | const int nvar = 10;
|
---|
| 68 | const char *vname[nvar] = {"x2r","ok","ph","th","v0","vn","A","N","B","DN"};
|
---|
[3790] | 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++) {
|
---|
[3983] | 74 | cout<<"...j = "<<j<<endl;
|
---|
[3790] | 75 | for(int k=0;k<Cube.SizeZ();k++) {
|
---|
[4008] | 76 | //cout<<"...k = "<<k<<endl;
|
---|
[3983] | 77 |
|
---|
| 78 | TVector<r_4> V(Cube.SizeX()), EV(Cube.SizeX());
|
---|
[3790] | 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 |
|
---|
[3983] | 84 | MyFCN myfcn(Freq,V,EV);
|
---|
| 85 | myfcn.SetNu0(Freq(0));
|
---|
[4008] | 86 | //myfcn.SetNu0((Freq(0)+Freq(Freq.Size()-1))/2.);
|
---|
| 87 | myfcn.SetTyp( ((typfit==1)? true: false) );
|
---|
[3790] | 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;
|
---|
[3983] | 110 | xnt[4] = V(0); xnt[5] = V(V.Size()-1);
|
---|
[4008] | 111 | for(int i=6;i<6+par.size() && i<nvar;i++) xnt[i] = par[i-6];
|
---|
[3790] | 112 | nt.Fill(xnt);
|
---|
| 113 | //vector<double> err = ustate.Errors();
|
---|
[3983] | 114 | for(int i=0;i<Cube.SizeX();i++) Cube(i,j,k) -= myfcn.Func(Freq(i),par);
|
---|
[3790] | 115 |
|
---|
| 116 | if(nfit<10) {
|
---|
| 117 | TVector<r_8> F(Cube.SizeX()), R(Cube.SizeX());
|
---|
| 118 | for(int i=0;i<Cube.SizeX();i++) {
|
---|
[3983] | 119 | F(i) = myfcn.Func(Freq(i),par);
|
---|
[3790] | 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 | }
|
---|
[3983] | 130 |
|
---|
[3790] | 131 | nfit++;
|
---|
[3983] | 132 |
|
---|
[3790] | 133 | }
|
---|
[3983] | 134 | if(nslicemax>0 && j>=nslicemax) break;
|
---|
[3790] | 135 | }
|
---|
| 136 |
|
---|
[3983] | 137 | cout<<"nfit = "<<nfit<<endl;
|
---|
[3790] | 138 | pos<<PPFNameTag("nt")<<nt;
|
---|
| 139 | pos<<PPFNameTag("cublis")<<Cube;
|
---|
| 140 |
|
---|
[3983] | 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;
|
---|
[3790] | 152 | }
|
---|
| 153 |
|
---|
[3983] | 154 | return rc;
|
---|
| 155 | }
|
---|
| 156 |
|
---|
[3790] | 157 | //--------------------------------------------------
|
---|
[3983] | 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)
|
---|
[3790] | 160 | {
|
---|
[3983] | 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);
|
---|
[4008] | 164 | _law2 = false;
|
---|
[3790] | 165 | _ndata =_V.Size();
|
---|
| 166 | }
|
---|
| 167 |
|
---|
| 168 | void MyFCN::InitFit(MnUserParameters& upar)
|
---|
| 169 | {
|
---|
[3983] | 170 | int n = _F.Size() - 1;
|
---|
[3790] | 171 | double a = _V(0);
|
---|
[3983] | 172 | double ni = log(_V(n)/a) / log(_F(n)/_nu0);
|
---|
[3790] | 173 |
|
---|
| 174 | upar.Add("A",a,a/50.);
|
---|
[4008] | 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 |
|
---|
[3790] | 181 | }
|
---|
| 182 |
|
---|
[3983] | 183 | double MyFCN::Func(double fr,const vector<double>& par) const
|
---|
[4008] | 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)
|
---|
[3790] | 186 | {
|
---|
[3983] | 187 | double f = par[0]*pow(fr/_nu0,par[1]);
|
---|
[4008] | 188 | if(_law2) f *= 1. + par[2]*pow(fr/_nu0,par[3]);
|
---|
[3790] | 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);
|
---|
[3983] | 200 | double f = Func(_F(i),par);
|
---|
[3790] | 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
|
---|
[3983] | 213 | zone 1 2
|
---|
[3790] | 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 |
|
---|
[3983] | 218 | zone 1 2
|
---|
| 219 | n/plot nt.ok%_nl ! ! "crossmarker3"
|
---|
| 220 | n/plot nt.x2r%_nl ! ! "crossmarker3"
|
---|
[3790] | 221 |
|
---|
[3983] | 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"
|
---|
[3790] | 226 |
|
---|
[3983] | 227 | zone
|
---|
[4008] | 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"
|
---|
[3983] | 232 |
|
---|
[4008] | 233 | n/plot nt.A%v0 ok>0 ! "crossmarker3"
|
---|
| 234 | n/plot nt.(A-v0)/v0%_nl ok>0 ! "crossmarker3"
|
---|
[3983] | 235 |
|
---|
[4008] | 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 |
|
---|
[3790] | 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 | */
|
---|