source: trunk/Mars/mjtrain/MJTrainSeparation.cc@ 11942

Last change on this file since 11942 was 9869, checked in by tbretz, 14 years ago
Gave names to the data sets in the output file in MJTrainSeparation
File size: 31.3 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 11/2005 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2006
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MJTrainSeparation
28//
29////////////////////////////////////////////////////////////////////////////
30#include "MJTrainSeparation.h"
31
32#include <TF1.h>
33#include <TH2.h>
34#include <TChain.h>
35#include <TGraph.h>
36#include <TMarker.h>
37#include <TCanvas.h>
38#include <TStopwatch.h>
39#include <TVirtualPad.h>
40
41#include "MHMatrix.h"
42
43#include "MLog.h"
44#include "MLogManip.h"
45
46// tools
47#include "MMath.h"
48#include "MDataSet.h"
49#include "MTFillMatrix.h"
50#include "MStatusDisplay.h"
51
52// eventloop
53#include "MParList.h"
54#include "MTaskList.h"
55#include "MEvtLoop.h"
56
57// tasks
58#include "MReadMarsFile.h"
59#include "MReadReports.h"
60#include "MContinue.h"
61#include "MFillH.h"
62#include "MSrcPosRndm.h"
63#include "MHillasCalc.h"
64#include "MRanForestCalc.h"
65#include "MParameterCalc.h"
66
67// container
68#include "MMcEvt.hxx"
69#include "MParameters.h"
70
71// histograms
72#include "MBinning.h"
73#include "MH3.h"
74#include "MHHadronness.h"
75
76// filter
77#include "MF.h"
78#include "MFEventSelector.h"
79#include "MFilterList.h"
80
81// wobble
82#include "MPointingPos.h"
83#include "MPointingDevCalc.h"
84#include "../mastro/MObservatory.h"
85#include "MSrcPosCalc.h"
86#include "MSrcPosCorrect.h"
87#include "../mimage/MHillasCalc.h"
88
89
90ClassImp(MJTrainSeparation);
91
92using namespace std;
93
94void MJTrainSeparation::DisplayResult(MH3 &h31, MH3 &h32, Float_t ontime)
95{
96 TH2D &g = (TH2D&)h32.GetHist();
97 TH2D &h = (TH2D&)h31.GetHist();
98
99 h.SetMarkerColor(kRed);
100 g.SetMarkerColor(kBlue);
101
102 TH2D res1(g);
103 TH2D res2(g);
104
105 h.SetTitle("Hadronness-Distribution vs. Size");
106 res1.SetTitle("Significance Li/Ma");
107 res1.SetXTitle("Size [phe]");
108 res1.SetYTitle("Hadronness");
109 res2.SetTitle("Significance-Distribution");
110 res2.SetXTitle("Size-Cut [phe]");
111 res2.SetYTitle("Hadronness-Cut");
112 res1.SetContour(50);
113 res2.SetContour(50);
114
115 const Int_t nx = h.GetNbinsX();
116 const Int_t ny = h.GetNbinsY();
117
118 gROOT->SetSelectedPad(NULL);
119
120
121 Double_t Stot = 0;
122 Double_t Btot = 0;
123
124 Double_t max2 = -1;
125
126 TGraph gr1;
127 TGraph gr2;
128 for (int x=nx-1; x>=0; x--)
129 {
130 TH1 *hx = h.ProjectionY("H_py", x+1, x+1);
131 TH1 *gx = g.ProjectionY("G_py", x+1, x+1);
132
133 Double_t S = 0;
134 Double_t B = 0;
135
136 Double_t max1 = -1;
137 Int_t maxy1 = 0;
138 Int_t maxy2 = 0;
139 for (int y=ny-1; y>=0; y--)
140 {
141 const Float_t s = gx->Integral(1, y+1);
142 const Float_t b = hx->Integral(1, y+1);
143 const Float_t sig1 = MMath::SignificanceLiMa(s+b, b);
144 const Float_t sig2 = MMath::SignificanceLiMa(s+Stot+b+Btot, b+Btot)*TMath::Log10(s+Stot+1);
145 if (sig1>max1)
146 {
147 maxy1 = y;
148 max1 = sig1;
149 }
150 if (sig2>max2)
151 {
152 maxy2 = y;
153 max2 = sig2;
154
155 S=s;
156 B=b;
157 }
158
159 res1.SetBinContent(x+1, y+1, sig1);
160 }
161
162 Stot += S;
163 Btot += B;
164
165 gr1.SetPoint(x, h.GetXaxis()->GetBinCenter(x+1), h.GetYaxis()->GetBinCenter(maxy1+1));
166 gr2.SetPoint(x, h.GetXaxis()->GetBinCenter(x+1), h.GetYaxis()->GetBinCenter(maxy2+1));
167
168 delete hx;
169 delete gx;
170 }
171
172 //cout << "--> " << MMath::SignificanceLiMa(Stot+Btot, Btot) << " ";
173 //cout << Stot << " " << Btot << endl;
174
175
176 Int_t mx1=0;
177 Int_t my1=0;
178 Int_t mx2=0;
179 Int_t my2=0;
180 Int_t s1=0;
181 Int_t b1=0;
182 Int_t s2=0;
183 Int_t b2=0;
184 Double_t sig1=-1;
185 Double_t sig2=-1;
186 for (int x=0; x<nx; x++)
187 {
188 TH1 *hx = h.ProjectionY("H_py", x+1);
189 TH1 *gx = g.ProjectionY("G_py", x+1);
190 for (int y=0; y<ny; y++)
191 {
192 const Float_t s = gx->Integral(1, y+1);
193 const Float_t b = hx->Integral(1, y+1);
194 const Float_t sig = MMath::SignificanceLiMa(s+b, b);
195 res2.SetBinContent(x+1, y+1, sig);
196
197 // Search for top-rightmost maximum
198 if (sig>=sig1)
199 {
200 mx1=x+1;
201 my1=y+1;
202 s1 = TMath::Nint(s);
203 b1 = TMath::Nint(b);
204 sig1=sig;
205 }
206 if (TMath::Log10(s)*sig>=sig2)
207 {
208 mx2=x+1;
209 my2=y+1;
210 s2 = TMath::Nint(s);
211 b2 = TMath::Nint(b);
212 sig2=TMath::Log10(s)*sig;
213 }
214 }
215 delete hx;
216 delete gx;
217 }
218
219 TGraph gr3;
220 TGraph gr4;
221 gr4.SetTitle("Significance Li/Ma vs. Hadronness-cut");
222
223 TH1 *hx = h.ProjectionY("H_py");
224 TH1 *gx = g.ProjectionY("G_py");
225 for (int y=0; y<ny; y++)
226 {
227 const Float_t s = gx->Integral(1, y+1);
228 const Float_t b = hx->Integral(1, y+1);
229 const Float_t sg1 = MMath::SignificanceLiMa(s+b, b);
230 const Float_t sg2 = s<1 ? 0 : MMath::SignificanceLiMa(s+b, b)*TMath::Log10(s);
231
232 gr3.SetPoint(y, h.GetYaxis()->GetBinLowEdge(y+2), sg1);
233 gr4.SetPoint(y, h.GetYaxis()->GetBinLowEdge(y+2), sg2);
234 }
235 delete hx;
236 delete gx;
237
238 if (fDisplay)
239 {
240 TCanvas &c = fDisplay->AddTab("OptCut");
241 c.SetBorderMode(0);
242 c.Divide(2,2);
243
244 c.cd(1);
245 gPad->SetBorderMode(0);
246 gPad->SetFrameBorderMode(0);
247 gPad->SetLogx();
248 gPad->SetGridx();
249 gPad->SetGridy();
250 h.DrawCopy();
251 g.DrawCopy("same");
252 gr1.SetMarkerStyle(kFullDotMedium);
253 gr1.DrawClone("LP")->SetBit(kCanDelete);
254 gr2.SetLineColor(kBlue);
255 gr2.SetMarkerStyle(kFullDotMedium);
256 gr2.DrawClone("LP")->SetBit(kCanDelete);
257
258 c.cd(3);
259 gPad->SetBorderMode(0);
260 gPad->SetFrameBorderMode(0);
261 gPad->SetGridx();
262 gPad->SetGridy();
263 gr4.SetMinimum(0);
264 gr4.SetMarkerStyle(kFullDotMedium);
265 gr4.DrawClone("ALP")->SetBit(kCanDelete);
266 gr3.SetLineColor(kBlue);
267 gr3.SetMarkerStyle(kFullDotMedium);
268 gr3.DrawClone("LP")->SetBit(kCanDelete);
269
270 c.cd(2);
271 gPad->SetBorderMode(0);
272 gPad->SetFrameBorderMode(0);
273 gPad->SetLogx();
274 gPad->SetGridx();
275 gPad->SetGridy();
276 gPad->AddExec("color", "gStyle->SetPalette(1, 0);");
277 res1.SetMaximum(7);
278 res1.DrawCopy("colz");
279
280 c.cd(4);
281 gPad->SetBorderMode(0);
282 gPad->SetFrameBorderMode(0);
283 gPad->SetLogx();
284 gPad->SetGridx();
285 gPad->SetGridy();
286 gPad->AddExec("color", "gStyle->SetPalette(1, 0);");
287 res2.SetMaximum(res2.GetMaximum()*1.05);
288 res2.DrawCopy("colz");
289
290 // Int_t mx, my, mz;
291 // res2.GetMaximumBin(mx, my, mz);
292
293 TMarker m;
294 m.SetMarkerStyle(kStar);
295 m.DrawMarker(res2.GetXaxis()->GetBinCenter(mx1), res2.GetYaxis()->GetBinCenter(my1));
296 m.SetMarkerStyle(kPlus);
297 m.DrawMarker(res2.GetXaxis()->GetBinCenter(mx2), res2.GetYaxis()->GetBinCenter(my2));
298 }
299
300 if (ontime>0)
301 *fLog << all << "Observation Time: " << TMath::Nint(ontime/60) << "min" << endl;
302 *fLog << "Maximum Significance: " << Form("%.1f", sig1);
303 if (ontime>0)
304 *fLog << Form(" [%.1f/sqrt(h)]", sig1/TMath::Sqrt(ontime/3600));
305 *fLog << endl;
306
307 *fLog << "Significance: S=" << Form("%.1f", sig1) << " E=" << s1 << " B=" << b1 << " h<";
308 *fLog << Form("%.2f", res2.GetYaxis()->GetBinCenter(my1)) << " s>";
309 *fLog << Form("%3d", TMath::Nint(res2.GetXaxis()->GetBinCenter(mx1))) << endl;
310 *fLog << "Significance*LogE: S=" << Form("%.1f", sig2/TMath::Log10(s2)) << " E=" << s2 << " B=" << b2 << " h<";
311 *fLog << Form("%.2f", res2.GetYaxis()->GetBinCenter(my2)) << " s>";
312 *fLog << Form("%3d", TMath::Nint(res2.GetXaxis()->GetBinCenter(mx2))) << endl;
313 *fLog << endl;
314}
315
316/*
317Bool_t MJSpectrum::InitWeighting(const MDataSet &set, MMcSpectrumWeight &w) const
318{
319 fLog->Separator("Initialize energy weighting");
320
321 if (!CheckEnv(w))
322 {
323 *fLog << err << "ERROR - Reading resources for MMcSpectrumWeight failed." << endl;
324 return kFALSE;
325 }
326
327 TChain chain("RunHeaders");
328 set.AddFilesOn(chain);
329
330 MMcCorsikaRunHeader *h=0;
331 chain.SetBranchAddress("MMcCorsikaRunHeader.", &h);
332 chain.GetEntry(1);
333
334 if (!h)
335 {
336 *fLog << err << "ERROR - Couldn't read MMcCorsikaRunHeader from DataSet." << endl;
337 return kFALSE;
338 }
339
340 if (!w.Set(*h))
341 {
342 *fLog << err << "ERROR - Initializing MMcSpectrumWeight failed." << endl;
343 return kFALSE;
344 }
345
346 w.Print();
347 return kTRUE;
348}
349
350Bool_t MJSpectrum::ReadOrigMCDistribution(const MDataSet &set, TH1 &h, MMcSpectrumWeight &weight) const
351{
352 // Some debug output
353 fLog->Separator("Compiling original MC distribution");
354
355 weight.SetNameMcEvt("MMcEvtBasic");
356 const TString w(weight.GetFormulaWeights());
357 weight.SetNameMcEvt();
358
359 *fLog << inf << "Using weights: " << w << endl;
360 *fLog << "Please stand by, this may take a while..." << flush;
361
362 if (fDisplay)
363 fDisplay->SetStatusLine1("Compiling MC distribution...");
364
365 // Create chain
366 TChain chain("OriginalMC");
367 set.AddFilesOn(chain);
368
369 // Prepare histogram
370 h.Reset();
371
372 // Fill histogram from chain
373 h.SetDirectory(gROOT);
374 if (h.InheritsFrom(TH2::Class()))
375 {
376 h.SetNameTitle("ThetaEMC", "Event-Distribution vs Theta and Energy for MC (produced)");
377 h.SetXTitle("\\Theta [\\circ]");
378 h.SetYTitle("E [GeV]");
379 h.SetZTitle("Counts");
380 chain.Draw("MMcEvtBasic.fEnergy:MMcEvtBasic.fTelescopeTheta*TMath::RadToDeg()>>ThetaEMC", w, "goff");
381 }
382 else
383 {
384 h.SetNameTitle("ThetaMC", "Event-Distribution vs Theta for MC (produced)");
385 h.SetXTitle("\\Theta [\\circ]");
386 h.SetYTitle("Counts");
387 chain.Draw("MMcEvtBasic.fTelescopeTheta*TMath::RadToDeg()>>ThetaMC", w, "goff");
388 }
389 h.SetDirectory(0);
390
391 *fLog << "done." << endl;
392 if (fDisplay)
393 fDisplay->SetStatusLine2("done.");
394
395 if (h.GetEntries()>0)
396 return kTRUE;
397
398 *fLog << err << "ERROR - Histogram with original MC distribution empty..." << endl;
399
400 return h.GetEntries()>0;
401}
402*/
403
404Bool_t MJTrainSeparation::GetEventsProduced(MDataSet &set, Double_t &num, Double_t &min, Double_t &max) const
405{
406 TChain chain("OriginalMC");
407 if (!set.AddFilesOn(chain))
408 return kFALSE;
409
410 min = chain.GetMinimum("MMcEvtBasic.fEnergy");
411 max = chain.GetMaximum("MMcEvtBasic.fEnergy");
412
413 num = chain.GetEntries();
414
415 if (num<100)
416 *fLog << err << "ERROR - Less than 100 entries in OriginalMC-Tree of MC-Train-Data found." << endl;
417
418 return num>=100;
419}
420
421Double_t MJTrainSeparation::GetDataRate(MDataSet &set, Double_t &num) const
422{
423 TChain chain1("Events");
424 if (!set.AddFilesOff(chain1))
425 return kFALSE;
426
427 num = chain1.GetEntries();
428 if (num<100)
429 {
430 *fLog << err << "ERROR - Less than 100 entries in Events-Tree of Train-Data found." << endl;
431 return -1;
432 }
433
434 TChain chain("EffectiveOnTime");
435 if (!set.AddFilesOff(chain))
436 return kFALSE;
437
438 chain.Draw("MEffectiveOnTime.fVal", "MEffectiveOnTime.fVal", "goff");
439
440 TH1 *h = dynamic_cast<TH1*>(gROOT->FindObject("htemp"));
441 if (!h)
442 {
443 *fLog << err << "ERROR - Weird things are happening (htemp not found)!" << endl;
444 return -1;
445 }
446
447 const Double_t ontime = h->Integral();
448 delete h;
449
450 if (ontime<1)
451 {
452 *fLog << err << "ERROR - Less than 1s of effective observation time found in Train-Data." << endl;
453 return -1;
454 }
455
456 return num/ontime;
457}
458
459Double_t MJTrainSeparation::GetNumMC(MDataSet &set) const
460{
461 TChain chain1("Events");
462 if (!set.AddFilesOn(chain1))
463 return kFALSE;
464
465 const Double_t num = chain1.GetEntries();
466 if (num<100)
467 {
468 *fLog << err << "ERROR - Less than 100 entries in Events-Tree of Train-Data found." << endl;
469 return -1;
470 }
471
472 return num;
473}
474
475Float_t MJTrainSeparation::AutoTrain(MDataSet &set, Type_t typon, Type_t typof, Float_t flux)
476{
477 Double_t num, min, max;
478 if (!GetEventsProduced(set, num, min, max))
479 return -1;
480
481 *fLog << inf << "Using build-in radius of 300m to calculate collection area!" << endl;
482
483 // Target spectrum
484 TF1 flx("Flux", "[0]/1000*(x/1000)^(-2.6)", min, max);
485 flx.SetParameter(0, flux);
486
487 // Number n0 of events this spectrum would produce per s and m^2
488 const Double_t n0 = flx.Integral(min, max); //[#]
489
490 // Area produced in MC
491 const Double_t A = TMath::Pi()*300*300; //[m²]
492
493 // Rate R of events this spectrum would produce per s
494 const Double_t R = n0*A; //[Hz]
495
496 *fLog << "Source Spectrum: " << flux << " * (E/TeV)^(-2.6) * TeV*m^2*s" << endl;
497
498 *fLog << "Gamma rate from the source inside the MC production area: " << R << "Hz" << endl;
499
500 // Number N of events produced (in trainings sample)
501 const Double_t N = num; //[#]
502
503 *fLog << "Events produced by MC inside the production area: " << TMath::Nint(num) << endl;
504
505 // This correponds to an observation time T [s]
506 const Double_t T = N/R; //[s]
507
508 *fLog << "Total time produced by the Monte Carlo: " << T << "s" << endl;
509
510 // With an average data rate after star of
511 Double_t data=0;
512 const Double_t r = GetDataRate(set, data); //[Hz]
513 Double_t ontime = data/r;
514
515 *fLog << "Events measured per second effective on time: " << r << "Hz" << endl;
516 *fLog << "Total effective on time: " << ontime << "s" << endl;
517
518 const Double_t ratio = T/ontime;
519 *fLog << "Ratio of Monte Carlo to data observation time: " << ratio << endl;
520
521 // 3570.5/43440.2 = 0.082
522
523
524 // this yields a number of n events to be read for training
525 const Double_t n = r*T; //[#]
526
527 *fLog << "Events to be read from the data sample: " << TMath::Nint(n) << endl;
528 *fLog << "Events available in data sample: " << data << endl;
529
530 if (r<0)
531 return -1;
532
533 Double_t nummc = GetNumMC(set);
534
535 *fLog << "Events available in MC sample: " << nummc << endl;
536
537// *fLog << "MC read probability: " << data/n << endl;
538
539 // more data requested than available => Scale down num MC events
540 Double_t on, off;
541 if (data<n)
542 {
543 on = TMath::Nint(nummc*data/n);
544 off = TMath::Nint(data);
545 *fLog << warn;
546 *fLog << "Not enough data events available... scaling MC to data by " << data/n << endl;
547 *fLog << inf;
548 }
549 else
550 {
551 on = TMath::Nint(nummc);
552 off = TMath::Nint(n);
553 }
554
555 if (fNum[typon]>0 && fNum[typon]<on)
556 {
557 fNum[typof] = TMath::Nint(off*fNum[typon]/on);
558 ontime *= fNum[typon]/on;
559 *fLog << warn << "Less MC events requested... scaling data to MC by " << fNum[typon]/on << endl;
560 }
561 else
562 {
563 fNum[typon] = TMath::Nint(on);
564 fNum[typof] = TMath::Nint(off);
565 }
566
567 *fLog << inf;
568 *fLog << "Target number of MC events: " << fNum[typon] << endl;
569 *fLog << "Target number of data events: " << fNum[typof] << endl;
570
571 /*
572 An event rate dependent selection?
573 ----------------------------------
574 Total average data rate: R
575 Goal number of events: N
576 Number of data events: N0
577 Rate assigned to single evt: r
578
579 Selection probability: N/N0 * r/R
580
581 f := N/N0 * r
582
583 MF f("f * MEventRate.fRate < rand");
584 */
585
586 return ontime;
587}
588
589Bool_t MJTrainSeparation::Train(const char *out)
590{
591 if (fDisplay)
592 fDisplay->SetTitle(out);
593
594 if (!fDataSetTrain.IsValid())
595 {
596 *fLog << err << "ERROR - DataSet for training invalid!" << endl;
597 return kFALSE;
598 }
599 if (!fDataSetTest.IsValid())
600 {
601 *fLog << err << "ERROR - DataSet for testing invalid!" << endl;
602 return kFALSE;
603 }
604
605 if (fDataSetTrain.IsWobbleMode()!=fDataSetTest.IsWobbleMode())
606 {
607 *fLog << err << "ERROR - Train- and Test-DataSet have different observation modes!" << endl;
608 return kFALSE;
609 }
610
611 if (!HasWritePermission(out))
612 return kFALSE;
613
614 TStopwatch clock;
615 clock.Start();
616
617 // ----------------------- Auto Train? ----------------------
618
619 Float_t ontime = -1;
620 if (fAutoTrain)
621 {
622 fLog->Separator("Auto-Training -- Train-Data");
623 if (AutoTrain(fDataSetTrain, kTrainOn, kTrainOff, fFluxTrain)<0)
624 return kFALSE;
625 fLog->Separator("Auto-Training -- Test-Data");
626 ontime = AutoTrain(fDataSetTest, kTestOn, kTestOff, fFluxTest);
627 if (ontime<0)
628 return kFALSE;
629 }
630
631 // --------------------- Setup files --------------------
632 MReadReports read1;//("Events");
633 MReadMarsFile read2("Events");
634 MReadMarsFile read3("Events");
635 MReadReports read4;//("Events");
636 //read1.DisableAutoScheme();
637 read2.DisableAutoScheme();
638 read3.DisableAutoScheme();
639 //read4.DisableAutoScheme();
640
641 read1.AddTree("Events", "MTime.", MReadReports::kMaster);
642 read4.AddTree("Events", "MTime.", MReadReports::kMaster);
643 read1.AddTree("Drive", MReadReports::kRequired);
644 read4.AddTree("Drive", MReadReports::kRequired);
645 read1.AddTree("Starguider", MReadReports::kRequired);
646 read4.AddTree("Starguider", MReadReports::kRequired);
647
648 // Setup four reading tasks with the on- and off-data of the two datasets
649 if (!fDataSetTrain.AddFilesOn(read1))
650 return kFALSE;
651 const Bool_t setrc1 = fDataSetTrain.IsWobbleMode() ?
652 fDataSetTrain.AddFilesOn(read3) : fDataSetTrain.AddFilesOff(read3);
653 const Bool_t setrc2 = fDataSetTest.IsWobbleMode() ?
654 fDataSetTest.AddFilesOn(read2) : fDataSetTest.AddFilesOff(read2);
655 if (!setrc1 || !setrc2)
656 return kFALSE;
657 if (!fDataSetTest.AddFilesOn(read4))
658 return kFALSE;
659
660 // ----------------------- Setup RF Matrix ----------------------
661 MHMatrix train("Train");
662 train.AddColumns(fRules);
663 if (fEnableWeights[kTrainOn] || fEnableWeights[kTrainOff])
664 train.AddColumn("MWeight.fVal");
665 train.AddColumn("MHadronness.fVal");
666
667 // ----------------------- Fill Matrix RF ----------------------
668
669 // Setup the hadronness container identifying gammas and off-data
670 // and setup a container for the weights
671 MParameterD had("MHadronness");
672 MParameterD wgt("MWeight");
673
674 // Add them to the parameter list
675 MParList plistx;
676 plistx.AddToList(this); // take care of fDisplay!
677 plistx.AddToList(&had);
678 plistx.AddToList(&wgt);
679
680 // Setup the tool class to fill the matrix
681 MTFillMatrix fill;
682 fill.SetLogStream(fLog);
683 fill.SetDisplay(fDisplay);
684 fill.AddPreCuts(fPreCuts);
685 fill.AddPreCuts(fTrainCuts);
686
687 // Set classifier for gammas
688 had.SetVal(0);
689 wgt.SetVal(1);
690
691 // How to get source position from off- and on-data?
692 MPointingPos source("MSourcePos");
693 MObservatory obs;
694 MSrcPosCalc scalc;
695 MSrcPosCorrect scor;
696 MHillasCalc hcalcw;
697 MHillasCalc hcalcw2;
698 MPointingDevCalc devcalc;
699 scalc.SetMode(MSrcPosCalc::kDefault); // kWobble for off-source
700 hcalcw.SetFlags(MHillasCalc::kCalcHillasSrc);
701 hcalcw2.SetFlags(MHillasCalc::kCalcHillasSrc);
702 hcalcw2.SetNameHillasSrc("MHillasSrcAnti");
703 hcalcw2.SetNameSrcPosCam("MSrcPosAnti");
704 if (fDataSetTrain.IsWobbleMode())
705 {
706 // *******************************************************************
707 // Possible source position (eg. Wobble Mode)
708 if (fDataSetTrain.HasSource())
709 {
710 if (!fDataSetTrain.GetSourcePos(source))
711 return -1;
712 *fLog << all;
713 source.Print("RaDec");
714 }
715 else
716 *fLog << all << "No source position applied..." << endl;
717
718 // La Palma Magic1
719 plistx.AddToList(&obs);
720 plistx.AddToList(&source);
721
722 TList tlist2;
723 tlist2.Add(&scalc);
724 tlist2.Add(&scor);
725 tlist2.Add(&hcalcw);
726 tlist2.Add(&hcalcw2);
727
728 devcalc.SetStreamId("Starguider");
729 tlist2.Add(&devcalc);
730
731 fill.AddPreTasks(tlist2);
732 // *******************************************************************
733 }
734
735 // Setup the tool class to read the gammas and read them
736 fill.SetName("FillGammas");
737 fill.SetDestMatrix1(&train, fNum[kTrainOn]);
738 fill.SetReader(&read1);
739 fill.AddPreTasks(fPreTasksSet[kTrainOn]);
740 fill.AddPreTasks(fPreTasks);
741 fill.AddPostTasks(fPostTasksSet[kTrainOn]);
742 fill.AddPostTasks(fPostTasks);
743 if (!fill.Process(plistx))
744 return kFALSE;
745
746 // Check the number or read events
747 const Int_t numgammastrn = train.GetNumRows();
748 if (numgammastrn==0)
749 {
750 *fLog << err << "ERROR - No gammas available for training... aborting." << endl;
751 return kFALSE;
752 }
753
754 // Remove possible post tasks
755 fill.ClearPreTasks();
756 fill.ClearPostTasks();
757
758 // Set classifier for background
759 had.SetVal(1);
760 wgt.SetVal(1);
761
762 // In case of wobble mode we have to do something special
763 MSrcPosRndm srcrndm;
764 srcrndm.SetDistOfSource(0.4);
765
766 MHillasCalc hcalc;
767 MHillasCalc hcalc2;
768 hcalc.SetFlags(MHillasCalc::kCalcHillasSrc);
769 hcalc2.SetFlags(MHillasCalc::kCalcHillasSrc);
770 hcalc2.SetNameHillasSrc("MHillasSrcAnti");
771 hcalc2.SetNameSrcPosCam("MSrcPosAnti");
772
773 if (fDataSetTrain.IsWobbleMode())
774 {
775 scalc.SetMode(MSrcPosCalc::kWobble); // kWobble for off-source
776 fPreTasksSet[kTrainOff].AddFirst(&hcalc2);
777 fPreTasksSet[kTrainOff].AddFirst(&hcalc);
778 //fPreTasksSet[kTrainOff].AddFirst(&srcrndm);
779 fPreTasksSet[kTrainOff].AddFirst(&scor);
780 fPreTasksSet[kTrainOff].AddFirst(&scalc);
781 }
782
783 // Setup the tool class to read the background and read them
784 fill.SetName("FillBackground");
785 fill.SetDestMatrix1(&train, fNum[kTrainOff]);
786 fill.SetReader(&read3);
787 fill.AddPreTasks(fPreTasksSet[kTrainOff]);
788 fill.AddPreTasks(fPreTasks);
789 fill.AddPostTasks(fPostTasksSet[kTrainOff]);
790 fill.AddPostTasks(fPostTasks);
791 if (!fill.Process(plistx))
792 return kFALSE;
793
794 // Check the number or read events
795 const Int_t numbackgrndtrn = train.GetNumRows()-numgammastrn;
796 if (numbackgrndtrn==0)
797 {
798 *fLog << err << "ERROR - No background available for training... aborting." << endl;
799 return kFALSE;
800 }
801
802 // ------------------------ Train RF --------------------------
803
804 MRanForestCalc rf("TrainSeparation", fTitle);
805 rf.SetNumTrees(fNumTrees);
806 rf.SetNdSize(fNdSize);
807 rf.SetNumTry(fNumTry);
808 rf.SetNumObsoleteVariables(1);
809 rf.SetLastDataColumnHasWeights(fEnableWeights[kTrainOn] || fEnableWeights[kTrainOff]);
810 rf.SetDebug(fDebug>1);
811 rf.SetDisplay(fDisplay);
812 rf.SetLogStream(fLog);
813 rf.SetFileName(out);
814 rf.SetNameOutput("MHadronness");
815
816 // Train the random forest either by classification or regression
817 if (fUseRegression)
818 {
819 if (!rf.TrainRegression(train)) // regression
820 return kFALSE;
821 }
822 else
823 {
824 if (!rf.TrainSingleRF(train)) // classification
825 return kFALSE;
826 }
827
828 // Output information about what was going on so far.
829 *fLog << all;
830 fLog->Separator("The forest was trained with...");
831
832 *fLog << "Training method:" << endl;
833 *fLog << " * " << (fUseRegression?"regression":"classification") << endl;
834 if (fEnableWeights[kTrainOn])
835 *fLog << " * weights for on-data" << endl;
836 if (fEnableWeights[kTrainOff])
837 *fLog << " * weights for off-data" << endl;
838 if (fDataSetTrain.IsWobbleMode())
839 *fLog << " * random source position in a distance of 0.4°" << endl;
840 *fLog << endl;
841 *fLog << "Events used for training:" << endl;
842 *fLog << " * Gammas: " << numgammastrn << endl;
843 *fLog << " * Background: " << numbackgrndtrn << endl;
844 *fLog << endl;
845 *fLog << "Gamma/Background ratio:" << endl;
846 *fLog << " * Requested: " << (float)fNum[kTrainOn]/fNum[kTrainOff] << endl;
847 *fLog << " * Result: " << (float)numgammastrn/numbackgrndtrn << endl;
848 *fLog << endl;
849 *fLog << "Run-Time: " << Form("%.1f", clock.RealTime()/60) << "min (CPU: ";
850 *fLog << Form("%.1f", clock.CpuTime()/60) << "min)" << endl;
851 *fLog << endl;
852 *fLog << "Output file name: " << out << endl;
853
854 // Chekc if testing is requested
855 if (!fDataSetTest.IsValid())
856 return kTRUE;
857
858 // --------------------- Display result ----------------------
859 fLog->Separator("Test");
860
861 clock.Continue();
862
863 // Setup parlist and tasklist for testing
864 MParList plist;
865 MTaskList tlist;
866 plist.AddToList(this); // Take care of display
867 plist.AddToList(&tlist);
868
869 MMcEvt mcevt;
870 plist.AddToList(&mcevt);
871
872 plist.AddToList(&wgt);
873
874 // ----- Setup histograms -----
875 MBinning binsy(50, 0 , 1, "BinningMH3Y", "lin");
876 MBinning binsx(40, 10, 100000, "BinningMH3X", "log");
877
878 plist.AddToList(&binsx);
879 plist.AddToList(&binsy);
880
881 MH3 h31("MHillas.fSize", "MHadronness.fVal");
882 MH3 h32("MHillas.fSize", "MHadronness.fVal");
883 MH3 h40("MMcEvt.fEnergy", "MHadronness.fVal");
884 h31.SetTitle("Background probability vs. Size:Size [phe]:Hadronness h");
885 h32.SetTitle("Background probability vs. Size:Size [phe]:Hadronness h");
886 h40.SetTitle("Background probability vs. Energy:Energy [GeV]:Hadronness h");
887
888 MHHadronness hist;
889
890 // ----- Setup tasks -----
891 MFillH fillh0(&hist, "", "FillHadronness");
892 MFillH fillh1(&h31);
893 MFillH fillh2(&h32);
894 MFillH fillh4(&h40);
895 fillh0.SetWeight("MWeight");
896 fillh1.SetWeight("MWeight");
897 fillh2.SetWeight("MWeight");
898 fillh4.SetWeight("MWeight");
899 fillh1.SetDrawOption("colz profy");
900 fillh2.SetDrawOption("colz profy");
901 fillh4.SetDrawOption("colz profy");
902 fillh1.SetNameTab("Background");
903 fillh2.SetNameTab("GammasH");
904 fillh4.SetNameTab("GammasE");
905 fillh0.SetBit(MFillH::kDoNotDisplay);
906
907 // ----- Setup filter -----
908 MFilterList precuts;
909 precuts.AddToList(fPreCuts);
910 precuts.AddToList(fTestCuts);
911
912 MContinue c0(&precuts);
913 c0.SetName("PreCuts");
914 c0.SetInverted();
915
916 MFEventSelector sel; // FIXME: USING IT (WITH PROB?) in READ will by much faster!!!
917 sel.SetNumSelectEvts(fNum[kTestOff]);
918
919 MContinue c1(&sel);
920 c1.SetInverted();
921
922 // ----- Setup tasklist -----
923 tlist.AddToList(&read2);
924 if (fDataSetTest.IsWobbleMode())
925 {
926 tlist.AddToList(&srcrndm);
927 tlist.AddToList(&hcalc);
928 }
929 tlist.AddToList(&c1);
930 tlist.AddToList(fPreTasksSet[kTestOff]);
931 tlist.AddToList(fPreTasks);
932 tlist.AddToList(&c0);
933 tlist.AddToList(&rf);
934 tlist.AddToList(fPostTasksSet[kTestOff]);
935 tlist.AddToList(fPostTasks);
936 tlist.AddToList(&fillh0);
937 tlist.AddToList(&fillh1);
938
939 // Enable Acceleration
940 tlist.SetAccelerator(MTask::kAccDontReset|MTask::kAccDontTime);
941
942 // ----- Run eventloop on background -----
943 MEvtLoop loop;
944 loop.SetDisplay(fDisplay);
945 loop.SetLogStream(fLog);
946 loop.SetParList(&plist);
947 //if (!SetupEnv(loop))
948 // return kFALSE;
949
950 wgt.SetVal(1);
951 if (!loop.Eventloop())
952 return kFALSE;
953 /*
954 if (!loop.GetDisplay())
955 {
956 gLog << warn << "Display closed by user... execution aborted." << endl << endl;
957 return kFALSE;
958 }
959 */
960 // ----- Setup and run eventloop on gammas -----
961 sel.SetNumSelectEvts(fNum[kTestOn]);
962 fillh0.ResetBit(MFillH::kDoNotDisplay);
963
964 // Remove PreTasksOff and PostTasksOff from the list
965 tlist.RemoveFromList(fPreTasksSet[kTestOff]);
966 tlist.RemoveFromList(fPostTasksSet[kTestOff]);
967
968 // replace the reading task by a new one
969 tlist.Replace(&read4);
970
971 if (fDataSetTest.IsWobbleMode())
972 {
973 // *******************************************************************
974 // Possible source position (eg. Wobble Mode)
975 if (fDataSetTest.HasSource())
976 {
977 if (!fDataSetTest.GetSourcePos(source))
978 return -1;
979 *fLog << all;
980 source.Print("RaDec");
981 }
982 else
983 *fLog << all << "No source position applied..." << endl;
984
985 // La Palma Magic1
986 plist.AddToList(&obs);
987 plist.AddToList(&source);
988
989 // How to get source position from off- and on-data?
990 tlist.AddToListAfter(&scalc, &read4);
991 tlist.AddToListAfter(&scor, &scalc);
992 tlist.AddToListAfter(&hcalcw, &scor);
993
994 tlist.AddToList(&devcalc, "Starguider");
995 // *******************************************************************
996 }
997
998 // Add the PreTasksOn directly after the reading task
999 tlist.AddToListAfter(fPreTasksSet[kTestOn], &c1);
1000
1001 // Add the PostTasksOn after rf
1002 tlist.AddToListAfter(fPostTasksSet[kTestOn], &rf);
1003
1004 // Replace fillh1 by fillh2
1005 tlist.Replace(&fillh2);
1006
1007 // Add fillh4 after the new fillh2
1008 tlist.AddToListAfter(&fillh4, &fillh2);
1009
1010 // Enable Acceleration
1011 tlist.SetAccelerator(MTask::kAccDontReset|MTask::kAccDontTime);
1012
1013 wgt.SetVal(1);
1014 if (!loop.Eventloop())
1015 return kFALSE;
1016
1017 // Show what was going on in the testing
1018 const Double_t numgammastst = h32.GetHist().GetEntries();
1019 const Double_t numbackgrndtst = h31.GetHist().GetEntries();
1020
1021 *fLog << all;
1022 fLog->Separator("The forest was tested with...");
1023 *fLog << "Test method:" << endl;
1024 *fLog << " * Random Forest: " << out << endl;
1025 if (fEnableWeights[kTestOn])
1026 *fLog << " * weights for on-data" << endl;
1027 if (fEnableWeights[kTestOff])
1028 *fLog << " * weights for off-data" << endl;
1029 if (fDataSetTrain.IsWobbleMode())
1030 *fLog << " * random source position in a distance of 0.4°" << endl;
1031 *fLog << endl;
1032 *fLog << "Events used for test:" << endl;
1033 *fLog << " * Gammas: " << numgammastst << endl;
1034 *fLog << " * Background: " << numbackgrndtst << endl;
1035 *fLog << endl;
1036 *fLog << "Gamma/Background ratio:" << endl;
1037 *fLog << " * Requested: " << (float)fNum[kTestOn]/fNum[kTestOff] << endl;
1038 *fLog << " * Result: " << (float)numgammastst/numbackgrndtst << endl;
1039 *fLog << endl;
1040
1041 // Display the result plots
1042 DisplayResult(h31, h32, ontime);
1043
1044 *fLog << "Total Run-Time: " << Form("%.1f", clock.RealTime()/60) << "min (CPU: ";
1045 *fLog << Form("%.1f", clock.CpuTime()/60) << "min)" << endl;
1046 fLog->Separator();
1047
1048 fDataSetTrain.SetName("DataSetTrain");
1049 fDataSetTest.SetName("DataSetTest");
1050
1051 // Write the display
1052 TObjArray arr;
1053 arr.Add(const_cast<MDataSet*>(&fDataSetTrain));
1054 arr.Add(const_cast<MDataSet*>(&fDataSetTest));
1055 if (fDisplay)
1056 arr.Add(fDisplay);
1057
1058 SetPathOut(out);
1059 return WriteContainer(arr, 0, "UPDATE");
1060}
Note: See TracBrowser for help on using the repository browser.