source: trunk/MagicSoft/Mars/mjobs/MJSpectrum.cc@ 6966

Last change on this file since 6966 was 6966, checked in by tbretz, 20 years ago
*** empty log message ***
File size: 18.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, 4/2005 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2005
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MJSpectrum
28//
29// Program to calculate spectrum
30//
31/////////////////////////////////////////////////////////////////////////////
32#include "MJSpectrum.h"
33
34// Root
35#include <TF1.h>
36#include <TH1.h>
37#include <TH2.h>
38#include <TFile.h>
39#include <TChain.h>
40#include <TCanvas.h>
41#include <TObjArray.h>
42
43// Environment
44#include "MLog.h"
45#include "MLogManip.h"
46
47#include "MStatusArray.h"
48#include "MStatusDisplay.h"
49
50// Container
51#include "MH3.h"
52#include "MBinning.h"
53#include "MDataSet.h"
54
55// Spectrum
56#include "../mhflux/MAlphaFitter.h"
57#include "../mhflux/MHAlpha.h"
58#include "../mhflux/MHCollectionArea.h"
59#include "../mhflux/MHEnergyEst.h"
60
61// Eventloop
62#include "MEvtLoop.h"
63#include "MTaskList.h"
64#include "MParList.h"
65
66// Tasks/Filter
67#include "MReadMarsFile.h"
68#include "MFEventSelector2.h"
69#include "MFDataMember.h"
70#include "MFillH.h"
71#include "MHillasCalc.h"
72#include "MSrcPosCalc.h"
73#include "MContinue.h"
74
75ClassImp(MJSpectrum);
76
77using namespace std;
78
79MJSpectrum::MJSpectrum(const char *name, const char *title)
80 : fCut0(0),fCut1(0), fCut2(0), fCut3(0), fEstimateEnergy(0),
81 fRefill(kFALSE), fSimpleMode(kTRUE)
82{
83 fName = name ? name : "MJSpectrum";
84 fTitle = title ? title : "Standard program to calculate spectrum";
85}
86
87MJSpectrum::~MJSpectrum()
88{
89 if (fCut0)
90 delete fCut0;
91 if (fCut1)
92 delete fCut1;
93 if (fCut2)
94 delete fCut2;
95 if (fCut3)
96 delete fCut3;
97 if (fEstimateEnergy)
98 delete fEstimateEnergy;
99}
100
101Bool_t MJSpectrum::ReadTask(MTask* &task, const char *name) const
102{
103 if (task)
104 {
105 delete task;
106 task = 0;
107 }
108
109 task = (MTask*)gFile->Get(name);
110 if (!task)
111 {
112 *fLog << err << dbginf << "ERROR - " << name << " doen't exist in file!" << endl;
113 return kFALSE;
114 }
115 if (!task->InheritsFrom(MTask::Class()))
116 {
117 *fLog << err << dbginf << "ERROR - " << name << " read doesn't inherit from MTask!" << endl;
118 delete task;
119 return kFALSE;
120 }
121
122 task->SetName(name);
123
124 return kTRUE;
125}
126
127Bool_t MJSpectrum::ReadInput(const MParList &plist)
128{
129 const TString fname = fPathIn;
130
131 *fLog << inf << "Reading from file: " << fname << endl;
132
133 TFile file(fname, "READ");
134 if (!file.IsOpen())
135 {
136 *fLog << err << dbginf << "ERROR - Could not open file " << fname << endl;
137 return kFALSE;
138 }
139
140 if (!ReadTask(fCut0, "Cut0"))
141 return kFALSE;
142 if (!ReadTask(fCut1, "Cut1"))
143 return kFALSE;
144 if (!ReadTask(fCut2, "Cut2"))
145 return kFALSE;
146 if (!ReadTask(fCut3, "Cut3"))
147 return kFALSE;
148
149 if (!ReadTask(fEstimateEnergy, "EstimateEnergy"))
150 return kFALSE;
151
152 TObjArray arr;
153
154 TIter Next(plist);
155 TObject *o=0;
156 while ((o=Next()))
157 if (o->InheritsFrom(MBinning::Class()))
158 arr.Add(o);
159
160 arr.Add(plist.FindObject("MAlphaFitter"));
161
162 return ReadContainer(arr);
163}
164
165void MJSpectrum::PrintSetup(const MAlphaFitter &fit) const
166{
167 gLog.Separator("Alpha Fitter");
168 *fLog << all;
169 fit.Print();
170
171 gLog.Separator("Used Cuts");
172 fCut0->Print();
173 fCut1->Print();
174 fCut2->Print();
175 fCut3->Print();
176
177 gLog.Separator("Energy Estimator");
178 fEstimateEnergy->Print();
179}
180
181Float_t MJSpectrum::ReadHistograms(TH1D &h1, TH1D &h2) const
182{
183 TFile file(fPathIn, "READ");
184 if (!file.IsOpen())
185 {
186 *fLog << err << dbginf << "ERROR - Could not open file " << fPathIn << endl;
187 return -1;
188 }
189
190 MStatusArray *arr = (MStatusArray*)file.Get("MStatusDisplay");
191 if (!arr)
192 {
193 gLog << "MStatusDisplay not found in file... abort." << endl;
194 return -1;
195 }
196
197 TH1D *vstime = (TH1D*)arr->FindObjectInCanvas("Theta", "TH1D", "OnTime");
198 TH1D *excen = (TH1D*)arr->FindObjectInCanvas("ExcessEnergy", "TH1D", "MHAlpha");
199 if (!vstime || !excen)
200 return -1;
201
202 vstime->Copy(h1);
203 excen->Copy(h2);
204 h1.SetDirectory(0);
205 h2.SetDirectory(0);
206
207 if (fDisplay)
208 arr->DisplayIn(*fDisplay, "MHAlpha");
209
210 delete arr;
211
212 return vstime->Integral();
213}
214
215Bool_t MJSpectrum::ReadOrigMCDistribution(const MDataSet &set, TH1 &h) const
216{
217 // Some debug output
218 fLog->Separator("Compiling original MC distribution");
219
220 *fLog << inf << "Please stand by, this may take a while..." << flush;
221
222 if (fDisplay)
223 fDisplay->SetStatusLine1("Compiling MC distribution...");
224
225 // Create chain
226 TChain chain("OriginalMC");
227 set.AddFilesOn(chain);
228
229 // Prepare histogram
230 h.Reset();
231
232 // Fill histogram from chain
233 h.SetDirectory(gROOT);
234 if (h.InheritsFrom(TH2::Class()))
235 {
236 h.SetNameTitle("ThetaEMC", "Event-Distribution vs Theta and Energy for MC (produced)");
237 h.SetXTitle("\\Theta [\\circ]");
238 h.SetYTitle("E [GeV]");
239 h.SetZTitle("Counts");
240 chain.Draw("MMcEvtBasic.fEnergy:MMcEvtBasic.fTelescopeTheta*TMath::RadToDeg()>>ThetaEMC", "", "goff");
241 }
242 else
243 {
244 h.SetNameTitle("ThetaMC", "Event-Distribution vs Theta for MC (produced)");
245 h.SetXTitle("\\Theta [\\circ]");
246 h.SetYTitle("Counts");
247 chain.Draw("MMcEvtBasic.fTelescopeTheta*TMath::RadToDeg()>>ThetaMC", "", "goff");
248 }
249 h.SetDirectory(0);
250
251 *fLog << "done." << endl;
252 if (fDisplay)
253 fDisplay->SetStatusLine2("done.");
254
255 if (h.GetEntries()>0)
256 return kTRUE;
257
258 *fLog << err << "ERROR - Histogram with original MC distribution empty..." << endl;
259
260 return h.GetEntries()>0;
261}
262
263Bool_t MJSpectrum::GetThetaDistribution(TH1D &temp1, TH1D &temp2) const
264{
265 // Display some stuff
266 if (fDisplay)
267 {
268 TCanvas &c = fDisplay->AddTab("ZdDist");
269 c.Divide(2,2);
270
271 // On-Time vs. Theta
272 c.cd(1);
273 gPad->SetBorderMode(0);
274 temp1.DrawCopy();
275
276 // Number of MC events (produced) vs Theta
277 c.cd(2);
278 gPad->SetBorderMode(0);
279 temp2.SetName("NVsTheta");
280 temp2.DrawCopy();
281
282 c.cd(4);
283 gPad->SetBorderMode(0);
284
285 c.cd(3);
286 gPad->SetBorderMode(0);
287 }
288
289 // Calculate the Probability
290 temp1.Divide(&temp2);
291 temp1.Scale(1./temp1.GetMaximum());
292
293 // Some cosmetics: Name, Axis, etc.
294 temp1.SetName("ProbVsTheta");
295 temp1.SetTitle("Probability vs. Zenith Angle to choose MC events");
296 temp1.SetYTitle("Probability");
297 if (fDisplay)
298 temp1.DrawCopy();
299
300 return kTRUE;
301}
302
303void MJSpectrum::DisplayResult(const TH2D &h2) const
304{
305 if (!fDisplay->CdCanvas("ZdDist"))
306 return;
307
308 TH1D &proj = *h2.ProjectionX();
309 proj.SetNameTitle("ThetaFinal", "Final Theta Distribution");
310 proj.SetXTitle("\\Theta [\\circ]");
311 proj.SetYTitle("Counts");
312 proj.SetLineColor(kBlue);
313 proj.SetDirectory(0);
314 proj.SetBit(kCanDelete);
315
316 TVirtualPad *pad = gPad;
317
318 pad->cd(4);
319 proj.DrawCopy();
320
321 pad->cd(1);
322 TH1D *theta = (TH1D*)gPad->FindObject("Theta");
323 if (theta)
324 {
325 proj.Scale(theta->Integral()/proj.Integral());
326 theta->SetMaximum(1.05*TMath::Max(theta->GetMaximum(), proj.GetMaximum()));
327 }
328 proj.Draw("same");
329}
330
331Bool_t MJSpectrum::Refill(MParList &plist, TH1D &h2) const
332{
333 *fLog << endl;
334 fLog->Separator("Refill Excess");
335 *fLog << endl;
336
337 MTaskList tlist;
338 plist.AddToList(&tlist);
339
340 MReadTree read("Events");
341 read.DisableAutoScheme();
342 read.AddFile(fPathIn);
343
344 MFillH fill1("MHAlphaOff [MHAlpha]", "MHillasSrc", "FillAlpha");
345 MFillH fill2("MHAlpha", "MHillasSrc", "FillAlpha");
346
347 MFDataMember f0("DataType.fVal", '<', 0.5, "FilterOffData");
348 MFDataMember f1("DataType.fVal", '>', 0.5, "FilterOnData");
349
350 fill1.SetFilter(&f0);
351 fill2.SetFilter(&f1);
352
353 tlist.AddToList(&read);
354 tlist.AddToList(fEstimateEnergy);
355 tlist.AddToList(&f0);
356 tlist.AddToList(&f1);
357 tlist.AddToList(&fill1);
358 tlist.AddToList(&fill2);
359
360 MEvtLoop loop(fName);
361 loop.SetParList(&plist);
362 loop.SetDisplay(fDisplay);
363 loop.SetLogStream(fLog);
364
365 if (!SetupEnv(loop))
366 return kFALSE;
367
368 if (!loop.Eventloop())
369 {
370 *fLog << err << GetDescriptor() << ": Refilling of data failed." << endl;
371 return kFALSE;
372 }
373
374 tlist.PrintStatistics();
375
376 if (!loop.GetDisplay())
377 {
378 *fLog << err << GetDescriptor() << ": Execution stopped by user." << endl;
379 return kFALSE;
380 }
381
382 const MHAlpha *halpha = (MHAlpha *)plist.FindObject("MHAlpha");
383 if (!halpha)
384 {
385 *fLog << err << GetDescriptor() << ": MHAlpha not found... abort." << endl;
386 return kFALSE;
387 }
388
389 halpha->GetHEnergy().Copy(h2);
390 h2.SetDirectory(0);
391
392 return kTRUE;
393}
394
395Bool_t MJSpectrum::Process(const MDataSet &set)
396{
397 if (!set.IsValid())
398 {
399 *fLog << err << "ERROR - DataSet invalid!" << endl;
400 return kFALSE;
401 }
402
403 CheckEnv();
404
405 // --------------------------------------------------------------------------------
406
407 *fLog << inf;
408 fLog->Separator(GetDescriptor());
409 *fLog << "Compile Monte Carlo Sample (data set " << set.GetName() << ")" << endl;
410 *fLog << endl;
411
412 MBinning bins1("BinningAlpha");
413 MBinning bins2("BinningEnergyEst");
414 MBinning bins3("BinningTheta");
415 MBinning bins4("BinningFalseSource");
416 MBinning bins5("BinningWidth");
417 MBinning bins6("BinningLength");
418 MBinning bins7("BinningDist");
419 MBinning bins8("BinningMaxDist");
420
421 MAlphaFitter fit;
422
423 MParList plist;
424 plist.AddToList(&bins1);
425 plist.AddToList(&bins2);
426 plist.AddToList(&bins3);
427 plist.AddToList(&bins4);
428 plist.AddToList(&bins5);
429 plist.AddToList(&bins6);
430 plist.AddToList(&bins7);
431 plist.AddToList(&bins8);
432 plist.AddToList(&fit);
433
434 if (!ReadInput(plist))
435 return kFALSE;
436
437 PrintSetup(fit);
438
439 TH1D temp1, excess;
440 const Float_t ontime = ReadHistograms(temp1, excess);
441 if (ontime<0)
442 {
443 *fLog << err << GetDescriptor() << ": Could not determin effective on time..." << endl;
444 return kFALSE;
445 }
446
447 TH1D temp2(temp1);
448 if (!ReadOrigMCDistribution(set, temp2))
449 return kFALSE;
450
451 if (!GetThetaDistribution(temp1, temp2))
452 return kFALSE;
453
454 if (fRefill && !Refill(plist, temp2))
455 return kFALSE;
456
457 TH2D hist;
458 MH3 mh1("MMcEvtBasic.fTelescopeTheta*kRad2Deg", "MMcEvtBasic.fEnergy");
459 if (fSimpleMode)
460 {
461 hist.UseCurrentStyle();
462 MH::SetBinning(&hist, temp1.GetXaxis(), excess.GetXaxis());
463 if (!ReadOrigMCDistribution(set, hist))
464 return kFALSE;
465
466 for (int y=0; y<hist.GetNbinsY(); y++)
467 for (int x=0; x<hist.GetNbinsX(); x++)
468 hist.SetBinContent(x, y, hist.GetBinContent(x, y)*temp1.GetBinContent(x));
469 }
470 else
471 {
472 MTaskList tlist1;
473 plist.Replace(&tlist1);
474
475 MReadMarsFile readmc("OriginalMC");
476 //readmc.DisableAutoScheme();
477 set.AddFilesOn(readmc);
478 readmc.EnableBranch("MMcEvtBasic.fTelescopeTheta");
479 readmc.EnableBranch("MMcEvtBasic.fEnergy");
480
481 mh1.SetLogy();
482 mh1.SetLogz();
483 mh1.SetName("ThetaE");
484
485 MFillH fill0(&mh1);
486 //fill0.SetDrawOption("projx only");
487
488 MBinning binsx(bins3, "BinningThetaEX");
489 MBinning binsy(bins2, "BinningThetaEY");
490 plist.AddToList(&binsx);
491 plist.AddToList(&binsy);
492 tlist1.AddToList(&readmc);
493
494 temp1.SetXTitle("MMcEvtBasic.fTelescopeTheta*kRad2Deg");
495 MH3 mh3mc(temp1);
496
497 MFEventSelector2 sel1(mh3mc);
498 sel1.SetHistIsProbability();
499
500 fill0.SetFilter(&sel1);
501
502 tlist1.AddToList(&sel1);
503 tlist1.AddToList(&fill0);
504
505 MEvtLoop loop1(fName);
506 loop1.SetParList(&plist);
507 loop1.SetLogStream(fLog);
508 loop1.SetDisplay(fDisplay);
509
510 if (!SetupEnv(loop1))
511 return kFALSE;
512
513 if (!loop1.Eventloop(fMaxEvents))
514 {
515 *fLog << err << GetDescriptor() << ": Processing of MC-data failed." << endl;
516 return kFALSE;
517 }
518
519 tlist1.PrintStatistics();
520
521 if (!loop1.GetDisplay())
522 {
523 *fLog << err << GetDescriptor() << ": Execution stopped by user." << endl;
524 return kFALSE;
525 }
526 }
527
528 DisplayResult(fSimpleMode ? hist : (TH2D&)mh1.GetHist());
529
530 // ------------------------- Final loop --------------------------
531
532 *fLog << endl;
533 fLog->Separator("Calculate efficiencies");
534 *fLog << endl;
535
536 MTaskList tlist2;
537 plist.Replace(&tlist2);
538
539 MReadMarsFile read("Events");
540 read.DisableAutoScheme();
541 set.AddFilesOn(read);
542
543 // Selector to get correct (final) theta-distribution
544 temp1.SetXTitle("MPointingPos.fZd");
545
546 MH3 mh3(temp1);
547
548 MFEventSelector2 sel2(mh3);
549 sel2.SetHistIsProbability();
550
551 MContinue contsel(&sel2);
552 contsel.SetInverted();
553
554 // Get correct source position
555 MSrcPosCalc calc;
556
557 // Calculate corresponding Hillas parameters
558 MHillasCalc hcalc1;
559 MHillasCalc hcalc2("MHillasCalcAnti");
560 hcalc1.SetFlags(MHillasCalc::kCalcHillasSrc);
561 hcalc2.SetFlags(MHillasCalc::kCalcHillasSrc);
562 hcalc2.SetNameHillasSrc("MHillasSrcAnti");
563 hcalc2.SetNameSrcPosCam("MSrcPosAnti");
564
565 // Fill collection area and energy estimator (unfolding)
566 // Make sure to use the same binning for MHCollectionArea and MHEnergyEst
567 MHCollectionArea area;
568 area.SetHistAll(fSimpleMode ? hist : (TH2D&)mh1.GetHist());
569 MHEnergyEst hest;
570
571 MFillH fill3(&area, "", "FillCollectionArea");
572 MFillH fill4(&hest, "", "FillEnergyEst");
573
574 MFillH fill1a("MHHillasMCPre [MHHillas]", "MHillas", "FillHillasPre");
575 MFillH fill2a("MHHillasMCPost [MHHillas]", "MHillas", "FillHillasPost");
576 MFillH fill3a("MHVsSizeMCPost [MHVsSize]", "MHillasSrc", "FillVsSizePost");
577 MFillH fill4a("MHHilExtMCPost [MHHillasExt]", "MHillasSrc", "FillHilExtPost");
578 MFillH fill5a("MHHilSrcMCPost [MHHillasSrc]", "MHillasSrc", "FillHilSrcPost");
579 MFillH fill6a("MHImgParMCPost [MHImagePar]", "MImagePar", "FillImgParPost");
580 MFillH fill7a("MHNewParMCPost [MHNewImagePar]", "MNewImagePar", "FillNewParPost");
581 fill1a.SetNameTab("PreCut");
582 fill2a.SetNameTab("PostCut");
583 fill3a.SetNameTab("VsSize");
584 fill4a.SetNameTab("HilExt");
585 fill5a.SetNameTab("HilSrc");
586 fill6a.SetNameTab("ImgPar");
587 fill7a.SetNameTab("NewPar");
588
589 tlist2.AddToList(&read);
590 tlist2.AddToList(&contsel);
591 tlist2.AddToList(&calc);
592 tlist2.AddToList(&hcalc1);
593 tlist2.AddToList(&hcalc2);
594 tlist2.AddToList(&fill1a);
595 tlist2.AddToList(fCut0);
596 tlist2.AddToList(fCut1);
597 tlist2.AddToList(fCut2);
598 tlist2.AddToList(fCut3);
599 tlist2.AddToList(fEstimateEnergy);
600 tlist2.AddToList(&fill3);
601 tlist2.AddToList(&fill4);
602 tlist2.AddToList(&fill2a);
603 tlist2.AddToList(&fill3a);
604 tlist2.AddToList(&fill4a);
605 tlist2.AddToList(&fill5a);
606 tlist2.AddToList(&fill6a);
607 tlist2.AddToList(&fill7a);
608
609 MEvtLoop loop2(fName);
610 loop2.SetParList(&plist);
611 loop2.SetDisplay(fDisplay);
612 loop2.SetLogStream(fLog);
613
614 if (!SetupEnv(loop2))
615 return kFALSE;
616
617 if (!loop2.Eventloop(fMaxEvents))
618 {
619 *fLog << err << GetDescriptor() << ": Processing of MC-data failed." << endl;
620 return kFALSE;
621 }
622
623 tlist2.PrintStatistics();
624
625 if (!loop2.GetDisplay())
626 {
627 *fLog << err << GetDescriptor() << ": Execution stopped by user." << endl;
628 return kFALSE;
629 }
630
631 // -------------------------- Spectrum ----------------------------
632
633 TH1D collarea(area.GetHEnergy());
634 TH1D weights;
635 hest.GetWeights(weights);
636
637 cout << "Effective On time: " << ontime << "s" << endl;
638
639 excess.SetDirectory(NULL);
640 excess.SetBit(kCanDelete);
641 excess.Scale(1./ontime);
642 excess.Divide(&collarea);
643 excess.SetNameTitle("Preliminary", "N/sm^{2} versus Energy (before unfolding)");
644 excess.SetYTitle("N/sm^{2}");
645
646 TCanvas &c = fDisplay->AddTab("Spectrum");
647 c.Divide(2,2);
648 c.cd(1);
649 gPad->SetBorderMode(0);
650 gPad->SetLogx();
651 gPad->SetLogy();
652 gPad->SetGridx();
653 gPad->SetGridy();
654 collarea.DrawCopy();
655
656 c.cd(2);
657 gPad->SetBorderMode(0);
658 gPad->SetLogx();
659 gPad->SetLogy();
660 gPad->SetGridx();
661 gPad->SetGridy();
662 excess.DrawCopy();
663
664 c.cd(3);
665 gPad->SetBorderMode(0);
666 gPad->SetLogx();
667 gPad->SetLogy();
668 gPad->SetGridx();
669 gPad->SetGridy();
670 weights.DrawCopy();
671
672 excess.Divide(&weights);
673 //excess.Multiply(&weights);
674 excess.SetNameTitle("Flux", "N/TeVsm^{2} versus Energy (after unfolding)");
675
676 for (int i=0; i<excess.GetNbinsX(); i++)
677 {
678 excess.SetBinContent(i+1, excess.GetBinContent(i+1)/excess.GetBinWidth(i+1)*1000);
679 excess.SetBinError(i+1, excess.GetBinError(i+1)/ excess.GetBinWidth(i+1)*1000);
680 }
681
682 excess.SetYTitle("N/TeVsm^{2}");
683
684 c.cd(4);
685 gPad->SetBorderMode(0);
686 gPad->SetLogx();
687 gPad->SetLogy();
688 gPad->SetGridx();
689 gPad->SetGridy();
690 excess.DrawCopy();
691
692 TF1 f("f", "[1]*(x/1e3)^[0]", 50, 3e4);
693 f.SetParameter(0, -2.87);
694 f.SetParameter(1, 1.9e-6);
695 f.SetLineColor(kGreen);
696 excess.Fit(&f, "NI", "", 55, 2e4);
697 f.DrawCopy("same");
698
699 if (!fPathOut.IsNull())
700 fDisplay->SaveAsRoot(fPathOut);
701
702 /*
703 TString str;
704 str += "(1.68#pm0.15)10^{-7}";
705 str += "(\\frac{E}{TeV})^{-2.59#pm0.06}";
706 str += "\\frac{ph}{TeVm^{2}s}";
707
708 TLatex tex;
709 tex.DrawLatex(2e2, 7e-5, str);
710 */
711
712 return kTRUE;
713}
Note: See TracBrowser for help on using the repository browser.