source: trunk/MagicSoft/Mars/mjobs/MJOptimize.cc@ 7022

Last change on this file since 7022 was 7001, checked in by tbretz, 20 years ago
*** empty log message ***
File size: 29.1 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 "MParList.h"
93#include "MTaskList.h"
94#include "MGeomCamCT1.h"
95#include "MFEventSelector.h"
96#include "MFDataMember.h"
97#include "MReadTree.h"
98#include "MHMatrix.h"
99#include "MEnergyEstimate.h"
100#include "MMatrixLoop.h"
101#include "MChisqEval.h"
102#include "MEvtLoop.h"
103#include "MDataElement.h"
104#include "MDataMember.h"
105#include "MLog.h"
106#include "MLogManip.h"
107#include "MParameters.h"
108#include "MFillH.h"
109#include "MF.h"
110#include "MFilterList.h"
111#include "../mfilter/MFMagicCuts.h"
112#include "MContinue.h"
113#include "MGeomCamMagic.h"
114#include "MHillasSrcCalc.h"
115#include "MHMatrix.h"
116#include "MMatrixLoop.h"
117#include "../mhflux/MHAlpha.h"
118#include "MStatusDisplay.h"
119#include "../mhflux/MHEnergyEst.h"
120#include "MDirIter.h"
121#include "MSequence.h"
122
123using namespace std;
124
125//------------------------------------------------------------------------
126//
127// fcn calculates the function to be minimized (using TMinuit::Migrad)
128//
129void MJOptimize::fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
130{
131 MJOptimize *optim = (MJOptimize*)gMinuit->GetObjectFit();
132
133 // WORKAROUND --- FOR WHAT?
134 if (gMinuit->fEpsi<1e-2)
135 {
136 *optim->fLog << warn << "WARNING - For unknown reasons: fEspi<1e-100... resetting to 0.01." << endl;
137 gMinuit->fEpsi = 0.01;
138 }
139
140 TMinuit *minuit = gMinuit;
141 f = optim->Fcn(TArrayD(TMath::Min(gMinuit->fMaxpar, optim->fParameters.GetSize()), par), minuit);
142 gMinuit = minuit;
143
144}
145
146Double_t MJOptimize::Fcn(const TArrayD &par, TMinuit *minuit)
147{
148 if (fEvtLoop->GetDisplay()!=fDisplay)
149 return 0;
150 /*
151 switch(iflag)
152 {
153 case 1: // first call
154 case 2: // calc derivative
155 break;
156 case 3:
157 // last call
158 MStatusDisplay *d = new MStatusDisplay;
159 fEvtLoop->SetDisplay(d);
160 break;
161 }
162 */
163 MParList *plist = fEvtLoop->GetParList();
164
165 MParameterD *eval = (MParameterD*)plist->FindObject("MinimizationValue", "MParameterD");
166 MParContainer *pars = (MParContainer*)plist->FindObject("MParameters", "MParContainer");
167
168 MRead *read = (MRead*)plist->FindObject("MTaskList")->FindObject("MRead");
169 if (read)
170 read->Rewind();
171
172 if (fDebug>=0)
173 {
174 *fLog << inf << "New Set: ";
175 for (Int_t i=0; i<fParameters.GetSize(); i++)
176 *fLog << par[i] << " ";
177 *fLog << endl;
178 }
179
180 pars->SetVariables(par);
181 eval->SetVal(0);
182
183 const Bool_t isnull = gLog.IsNullOutput();
184 if (fDebug<3)
185 gLog.SetNullOutput(kTRUE);
186
187 TStopwatch clock;
188 clock.Start();
189 fEvtLoop->Eventloop(fNumEvents);
190 clock.Stop();
191
192 if (fDebug<3)
193 gLog.SetNullOutput(isnull);
194
195 const Double_t f = eval->GetVal();
196
197 if (fDebug>=0)
198 *fLog << inf << "Result F=" << f << endl;
199
200 if (fDebug>=1 && minuit)
201 {
202 Double_t fmin, fedm, errdef;
203 Int_t n1, n2, istat;
204 minuit->mnstat(fmin, fedm, errdef, n1, n2, istat);
205 *fLog << inf << underline << "Minimization Status so far:" << endl;
206 *fLog << " Calls: " << minuit->fNfcn << " (max=" << gMinuit->fMaxIterations << ")" << endl;
207 *fLog << " Parameters: fixed=" << gMinuit->fNpfix << ", free=" << gMinuit->fNpar << endl;
208 *fLog << " Func min: " << fmin << " (Epsi=" << gMinuit->fEpsi << ", Apsi=" << gMinuit->fApsi << ")" << endl;
209 *fLog << " Found edm: " << fedm << endl;
210 *fLog << " ErrDef: " << errdef << endl;
211 *fLog << " Status: ";
212
213 switch (istat)
214 {
215 case 0: *fLog << "n/a" << endl; break;
216 case 1: *fLog << "approximation only, not accurate" << endl; break;
217 case 2: *fLog << "full matrix, but forced positive-definite" << endl; break;
218 case 3: *fLog << "full accurate covariance matrix" << endl; break;
219 default: *fLog << "undefined" << endl; break;
220 }
221 }
222
223 if (fDebug>=1)
224 {
225 clock.Print();
226 fEvtLoop->GetTaskList()->PrintStatistics();
227 }
228
229 return f;
230}
231
232MJOptimize::MJOptimize() : fDebug(-1), fNumEvents(0), fType(kSimplex), fNumMaxCalls(0), fTolerance(0), fTestTrain(0)
233{
234 fRules.SetOwner();
235 fFilter.SetOwner();
236
237 fNamesOn.SetOwner();
238 fNamesOff.SetOwner();
239}
240
241//------------------------------------------------------------------------
242//
243// Add seqeunces from list to reader
244//
245Bool_t MJOptimize::AddSequences(MRead &read, TList &list) const
246{
247 MDirIter files;
248
249 TIter Next(&list);
250 TObject *o=0;
251 while ((o=Next()))
252 {
253 MSequence seq(o->GetName());
254 if (!seq.IsValid())
255 return kFALSE;
256
257 seq.SetupDatRuns(files, o->GetTitle(), "I");
258 }
259
260 return read.AddFiles(files)>0;
261}
262
263//------------------------------------------------------------------------
264//
265// Add on-sequences:
266// - fname: sequence file name (with path)
267// - dir: directory were image files are stored
268//
269void MJOptimize::AddSequenceOn(const char *fname, const char *dir)
270{
271 fNamesOn.Add(new TNamed(fname, dir));
272}
273
274//------------------------------------------------------------------------
275//
276// Add off-sequences:
277// - fname: sequence file name (with path)
278// - dir: directory were image files are stored
279//
280void MJOptimize::AddSequenceOff(const char *fname, const char *dir)
281{
282 fNamesOff.Add(new TNamed(fname, dir));
283}
284
285//------------------------------------------------------------------------
286//
287// Empty list of on- and off-sequences
288//
289void MJOptimize::ResetSequences()
290{
291 fNamesOn.Delete();
292 fNamesOff.Delete();
293}
294
295//------------------------------------------------------------------------
296//
297// Add a parameter used in your filters (see AddFilter) The parameter
298// index is returned,
299//
300// Int_t idx = AddParameter("log10(MHillas.fSize)");
301//
302// The indices area starting with 0 always.
303//
304Int_t MJOptimize::AddParameter(const char *rule)
305{
306 fRules.Add(new TNamed(rule, ""));
307 return fRules.GetSize()-1;
308}
309
310//------------------------------------------------------------------------
311//
312// Add a filter which can be applied in the optimization (for deatils
313// see correspodning Run function) You can use the indices you got by
314// AddParameter, eg
315//
316// AddFilter("M[0] < 3.2");
317//
318// if used in optimization you can do
319//
320// AddFilter("M[0] < [0]");
321//
322// for more details, see SetParameter and FixParameter
323//
324void MJOptimize::AddFilter(const char *rule)
325{
326 fFilter.Add(new MF(rule));
327}
328
329//------------------------------------------------------------------------
330//
331// Add a cut which is used to fill the matrix, eg "MMcEvt.fOartId<1.5"
332// (The rule is applied, nit inverted: The matrix is filled with
333// the events fullfilling the condition)
334//
335void MJOptimize::AddPreCut(const char *rule)
336{
337 MFilter *f = new MF(rule);
338 f->SetBit(kCanDelete);
339 AddPreCut(f);
340}
341
342//------------------------------------------------------------------------
343//
344// Add a cut which is used to fill the matrix. If kCanDelete is set
345// MJOptimize takes the ownership.
346//
347void MJOptimize::AddPreCut(MFilter *f)
348{
349 fPreCuts.Add(f);
350}
351
352//------------------------------------------------------------------------
353//
354// Set the fParameters Array accoring to par.
355//
356void MJOptimize::SetParameters(const TArrayD &par)
357{
358 fParameters = par;
359}
360
361//------------------------------------------------------------------------
362//
363// Set the number of events processed by the eventloop. (Be carfull,
364// if you are doing on-off analysis and you only process the first
365// 1000 events which are on-events only the optimization may not work)
366//
367void MJOptimize::SetNumEvents(UInt_t n)
368{
369 fNumEvents=n;
370}
371
372//------------------------------------------------------------------------
373//
374// Set a debug level, which tells the optimization how much information
375// is displayed about and in the running eventloop.
376//
377void MJOptimize::SetDebug(UInt_t n)
378{
379 fDebug=n;
380}
381
382//------------------------------------------------------------------------
383//
384// Set a optimization algorithm to be used. For more information see
385// TMinuit.
386//
387// Available Algorithms are:
388// kMigrad, // Minimize by the method of Migrad
389// kSimplex, // Minimize by the method of Simplex
390// kSeek // Minimize by the method of Monte Carlo
391//
392void MJOptimize::SetOptimizer(Optimizer_t o)
393{
394 fType = o;
395}
396
397//------------------------------------------------------------------------
398//
399// If a status didplay is set, search for tab "Optimizer".
400// If not found, create it.
401// In the tab search for TMultiGraph "Parameters".
402// If not found create it.
403// If empty create TGraphs.
404// Check number of graphs vs. number of parameters.
405// return TList with graphs.
406//
407TList *MJOptimize::GetPlots() const
408{
409 if (!fDisplay)
410 return NULL;
411
412 TCanvas *c=fDisplay->GetCanvas("Optimizer");
413 if (!c)
414 c = &fDisplay->AddTab("Optimizer");
415
416 TMultiGraph *mg = dynamic_cast<TMultiGraph*>(c->FindObject("Parameters"));
417 if (!mg)
418 mg = new TMultiGraph("Parameters", "Parameters of optimization");
419
420 TList *l = mg->GetListOfGraphs();
421 if (!l)
422 {
423 const Int_t n = fParameters.GetSize();
424 for (int i=0; i<n+1; i++)
425 {
426 TGraph *g = new TGraph;
427 if (i==n)
428 g->SetLineColor(kBlue);
429 mg->Add(g, "");
430 AddPoint(mg->GetListOfGraphs(), i, i==n?1:fParameters[i]);
431 }
432 mg->SetBit(kCanDelete);
433 mg->Draw("al*");
434
435 l = mg->GetListOfGraphs();
436 }
437
438 return l->GetSize() == fParameters.GetSize()+1 ? l : NULL;
439}
440
441//------------------------------------------------------------------------
442//
443// Add a point with y=val as last point in idx-th Tgraph of list l.
444//
445void MJOptimize::AddPoint(TList *l, Int_t idx, Float_t val) const
446{
447 if (!l)
448 return;
449
450 TGraph *gr = (TGraph*)l->At(idx);
451 gr->SetPoint(gr->GetN(), gr->GetN(), val);
452}
453
454Int_t MJOptimize::Minuit(TMinuit &minuit, const char *cmd) const
455{
456 Int_t err;
457 Double_t tmp[2] = { fNumMaxCalls, fTolerance };
458 minuit.mnexcm(cmd, tmp, 2, err);
459
460 switch (err)
461 {
462 case 0:
463 *fLog << inf << GetDescriptor() << " TMinuit::mnexcm excuted normally." << endl;
464 break;
465 case 1:
466 *fLog << warn << GetDescriptor() << " TMinuit::mnexcm command is blank... ignored." << endl;
467 break;
468 case 2:
469 *fLog << warn << GetDescriptor() << " TMinuit::mnexcm command-line syntax error... ignored." << endl;
470 break;
471 case 3:
472 *fLog << warn << GetDescriptor() << " TMinuit::mnexcm unknown command... ignored." << endl;
473 break;
474 case 4:
475 *fLog << warn << GetDescriptor() << " TMinuit::mnexcm - Abnormal termination (eg Migrad not converged)" << endl;
476 break;
477 /*
478 case 5:
479 *fLog << inf << GetDescriptor() << " TMinuit::mnexcm - Parameters requested." << endl;
480 break;
481 case 6:
482 *fLog << inf << GetDescriptor() << " TMinuit::mnexcm - SET INPUT returned." << endl;
483 break;
484 case 7:
485 *fLog << inf << GetDescriptor() << " TMinuit::mnexcm - SET TITLE returned." << endl;
486 break;
487 case 8:
488 *fLog << inf << GetDescriptor() << " TMinuit::mnexcm - SET COVAR returned." << endl;
489 break;
490 case 9:
491 *fLog << inf << GetDescriptor() << " TMinuit::mnexcm - reserved." << endl;
492 break;
493 case 10:
494 *fLog << inf << GetDescriptor() << " TMinuit::mnexcm - END returned." << endl;
495 break;
496 case 11:
497 *fLog << inf << GetDescriptor() << " TMinuit::mnexcm - EXIT or STOP returned." << endl;
498 break;
499 case 12:
500 *fLog << inf << GetDescriptor() << " TMinuit::mnexcm - RETURN returned." << endl;
501 break;*/
502 }
503
504 return err;
505}
506
507Bool_t MJOptimize::Optimize(MEvtLoop &evtloop)
508{
509 if (fType==kNone)
510 return kTRUE;
511
512 gMinuit = new TMinuit(fParameters.GetSize());
513
514 gMinuit->SetFCN(fcn);
515 gMinuit->SetObjectFit(this);
516 gMinuit->SetPrintLevel(-1); // Don't print when DefineParameter
517
518 //
519 // Set starting values and step sizes for parameters
520 //
521 for (Int_t i=0; i<fParameters.GetSize(); i++)
522 {
523 TString name = "par[";
524 name += i;
525 name += "]";
526 Double_t vinit = fParameters[i];
527 Double_t step = fStep[i];
528
529 Double_t limlo = fLimLo[i];
530 Double_t limup = fLimUp[i];
531
532 Bool_t rc = gMinuit->DefineParameter(i, name, vinit, step, limlo, limup);
533 if (rc)
534 {
535 *fLog << err << dbginf << "Error in defining parameter #" << i << endl;
536 return kFALSE;
537 }
538
539 if (step==0)
540 gMinuit->FixParameter(i);
541 }
542
543 gMinuit->SetPrintLevel(1); // Switch on pritning again
544 gMinuit->mnprin(1,0); // Print all parameters
545
546 fEvtLoop = &evtloop;
547
548 TList *g=GetPlots();
549
550 // Now ready for minimization step:
551 TStopwatch clock;
552 clock.Start();
553 switch (fType)
554 {
555 case kSimplex:
556 Simplex(*gMinuit);
557 break;
558 case kMigrad:
559 Migrad(*gMinuit);
560 break;
561 case kMinimize:
562 Minimize(*gMinuit);
563 break;
564 case kMinos:
565 Minos(*gMinuit);
566 break;
567 case kImprove:
568 Improve(*gMinuit);
569 break;
570 case kSeek:
571 Seek(*gMinuit);
572 break;
573 case kNone: // Should never happen
574 return kFALSE;
575 }
576 clock.Stop();
577 clock.Print();
578
579 if (evtloop.GetDisplay()!=fDisplay)
580 {
581 *fLog << inf << "Optimization aborted by user." << endl;
582 fDisplay = 0;
583 return kFALSE;
584 }
585
586 *fLog << inf << "Resulting Chisq: " << gMinuit->fAmin << endl;
587
588 //
589 // Update values of fA, fB:
590 //
591 for (Int_t i=0; i<fParameters.GetSize(); i++)
592 {
593 Double_t x1, x2;
594 gMinuit->GetParameter(i,x1,x2);
595 fParameters[i] = x1;
596 cout << i << ": " << fParameters[i] << endl;
597
598 AddPoint(g, i, x1);
599 }
600 AddPoint(g, fParameters.GetSize(), gMinuit->fAmin);
601
602 delete gMinuit;
603
604 return kTRUE;
605}
606
607//------------------------------------------------------------------------
608//
609// Optimize allows to use the optimizing by an eventloop based on
610// some requirements.
611//
612// 1) The tasklist to be executed must have the name MTaskList and
613// be an entry in the parameterlist.
614//
615// 2) The reading task (MReadMarsFile, MMatrixLoop) must have the name
616// "MRead". If it derives from MRead Rewind() must be implemented,
617// otherwise it must start reading from scratch each time its
618// PreProcess is called.
619//
620// 3) The parameters to be optimized must be accessed through (currently)
621// a single parameter container (MParContainer) called MParameters.
622// The parameters are set through SetVariables.
623//
624// 4) The result of a single function call for minimization (eg. chisquare)
625// must be available after the eventloop in a container of type
626// MParameterD with the name "MinimizationResult".
627//
628// 5) The parameters to start with must have been set using
629// MJOptimize::SetParameter or MJOptimize::SetParameters and
630// MJOptimize::FixParameter
631//
632// The behaviour of the optimization can be changed using:
633// void SetNumEvents(UInt_t n);
634// void SetDebug(UInt_t n);
635// void SetOptimizer(Optimizer_t o);
636//
637// After optimization the resulting parameters are set and another eventloop
638// with a MStatusDisplay is set is called. The resulting parameters can be
639// accessed using: GetParameters()
640//
641// To be fixed:
642// - MStatusDisplay should show status while optimization is running
643// - write result into MStatusDisplay
644// - save result
645//
646Bool_t MJOptimize::Optimize(MParList &parlist)
647{
648 // Checks to make sure, that fcn doesn't crash
649 if (!parlist.FindCreateObj("MParameterD", "MinimizationValue"))
650 return kFALSE;
651
652 if (!parlist.FindObject("MParameters", "MParContainer"))
653 {
654 *fLog << err << "MParameters [MParContainer] not found... abort." << endl;
655 return kFALSE;
656 }
657
658 MMatrixLoop *loop = dynamic_cast<MMatrixLoop*>(parlist.FindTask("MRead"));
659
660 TString txt("Starting ");
661 switch (fType)
662 {
663 case kMigrad: txt += "Migrad"; break;
664 case kMinimize: txt += "Minimize"; break;
665 case kMinos: txt += "Minos"; break;
666 case kImprove: txt += "Improve"; break;
667 case kSimplex: txt += "Simplex"; break;
668 case kSeek: txt += "Seek"; break;
669 case kNone: txt += "no"; break;
670 }
671 txt += " optimization";
672
673 fLog->Separator(txt);
674
675 // Setup eventloop
676 MEvtLoop evtloop;
677 evtloop.SetParList(&parlist);
678 evtloop.SetDisplay(fDisplay); // set display for evtloop and all childs
679 parlist.SetDisplay(0); // reset display for all contents of parlist and tasklist
680 evtloop.SetPrivateDisplay(); // prevent display from being cascaded again in PreProcess
681
682 *fLog << inf << "Number of Parameters: " << fParameters.GetSize() << endl;
683
684 // In case the reader is the matrix loop and testrain is enabled
685 // switch on even mode...
686 if (loop && TMath::Abs(fTestTrain)>0)
687 loop->SetOperationMode(fTestTrain>0?MMatrixLoop::kEven:MMatrixLoop::kOdd);
688
689 if (!Optimize(evtloop))
690 return kFALSE;
691
692 gMinuit = 0;
693
694 fEvtLoop->SetDisplay(fDisplay);
695 if (!Fcn(fParameters))
696 return kFALSE;
697
698 // In case the reader is the matrix loop and testrain is enabled
699 // switch on odd mode...
700 if (!loop || fTestTrain==0)
701 return kTRUE;
702
703 loop->SetOperationMode(fTestTrain<0?MMatrixLoop::kEven:MMatrixLoop::kOdd);
704
705 // Done already in Fcn
706 // list.SetVariables(fParameters);
707 return Fcn(fParameters);
708}
709
710void MJOptimize::AddRulesToMatrix(MHMatrix &m) const
711{
712 TIter Next1(&fRules);
713 TObject *o1=0;
714 while ((o1=Next1()))
715 m.AddColumn(o1->GetName());
716}
717
718//------------------------------------------------------------------------
719//
720// Fill matrix m by using read. Use rules as a filter if userules.
721//
722Bool_t MJOptimize::FillMatrix(MReadTree &read, MParList &parlist, Bool_t userules)
723{
724 MHMatrix *m = (MHMatrix*)parlist.FindObject("M", "MHMatrix");
725 if (!m)
726 {
727 *fLog << err << "MJOptimize::FillMatrix - ERROR: M [MHMatrix] not found in parlist... abort." << endl;
728 return kFALSE;
729 }
730
731 m->Print("cols");
732
733 //MParList parlist;
734
735 // MGeomCamMagic cam;
736 // parlist.AddToList(&cam);
737
738 MTaskList tlist;
739 parlist.Replace(&tlist);
740
741 MFillH fillh(m);
742
743 tlist.AddToList(&read);
744
745 MFilterList list;
746 if (!list.AddToList(fPreCuts))
747 *fLog << err << "ERROR - Calling MFilterList::AddToList for fPreCuts failed!" << endl;
748 if (userules)
749 SetupFilters(list);
750 list.SetName("PreCuts"); // reset Name set by SetupFilters
751 list.SetInverted(kFALSE); // reset inversion set by SetupFilters
752 fillh.SetFilter(&list);
753 tlist.AddToList(&list);
754
755 tlist.AddToList(&fillh);
756
757 MEvtLoop fillloop;
758 fillloop.SetParList(&parlist);
759 fillloop.SetDisplay(fDisplay);
760 if (!fillloop.Eventloop(fNumEvents))
761 {
762 *fLog << err << "Filling matrix failed..." << endl;
763 return kFALSE;
764 }
765 tlist.PrintStatistics();
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}
809
810//------------------------------------------------------------------------
811//
812Bool_t MJOptimize::Run(const char *fname, MFilter *filter, MAlphaFitter *fit)
813{
814 if (fParameters.GetSize()==0)
815 {
816 *fLog << err << "Sorry, no parameters defined." << endl;
817 return kFALSE;
818 }
819
820 fLog->Separator("Preparing On-only-optimization");
821
822 MParList parlist;
823
824 MGeomCamMagic geom; // For GetConvMm2Deg
825 parlist.AddToList(&geom);
826
827 MHMatrix m("M");
828 AddRulesToMatrix(m);
829 parlist.AddToList(&m);
830
831 MHAlpha hist;
832 hist.SkipHistTime();
833 hist.SkipHistTheta();
834 hist.SkipHistEnergy();
835 hist.InitMapping(&m);
836
837 if (filter && filter->InheritsFrom(MFMagicCuts::Class()))
838 ((MFMagicCuts*)filter)->InitMapping(&m);
839
840 MReadTree read("Events");
841 read.DisableAutoScheme(); // AutoScheme doesn't seem to be faster!
842 if (fname)
843 read.AddFile(fname);
844 else
845 AddSequences(read, fNamesOn);
846 if (!FillMatrix(read, parlist))
847 return kFALSE;
848
849 MTaskList tasklist;
850 parlist.Replace(&tasklist);
851 if (fit)
852 parlist.AddToList(fit);
853
854 MFilterList list;
855 SetupFilters(list, filter);
856
857 MContinue contin(&list);
858 parlist.AddToList(&list);
859
860 MFillH fill(&hist);
861
862 MMatrixLoop loop(&m);
863
864 tasklist.AddToList(&loop);
865 tasklist.AddToList(&list);
866 tasklist.AddToList(&contin);
867 tasklist.AddToList(&fill);
868
869 // Optimize with the tasklist in this parameterlist
870 if (!Optimize(parlist))
871 return kFALSE;
872
873 // Copy the result back to be accessible by the user
874 if (fit)
875 hist.GetAlphaFitter().Copy(*fit);
876 // Print the result
877 hist.GetAlphaFitter().Print("result");
878
879 // Store result if requested
880 TObjArray cont;
881 cont.Add(&contin);
882 return WriteContainer(cont, fNameOut);
883}
884
885//------------------------------------------------------------------------
886//
887// Make sure, that filter->GetDataMember is correctly implemented!!!!
888//
889Bool_t MJOptimize::RunOnOff(const char *fname, MFilter *filter, MAlphaFitter *fit, const char *tree)
890{
891 if (fParameters.GetSize()==0)
892 {
893 *fLog << err << "Sorry, no parameters defined." << endl;
894 return kFALSE;
895 }
896
897 fLog->Separator("Preparing On/Off-optimization");
898
899 MParList parlist;
900
901 MGeomCamMagic geom; // For GetConvMm2Deg
902 parlist.AddToList(&geom);
903
904 MHMatrix m("M");
905 AddRulesToMatrix(m);
906 parlist.AddToList(&m);
907
908 const Int_t idxdatatype = m.AddColumn("DataType.fVal");
909
910 MHAlpha histon, histof("MHAlphaOff");
911 histon.SkipHistTime();
912 histon.SkipHistTheta();
913 //histon.SkipHistEnergy();
914 histof.SkipHistTime();
915 histof.SkipHistTheta();
916 //histof.SkipHistEnergy();
917 histon.ForceUsingSize();
918 histof.ForceUsingSize();
919 histon.InitMapping(&m, 1);
920 histof.InitMapping(&m, 1);
921
922 if (filter && filter->InheritsFrom(MFMagicCuts::Class()))
923 ((MFMagicCuts*)filter)->InitMapping(&m);
924
925 parlist.AddToList(&histon);
926 parlist.AddToList(&histof);
927
928 if (fname)
929 {
930 MReadTree read(tree);
931 read.DisableAutoScheme(); // AutoScheme doesn't seem to be faster!
932 read.AddFile(fname);
933 if (!FillMatrix(read, parlist))
934 return kFALSE;
935 }
936 else
937 {
938 MParameterI par("DataType");
939 parlist.AddToList(&par);
940
941 gLog.Separator("Reading On-Data");
942 par.SetVal(1);
943 MReadTree readon(tree);
944 readon.DisableAutoScheme(); // AutoScheme doesn't seem to be faster!
945 AddSequences(readon, fNamesOn);
946 if (!FillMatrix(readon, parlist))
947 return kFALSE;
948
949 gLog.Separator("Reading Off-Data");
950 par.SetVal(0);
951 MReadTree readoff(tree);
952 readoff.DisableAutoScheme(); // AutoScheme doesn't seem to be faster!
953 AddSequences(readoff, fNamesOff);
954 if (!FillMatrix(readoff, parlist))
955 return kFALSE;
956 }
957
958 MTaskList tasklist;
959 parlist.Replace(&tasklist);
960 if (fit)
961 parlist.AddToList(fit);
962
963 MFilterList list;
964 SetupFilters(list, filter);
965
966 MContinue contin(&list);
967 parlist.AddToList(&list);
968
969 MFillH fillof(&histof, "", "FillHistOff");
970 MFillH fillon(&histon, "", "FillHistOn");
971
972 MF f0(Form("M[%d]<0.5", idxdatatype), "FilterOffData");
973 MF f1(Form("M[%d]>0.5", idxdatatype), "FilterOnData");
974
975 fillof.SetFilter(&f0);
976 fillon.SetFilter(&f1);
977
978 MMatrixLoop loop(&m);
979
980 tasklist.AddToList(&loop);
981 tasklist.AddToList(&list);
982 tasklist.AddToList(&contin);
983 tasklist.AddToList(&f0);
984 tasklist.AddToList(&f1);
985 tasklist.AddToList(&fillof);
986 tasklist.AddToList(&fillon);
987
988 // Optimize with the tasklist in this parameterlist
989 if (!Optimize(parlist))
990 return kFALSE;
991
992 // Copy the result back to be accessible by the user
993 if (fit)
994 histon.GetAlphaFitter().Copy(*fit);
995 // Print the result
996 histon.GetAlphaFitter().Print("result");
997
998 // Store result if requested
999 TObjArray cont;
1000 cont.Add(&contin);
1001 return WriteContainer(cont, fNameOut);
1002}
1003
1004//------------------------------------------------------------------------
1005//
1006// Read all events from file which do match rules and optimize
1007// energy estimator.
1008//
1009Bool_t MJOptimize::RunEnergy(const char *fname, const char *rule)
1010{
1011 if (fParameters.GetSize()==0)
1012 {
1013 *fLog << err << "Sorry, no parameters defined." << endl;
1014 return kFALSE;
1015 }
1016
1017 fLog->Separator("Preparing Energy optimization");
1018
1019 MParList parlist;
1020
1021 MParameterI par("DataType");
1022 par.SetVal(1);
1023 parlist.AddToList(&par);
1024
1025 MFDataMember filter("DataType.fVal", '>', 0.5);
1026 fPreCuts.Add(&filter);
1027
1028 MGeomCamMagic geom; // For GetConvMm2Deg
1029 parlist.AddToList(&geom);
1030
1031 MHMatrix m("M");
1032 AddRulesToMatrix(m);
1033 parlist.AddToList(&m);
1034
1035 MHEnergyEst hist;
1036 hist.InitMapping(&m);
1037
1038 MEnergyEstimate est("MParameters");
1039 est.SetRule(rule);
1040 parlist.AddToList(&est);
1041
1042 MReadTree read("Events");
1043 // NECESSARY BECAUSE OF MDataFormula GetRules missing
1044 read.DisableAutoScheme();
1045 if (fname)
1046 read.AddFile(fname);
1047 else
1048 AddSequences(read, fNamesOn);
1049 if (!FillMatrix(read, parlist, kTRUE))
1050 return kFALSE;
1051
1052 fPreCuts.Remove(&filter);
1053
1054 MTaskList tasklist;
1055 parlist.Replace(&tasklist);
1056
1057 MFillH fill(&hist);
1058
1059 MMatrixLoop loop(&m);
1060
1061 tasklist.AddToList(&loop);
1062 tasklist.AddToList(&est);
1063 tasklist.AddToList(&fill);
1064
1065 // Optimize with the tasklist in this parameterlist
1066 if (!Optimize(parlist))
1067 return kFALSE;
1068
1069 // Print the result
1070 hist.Print();
1071
1072 // Store result if requested
1073 TObjArray cont;
1074 cont.Add(&est);
1075 return WriteContainer(cont, fNameOut);
1076}
Note: See TracBrowser for help on using the repository browser.