source: trunk/MagicSoft/Mars/mjoptim/MJOptimize.cc@ 7392

Last change on this file since 7392 was 7152, checked in by tbretz, 19 years ago
*** empty log message ***
File size: 22.4 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz, 9/2004 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2004
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MJOptimize
28//
29// Class for otimizing the parameters of the supercuts
30//
31// Minimization Control
32// ====================
33//
34// To choose the minimization algorithm use:
35// void SetOptimizer(Optimizer_t o);
36//
37// Allowed options are:
38// enum Optimizer_t
39// {
40// kMigrad, // Minimize by the method of Migrad
41// kSimplex, // Minimize by the method of Simplex
42// kMinimize, // Migrad + Simplex (if Migrad fails)
43// kMinos, // Minos error determination
44// kImprove, // Local minimum search
45// kSeek, // Minimize by the method of Monte Carlo
46// kNone // Skip optimization
47// };
48//
49// For more details on the methods see TMinuit.
50//
51//
52// You can change the behaviour of the minimization using
53//
54// void SetNumMaxCalls(UInt_t num=0);
55// void SetTolerance(Float_t tol=0);
56//
57// While NumMaxCalls is the first, Tolerance the second arguement.
58// For more details start root and type
59//
60// gMinuit->mnhelp("command")
61//
62// while command can be
63// * MIGRAD
64// * SIMPLEX
65// * MINIMIZE
66// * MINOS
67// * IMPROVE
68// * SEEK
69//
70// The default (num==0 and tol==0) should always give you the
71// corresponding defaults used in Minuit.
72//
73//
74// FIXME: Implement changing cut in hadronness...
75// FIXME: Show MHSignificance on MStatusDisplay during filling...
76// FIXME: Choose step-size percentage as static data membewr
77// FIXME: Choose minimization method
78//
79/////////////////////////////////////////////////////////////////////////////
80#include "MJOptimize.h"
81
82#include <TMinuit.h>
83#include <TVirtualFitter.h>
84
85#include <TStopwatch.h>
86
87#include <TCanvas.h>
88
89#include <TGraph.h>
90#include <TMultiGraph.h>
91
92#include "MHMatrix.h"
93
94// environment
95#include "MLog.h"
96#include "MLogManip.h"
97
98#include "MDirIter.h"
99#include "MStatusDisplay.h"
100
101// eventloop
102#include "MParList.h"
103#include "MTaskList.h"
104#include "MEvtLoop.h"
105
106// parameters
107#include "MParameters.h"
108
109// tasks
110#include "MReadTree.h"
111#include "MMatrixLoop.h"
112#include "MFillH.h"
113
114// filters
115#include "MF.h"
116#include "MFilterList.h"
117
118using namespace std;
119
120//------------------------------------------------------------------------
121//
122// fcn calculates the function to be minimized (using TMinuit::Migrad)
123//
124void MJOptimize::fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
125{
126 MJOptimize *optim = (MJOptimize*)gMinuit->GetObjectFit();
127
128 // WORKAROUND --- FOR WHAT?
129 if (gMinuit->fEpsi<1e-2)
130 {
131 *optim->fLog << warn << "WARNING - For unknown reasons: fEspi<1e-100... resetting to 0.01." << endl;
132 gMinuit->fEpsi = 0.01;
133 }
134
135 TMinuit *minuit = gMinuit;
136 f = optim->Fcn(TArrayD(TMath::Min(gMinuit->fMaxpar, optim->fParameters.GetSize()), par), minuit);
137 gMinuit = minuit;
138
139}
140
141Double_t MJOptimize::Fcn(const TArrayD &par, TMinuit *minuit)
142{
143 if (fEvtLoop->GetDisplay()!=fDisplay)
144 return 0;
145 /*
146 switch(iflag)
147 {
148 case 1: // first call
149 case 2: // calc derivative
150 break;
151 case 3:
152 // last call
153 MStatusDisplay *d = new MStatusDisplay;
154 fEvtLoop->SetDisplay(d);
155 break;
156 }
157 */
158 MParList *plist = fEvtLoop->GetParList();
159
160 MParameterD *eval = (MParameterD*)plist->FindObject(fNameMinimizationValue, "MParameterD");
161 MParContainer *pars = (MParContainer*)plist->FindObject("MParameters", "MParContainer");
162
163 MRead *read = (MRead*)plist->FindObject("MTaskList")->FindObject("MRead");
164 if (read)
165 read->Rewind();
166
167 if (fDebug>=0)
168 {
169 *fLog << inf << "New Set: ";
170 for (Int_t i=0; i<fParameters.GetSize(); i++)
171 *fLog << par[i] << " ";
172 *fLog << endl;
173 }
174
175 pars->SetVariables(par);
176 eval->SetVal(0);
177
178 const Bool_t isnull = gLog.IsNullOutput();
179 if (fDebug<3)
180 gLog.SetNullOutput(kTRUE);
181
182 TStopwatch clock;
183 clock.Start();
184 fEvtLoop->Eventloop(fNumEvents, MEvtLoop::kNoStatistics);
185 clock.Stop();
186
187 if (fDebug<3)
188 gLog.SetNullOutput(isnull);
189
190 const Double_t f = eval->GetVal();
191
192 if (fDebug>=0)
193 *fLog << inf << "Result F=" << f << endl;
194
195 if (fDebug>=1 && minuit)
196 {
197 Double_t fmin, fedm, errdef;
198 Int_t n1, n2, istat;
199 minuit->mnstat(fmin, fedm, errdef, n1, n2, istat);
200 *fLog << inf << underline << "Minimization Status so far:" << endl;
201 *fLog << " Calls: " << minuit->fNfcn << " (max=" << gMinuit->fMaxIterations << ")" << endl;
202 *fLog << " Parameters: fixed=" << gMinuit->fNpfix << ", free=" << gMinuit->fNpar << endl;
203 *fLog << " Func min: " << fmin << " (Epsi=" << gMinuit->fEpsi << ", Apsi=" << gMinuit->fApsi << ")" << endl;
204 *fLog << " Found edm: " << fedm << endl;
205 *fLog << " ErrDef: " << errdef << endl;
206 *fLog << " Status: ";
207
208 switch (istat)
209 {
210 case 0: *fLog << "n/a" << endl; break;
211 case 1: *fLog << "approximation only, not accurate" << endl; break;
212 case 2: *fLog << "full matrix, but forced positive-definite" << endl; break;
213 case 3: *fLog << "full accurate covariance matrix" << endl; break;
214 default: *fLog << "undefined" << endl; break;
215 }
216 }
217
218 if (fDebug>=1)
219 {
220 clock.Print();
221 fEvtLoop->GetTaskList()->PrintStatistics();
222 }
223
224 return f;
225}
226
227MJOptimize::MJOptimize() : fDebug(-1), fNumEvents(0), fType(kSimplex), fNumMaxCalls(0), fTolerance(0), fTestTrain(0), fNameMinimizationValue("MinimizationValue")
228{
229 fRules.SetOwner();
230 fFilter.SetOwner();
231
232 fNamesOn.SetOwner();
233 fNamesOff.SetOwner();
234}
235
236//------------------------------------------------------------------------
237//
238// Add seqeunces from list to reader
239//
240Bool_t MJOptimize::AddSequences(MRead &read, TList &list) const
241{
242 MDirIter files;
243
244 TIter Next(&list);
245 TObject *o=0;
246 while ((o=Next()))
247 {
248 MSequence seq(o->GetName());
249 if (!seq.IsValid())
250 return kFALSE;
251
252 seq.SetupDatRuns(files, o->GetTitle(), "I");
253 }
254
255 return read.AddFiles(files)>0;
256}
257
258//------------------------------------------------------------------------
259//
260// Add on-sequences:
261// - fname: sequence file name (with path)
262// - dir: directory were image files are stored
263//
264void MJOptimize::AddSequenceOn(const char *fname, const char *dir)
265{
266 fNamesOn.Add(new TNamed(fname, dir));
267}
268
269//------------------------------------------------------------------------
270//
271// Add off-sequences:
272// - fname: sequence file name (with path)
273// - dir: directory were image files are stored
274//
275void MJOptimize::AddSequenceOff(const char *fname, const char *dir)
276{
277 fNamesOff.Add(new TNamed(fname, dir));
278}
279
280//------------------------------------------------------------------------
281//
282// Empty list of on- and off-sequences
283//
284void MJOptimize::ResetSequences()
285{
286 fNamesOn.Delete();
287 fNamesOff.Delete();
288}
289
290//------------------------------------------------------------------------
291//
292// Add a parameter used in your filters (see AddFilter) The parameter
293// index is returned,
294//
295// Int_t idx = AddParameter("log10(MHillas.fSize)");
296//
297// The indices area starting with 0 always.
298//
299Int_t MJOptimize::AddParameter(const char *rule)
300{
301 fRules.Add(new TNamed(rule, ""));
302 return fRules.GetSize()-1;
303}
304
305//------------------------------------------------------------------------
306//
307// Add a filter which can be applied in the optimization (for deatils
308// see correspodning Run function) You can use the indices you got by
309// AddParameter, eg
310//
311// AddFilter("M[0] < 3.2");
312//
313// if used in optimization you can do
314//
315// AddFilter("M[0] < [0]");
316//
317// for more details, see SetParameter and FixParameter
318//
319void MJOptimize::AddFilter(const char *rule)
320{
321 fFilter.Add(new MF(rule));
322}
323
324//------------------------------------------------------------------------
325//
326// Add a cut which is used to fill the matrix, eg "MMcEvt.fOartId<1.5"
327// (The rule is applied, nit inverted: The matrix is filled with
328// the events fullfilling the condition)
329//
330void MJOptimize::AddPreCut(const char *rule)
331{
332 MFilter *f = new MF(rule);
333 f->SetBit(kCanDelete);
334 AddPreCut(f);
335}
336
337//------------------------------------------------------------------------
338//
339// Add a cut which is used to fill the matrix. If kCanDelete is set
340// MJOptimize takes the ownership.
341//
342void MJOptimize::AddPreCut(MFilter *f)
343{
344 fPreCuts.Add(f);
345}
346
347//------------------------------------------------------------------------
348//
349// Set the fParameters Array accoring to par.
350//
351void MJOptimize::SetParameters(const TArrayD &par)
352{
353 fParameters = par;
354}
355
356//------------------------------------------------------------------------
357//
358// Set the number of events processed by the eventloop. (Be carfull,
359// if you are doing on-off analysis and you only process the first
360// 1000 events which are on-events only the optimization may not work)
361//
362void MJOptimize::SetNumEvents(UInt_t n)
363{
364 fNumEvents=n;
365}
366
367//------------------------------------------------------------------------
368//
369// Set a debug level, which tells the optimization how much information
370// is displayed about and in the running eventloop.
371//
372void MJOptimize::SetDebug(UInt_t n)
373{
374 fDebug=n;
375}
376
377//------------------------------------------------------------------------
378//
379// Set a optimization algorithm to be used. For more information see
380// TMinuit.
381//
382// Available Algorithms are:
383// kMigrad, // Minimize by the method of Migrad
384// kSimplex, // Minimize by the method of Simplex
385// kSeek // Minimize by the method of Monte Carlo
386//
387void MJOptimize::SetOptimizer(Optimizer_t o)
388{
389 fType = o;
390}
391
392//------------------------------------------------------------------------
393//
394// If a status didplay is set, search for tab "Optimizer".
395// If not found, create it.
396// In the tab search for TMultiGraph "Parameters".
397// If not found create it.
398// If empty create TGraphs.
399// Check number of graphs vs. number of parameters.
400// return TList with graphs.
401//
402TList *MJOptimize::GetPlots() const
403{
404 if (!fDisplay)
405 return NULL;
406
407 TCanvas *c=fDisplay->GetCanvas("Optimizer");
408 if (!c)
409 c = &fDisplay->AddTab("Optimizer");
410
411 TMultiGraph *mg = dynamic_cast<TMultiGraph*>(c->FindObject("Parameters"));
412 if (!mg)
413 mg = new TMultiGraph("Parameters", "Parameters of optimization");
414
415 TList *l = mg->GetListOfGraphs();
416 if (!l)
417 {
418 const Int_t n = fParameters.GetSize();
419 for (int i=0; i<n+1; i++)
420 {
421 TGraph *g = new TGraph;
422 if (i==n)
423 g->SetLineColor(kBlue);
424 mg->Add(g, "");
425 AddPoint(mg->GetListOfGraphs(), i, i==n?1:fParameters[i]);
426 }
427 mg->SetBit(kCanDelete);
428 mg->Draw("al*");
429
430 l = mg->GetListOfGraphs();
431 }
432
433 return l->GetSize() == fParameters.GetSize()+1 ? l : NULL;
434}
435
436//------------------------------------------------------------------------
437//
438// Add a point with y=val as last point in idx-th Tgraph of list l.
439//
440void MJOptimize::AddPoint(TList *l, Int_t idx, Float_t val) const
441{
442 if (!l)
443 return;
444
445 TGraph *gr = (TGraph*)l->At(idx);
446 gr->SetPoint(gr->GetN(), gr->GetN(), val);
447}
448
449Int_t MJOptimize::Minuit(TMinuit &minuit, const char *cmd) const
450{
451 Int_t err;
452 Double_t tmp[2] = { fNumMaxCalls, fTolerance };
453 minuit.mnexcm(cmd, tmp, 2, err);
454
455 switch (err)
456 {
457 case 0:
458 *fLog << inf << GetDescriptor() << " TMinuit::mnexcm excuted normally." << endl;
459 break;
460 case 1:
461 *fLog << warn << GetDescriptor() << " TMinuit::mnexcm command is blank... ignored." << endl;
462 break;
463 case 2:
464 *fLog << warn << GetDescriptor() << " TMinuit::mnexcm command-line syntax error... ignored." << endl;
465 break;
466 case 3:
467 *fLog << warn << GetDescriptor() << " TMinuit::mnexcm unknown command... ignored." << endl;
468 break;
469 case 4:
470 *fLog << warn << GetDescriptor() << " TMinuit::mnexcm - Abnormal termination (eg Migrad not converged)" << endl;
471 break;
472 /*
473 case 5:
474 *fLog << inf << GetDescriptor() << " TMinuit::mnexcm - Parameters requested." << endl;
475 break;
476 case 6:
477 *fLog << inf << GetDescriptor() << " TMinuit::mnexcm - SET INPUT returned." << endl;
478 break;
479 case 7:
480 *fLog << inf << GetDescriptor() << " TMinuit::mnexcm - SET TITLE returned." << endl;
481 break;
482 case 8:
483 *fLog << inf << GetDescriptor() << " TMinuit::mnexcm - SET COVAR returned." << endl;
484 break;
485 case 9:
486 *fLog << inf << GetDescriptor() << " TMinuit::mnexcm - reserved." << endl;
487 break;
488 case 10:
489 *fLog << inf << GetDescriptor() << " TMinuit::mnexcm - END returned." << endl;
490 break;
491 case 11:
492 *fLog << inf << GetDescriptor() << " TMinuit::mnexcm - EXIT or STOP returned." << endl;
493 break;
494 case 12:
495 *fLog << inf << GetDescriptor() << " TMinuit::mnexcm - RETURN returned." << endl;
496 break;*/
497 }
498
499 return err;
500}
501
502Bool_t MJOptimize::Optimize(MEvtLoop &evtloop)
503{
504 if (fParameters.GetSize()==0)
505 {
506 *fLog << err << GetDescriptor() << "::Optimize: ERROR - Sorry, no parameters defined." << endl;
507 return kFALSE;
508 }
509
510 if (fType==kNone)
511 return kTRUE;
512
513 gMinuit = new TMinuit(fParameters.GetSize());
514
515 gMinuit->SetFCN(fcn);
516 gMinuit->SetObjectFit(this);
517 gMinuit->SetPrintLevel(-1); // Don't print when DefineParameter
518
519 //
520 // Set starting values and step sizes for parameters
521 //
522 for (Int_t i=0; i<fParameters.GetSize(); i++)
523 {
524 TString name = "par[";
525 name += i;
526 name += "]";
527 Double_t vinit = fParameters[i];
528 Double_t step = fStep[i];
529
530 Double_t limlo = fLimLo[i];
531 Double_t limup = fLimUp[i];
532
533 Bool_t rc = gMinuit->DefineParameter(i, name, vinit, step, limlo, limup);
534 if (rc)
535 {
536 *fLog << err << dbginf << "Error in defining parameter #" << i << endl;
537 return kFALSE;
538 }
539
540 if (step==0)
541 gMinuit->FixParameter(i);
542 }
543
544 gMinuit->SetPrintLevel(1); // Switch on pritning again
545 gMinuit->mnprin(1,0); // Print all parameters
546
547 fEvtLoop = &evtloop;
548
549 TList *g=GetPlots();
550
551 // Now ready for minimization step:
552 TStopwatch clock;
553 clock.Start();
554 switch (fType)
555 {
556 case kSimplex:
557 Simplex(*gMinuit);
558 break;
559 case kMigrad:
560 Migrad(*gMinuit);
561 break;
562 case kMinimize:
563 Minimize(*gMinuit);
564 break;
565 case kMinos:
566 Minos(*gMinuit);
567 break;
568 case kImprove:
569 Improve(*gMinuit);
570 break;
571 case kSeek:
572 Seek(*gMinuit);
573 break;
574 case kNone: // Should never happen
575 return kFALSE;
576 }
577 clock.Stop();
578 clock.Print();
579
580 if (evtloop.GetDisplay()!=fDisplay)
581 {
582 *fLog << inf << "Optimization aborted by user." << endl;
583 fDisplay = 0;
584 return kFALSE;
585 }
586
587 *fLog << inf << "Resulting Chisq: " << gMinuit->fAmin << endl;
588
589 //
590 // Update values of fA, fB:
591 //
592 for (Int_t i=0; i<fParameters.GetSize(); i++)
593 {
594 Double_t x1, x2;
595 gMinuit->GetParameter(i,x1,x2);
596 fParameters[i] = x1;
597 cout << i << ": " << fParameters[i] << endl;
598
599 AddPoint(g, i, x1);
600 }
601 AddPoint(g, fParameters.GetSize(), gMinuit->fAmin);
602
603 delete gMinuit;
604
605 return kTRUE;
606}
607
608//------------------------------------------------------------------------
609//
610// Optimize allows to use the optimizing by an eventloop based on
611// some requirements.
612//
613// 1) The tasklist to be executed must have the name MTaskList and
614// be an entry in the parameterlist.
615//
616// 2) The reading task (MReadMarsFile, MMatrixLoop) must have the name
617// "MRead". If it derives from MRead Rewind() must be implemented,
618// otherwise it must start reading from scratch each time its
619// PreProcess is called.
620//
621// 3) The parameters to be optimized must be accessed through (currently)
622// a single parameter container (MParContainer) called MParameters.
623// The parameters are set through SetVariables.
624//
625// 4) The result of a single function call for minimization (eg. chisquare)
626// must be available after the eventloop in a container of type
627// MParameterD with the name "MinimizationResult".
628//
629// 5) The parameters to start with must have been set using
630// MJOptimize::SetParameter or MJOptimize::SetParameters and
631// MJOptimize::FixParameter
632//
633// The behaviour of the optimization can be changed using:
634// void SetNumEvents(UInt_t n);
635// void SetDebug(UInt_t n);
636// void SetOptimizer(Optimizer_t o);
637//
638// After optimization the resulting parameters are set and another eventloop
639// with a MStatusDisplay is set is called. The resulting parameters can be
640// accessed using: GetParameters()
641//
642// To be fixed:
643// - MStatusDisplay should show status while optimization is running
644// - write result into MStatusDisplay
645// - save result
646//
647Bool_t MJOptimize::Optimize(MParList &parlist)
648{
649 // Checks to make sure, that fcn doesn't crash
650 if (!parlist.FindCreateObj("MParameterD", fNameMinimizationValue))
651 return kFALSE;
652
653 if (!parlist.FindObject("MParameters", "MParContainer"))
654 {
655 *fLog << err << "MParameters [MParContainer] not found... abort." << endl;
656 return kFALSE;
657 }
658
659 MMatrixLoop *loop = dynamic_cast<MMatrixLoop*>(parlist.FindTask("MRead"));
660
661 TString txt("Starting ");
662 switch (fType)
663 {
664 case kMigrad: txt += "Migrad"; break;
665 case kMinimize: txt += "Minimize"; break;
666 case kMinos: txt += "Minos"; break;
667 case kImprove: txt += "Improve"; break;
668 case kSimplex: txt += "Simplex"; break;
669 case kSeek: txt += "Seek"; break;
670 case kNone: txt += "no"; break;
671 }
672 txt += " optimization";
673
674 fLog->Separator(txt);
675
676 // Setup eventloop
677 MEvtLoop evtloop;
678 evtloop.SetParList(&parlist);
679 evtloop.SetDisplay(fDisplay); // set display for evtloop and all childs
680 parlist.SetDisplay(0); // reset display for all contents of parlist and tasklist
681 evtloop.SetPrivateDisplay(); // prevent display from being cascaded again in PreProcess
682
683 *fLog << inf << "Number of Parameters: " << fParameters.GetSize() << endl;
684
685 // In case the reader is the matrix loop and testrain is enabled
686 // switch on even mode...
687 if (loop && TMath::Abs(fTestTrain)>0)
688 loop->SetOperationMode(fTestTrain>0?MMatrixLoop::kEven:MMatrixLoop::kOdd);
689
690 if (!Optimize(evtloop))
691 return kFALSE;
692
693 gMinuit = 0;
694
695 fEvtLoop->SetDisplay(fDisplay);
696 if (!Fcn(fParameters))
697 return kFALSE;
698
699 // In case the reader is the matrix loop and testrain is enabled
700 // switch on odd mode...
701 if (!loop || fTestTrain==0)
702 return kTRUE;
703
704 loop->SetOperationMode(fTestTrain<0?MMatrixLoop::kEven:MMatrixLoop::kOdd);
705
706 // Done already in Fcn
707 // list.SetVariables(fParameters);
708 return Fcn(fParameters);
709}
710
711void MJOptimize::AddRulesToMatrix(MHMatrix &m) const
712{
713 TIter Next1(&fRules);
714 TObject *o1=0;
715 while ((o1=Next1()))
716 m.AddColumn(o1->GetName());
717}
718
719//------------------------------------------------------------------------
720//
721// Fill matrix m by using read. Use rules as a filter if userules.
722//
723Bool_t MJOptimize::FillMatrix(MReadTree &read, MParList &parlist, Bool_t userules)
724{
725 MHMatrix *m = (MHMatrix*)parlist.FindObject("M", "MHMatrix");
726 if (!m)
727 {
728 *fLog << err << "MJOptimize::FillMatrix - ERROR: M [MHMatrix] not found in parlist... abort." << endl;
729 return kFALSE;
730 }
731
732 m->Print("cols");
733
734 //MParList parlist;
735
736 // MGeomCamMagic cam;
737 // parlist.AddToList(&cam);
738
739 MTaskList tlist;
740 parlist.Replace(&tlist);
741
742 MFillH fillh(m);
743
744 tlist.AddToList(&read);
745
746 MFilterList list;
747 if (!list.AddToList(fPreCuts))
748 *fLog << err << "ERROR - Calling MFilterList::AddToList for fPreCuts failed!" << endl;
749 if (userules)
750 SetupFilters(list);
751 list.SetName("PreCuts"); // reset Name set by SetupFilters
752 list.SetInverted(kFALSE); // reset inversion set by SetupFilters
753 fillh.SetFilter(&list);
754 tlist.AddToList(&list);
755
756 tlist.AddToList(&fillh);
757
758 MEvtLoop fillloop;
759 fillloop.SetParList(&parlist);
760 fillloop.SetDisplay(fDisplay);
761 if (!fillloop.Eventloop(fNumEvents))
762 {
763 *fLog << err << "Filling matrix failed..." << endl;
764 return kFALSE;
765 }
766
767 *fLog << inf << "Read events from file '" << read.GetFileName() << "'" << endl;
768
769 if (fillloop.GetDisplay()!=fDisplay)
770 {
771 fDisplay = 0;
772 *fLog << inf << "Optimization aborted by user." << endl;
773 return kFALSE;
774 }
775
776 m->Print("size");
777
778 return kTRUE;
779}
780
781//------------------------------------------------------------------------
782//
783// Adds all filters to MFilterList
784//
785void MJOptimize::SetupFilters(MFilterList &list, MFilter *filter) const
786{
787 list.SetName("MParameters");
788 list.SetInverted();
789
790 if (filter)
791 {
792 if (fFilter.GetSize()>0)
793 {
794 *fLog << inf;
795 *fLog << "INFORMATION - You are using an external filter and internal filters." << endl;
796 *fLog << " Please make sure that all parameters '[i]' are starting" << endl;
797 *fLog << " behind the number of parameters of the external filter." << endl;
798 }
799 list.AddToList(filter);
800 }
801
802 if (!list.AddToList(fFilter))
803 *fLog << err << "ERROR - Calling MFilterList::AddToList fFilter failed!" << endl;
804
805 *fLog << inf << "Filter: ";
806 list.Print();
807 *fLog << endl;
808}
Note: See TracBrowser for help on using the repository browser.