GSI Object Oriented Online Offline (Go4)  GO4-6.3.0
TGo4FitMinuit.cxx
Go to the documentation of this file.
1 // $Id$
2 //-----------------------------------------------------------------------
3 // The GSI Online Offline Object Oriented (Go4) Project
4 // Experiment Data Processing at EE department, GSI
5 //-----------------------------------------------------------------------
6 // Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
7 // Planckstr. 1, 64291 Darmstadt, Germany
8 // Contact: http://go4.gsi.de
9 //-----------------------------------------------------------------------
10 // This software can be used under the license agreements as stated
11 // in Go4License.txt file which is part of the distribution.
12 //-----------------------------------------------------------------------
13 
14 #include "TGo4FitMinuit.h"
15 
16 #include <iostream>
17 
18 #include "TMinuit.h"
19 #include "TObjString.h"
20 
21 #include "TGo4FitterAbstract.h"
22 #include "TGo4FitMinuitResult.h"
23 
24 class TMinuitEx : public TMinuit {
25 public:
26  TMinuitEx(Int_t NumPars, TGo4FitterAbstract *fitter);
27  virtual ~TMinuitEx();
28 
29  Int_t Eval(Int_t npar, Double_t *grad, Double_t &fval, Double_t *pars, Int_t iflag) override;
30 
31 protected:
33 };
34 
35 TMinuitEx::TMinuitEx(Int_t NumPars, TGo4FitterAbstract *fitter) : TMinuit(NumPars), fxFitter(fitter) {}
36 
38 
39 Int_t TMinuitEx::Eval(Int_t npar, Double_t *grad, Double_t &fval, Double_t *pars, Int_t iflag)
40 {
41  if (fxFitter)
42  fval = fxFitter->CalculateFitFunction(pars);
43  else
44  fval = 0.;
45  return 0;
46 }
47 
48 // *******************************************************************************
49 
50 TGo4FitMinuit::TGo4FitMinuit() : TGo4FitterAction(), fxCommands(), fxResults() {}
51 
53  : TGo4FitterAction(Name, "Fitter minimization using TMinuit object"), fxCommands(), fxResults()
54 {
55  fxCommands.SetOwner(kTRUE);
56  fxResults.SetOwner(kTRUE);
57 }
58 
60 
61 void TGo4FitMinuit::AddCommand(const char *iCommand)
62 {
63  fxCommands.Add(new TObjString(iCommand));
64 }
65 
66 const char *TGo4FitMinuit::GetCommand(Int_t n) const
67 {
68  return fxCommands[n]->GetName();
69 }
70 
72 {
73 
74  TMinuitEx fMinuit(Fitter->NumPars(), Fitter);
75  fMinuit.SetPrintLevel(-1);
76 
77  for (Int_t n = 0; n < Fitter->NumPars(); n++) {
78  const char *FullName = Fitter->GetParFullName(n);
79  Int_t ierflg = 0;
80  Double_t epsilon = 0, RangeMin = 0, RangeMax = 0;
81  if (!Fitter->GetParEpsilon(FullName, epsilon))
82  epsilon = 1.;
83 
84  if (!Fitter->GetParRange(FullName, RangeMin, RangeMax)) {
85  RangeMin = 0;
86  RangeMax = 0;
87  }
88 
89  fMinuit.mnparm(n, FullName, Fitter->GetParValue(FullName), epsilon, RangeMin, RangeMax, ierflg);
90 
91  if (Fitter->GetParFixed(FullName))
92  fMinuit.FixParameter(n);
93  }
94 
95  if (fxCommands.GetLast() < 0)
96  fMinuit.Command("MIGRAD 500 1");
97  else
98  for (Int_t n = 0; n <= fxCommands.GetLast(); n++) {
99  TString cmd = ((TObjString *)fxCommands[n])->GetString();
100  if (cmd[0] == 'r') {
101  if (cmd.Index("result", 6, 0, TString::kIgnoreCase) == 0) {
102  cmd.Remove(0, 6);
103  while ((cmd.Length() > 0) && (cmd[0] == ' '))
104  cmd.Remove(0, 1);
105  if (cmd.IsNull())
106  cmd = "1000";
107  if (cmd.Length() < 4) {
108  std::cerr << "invalid result command syntax" << std::endl;
109  break;
110  }
111  Bool_t getpar = (cmd[0] == '1');
112  Bool_t geterr = (cmd[1] == '1');
113  Bool_t getmatr = (cmd[2] == '1');
114  Bool_t getcontr = (cmd[3] == '1');
115  cmd.Remove(0, 4);
116  while ((cmd.Length() > 0) && (cmd[0] == ' '))
117  cmd.Remove(0, 1);
118  if (cmd.IsNull())
119  cmd = "Result";
120 
121  TGo4FitMinuitResult *res = new TGo4FitMinuitResult(cmd, "TMinuit result object");
122  fxResults.Add(res);
123  res->CallMNSTAT(&fMinuit);
124  if (getpar)
125  res->CallMNPOUT(&fMinuit, Fitter->NumPars());
126  if (geterr)
127  res->CallMNERRS(&fMinuit, Fitter->NumPars());
128  if (getmatr)
129  res->CallMNEMAT(&fMinuit, Fitter->NumPars(), kTRUE);
130  if (getcontr)
131  res->GetContourPlot(&fMinuit);
132  }
133 
134  } else
135  fMinuit.Command(cmd);
136  }
137 
138  for (Int_t n = 0; n < Fitter->NumPars(); n++) {
139  Double_t value, error;
140  fMinuit.GetParameter(n, value, error);
141  Fitter->SetParValue(Fitter->GetParFullName(n), value);
142  Fitter->SetParError(Fitter->GetParFullName(n), error);
143  }
144 }
145 
147 {
148  return (indx >= 0) && (indx <= fxResults.GetLast()) ? (TGo4FitMinuitResult *)fxResults.At(indx) : nullptr;
149 }
150 
152 {
153  return (TGo4FitMinuitResult *)fxResults.FindObject(ResName);
154 }
155 
157 {
158  fxResults.Add(res);
159 }
160 
162 {
163  fxResults.Remove(res);
164  fxResults.Compress();
165 }
166 
167 void TGo4FitMinuit::Print(Option_t *option) const
168 {
169  TGo4FitterAction::Print(option);
170  if (fxCommands.GetLast() >= 0)
171  std::cout << "List of commands:" << std::endl;
172  for (Int_t n = 0; n <= fxCommands.GetLast(); n++)
173  std::cout << " " << fxCommands[n]->GetName() << std::endl;
174  if (fxResults.GetLast() >= 0) {
175  std::cout << "List of stored results:" << std::endl;
176  fxResults.Print(option);
177  }
178 }
Bool_t SetParValue(const char *ParName, Double_t iValue)
Int_t Eval(Int_t npar, Double_t *grad, Double_t &fval, Double_t *pars, Int_t iflag) override
void GetContourPlot(TMinuit *fMinuit)
TGo4FitterAbstract * fxFitter
void RemoveResult(TGo4FitMinuitResult *res)
const char * GetCommand(Int_t n) const
TGo4FitMinuitResult * GetResult(Int_t indx) const
TObjArray fxResults
TMinuitEx(Int_t NumPars, TGo4FitterAbstract *fitter)
void AddCommand(const char *iCommand)
Int_t NumPars() override
void CallMNERRS(TMinuit *fMinuit, Int_t nPars)
void CallMNEMAT(TMinuit *fMinuit, Int_t nPars, Bool_t DoTransform=kTRUE)
Bool_t SetParError(const char *ParName, Double_t iError)
Bool_t GetParEpsilon(const char *ParName, Double_t &Epsilon) override
const char * GetParFullName(Int_t n)
void DoAction(TGo4FitterAbstract *Fitter) override
virtual ~TMinuitEx()
virtual ~TGo4FitMinuit()
Bool_t GetParFixed(const char *ParName) override
void Print(Option_t *option="") const override
void Print(Option_t *option="") const override
TGo4FitMinuitResult * FindResult(const char *ResName)
Double_t CalculateFitFunction(Double_t *pars=nullptr)
void CallMNSTAT(TMinuit *fMinuit)
void AddResult(TGo4FitMinuitResult *res)
Bool_t GetParRange(const char *ParName, Double_t &RangeMin, Double_t &RangeMax) override
void CallMNPOUT(TMinuit *fMinuit, Int_t nPars)
TObjArray fxCommands
Double_t GetParValue(const char *ParName)