source: trunk/MagicSoft/Mars/mhist/MHAlpha.cc@ 4837

Last change on this file since 4837 was 4837, checked in by tbretz, 20 years ago
*** empty log message ***
File size: 9.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, 3/2004 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2004
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MHAlpha
28//
29// Create a single Alpha-Plot. The alpha-plot is fitted online. You can
30// check the result when it is filles in the MStatusDisplay
31// For more information see MHFalseSource::FitSignificance
32//
33// For convinience (fit) the output significance is stored in a
34// container in the parlisrt
35//
36// PRELIMINARY!
37//
38//////////////////////////////////////////////////////////////////////////////
39#include "MHAlpha.h"
40
41#include <TF1.h>
42#include <TH2.h>
43#include <TGraph.h>
44#include <TStyle.h>
45#include <TLatex.h>
46#include <TCanvas.h>
47#include <TStopwatch.h>
48
49#include "MGeomCam.h"
50#include "MSrcPosCam.h"
51#include "MHillasSrc.h"
52#include "MTime.h"
53#include "MObservatory.h"
54#include "MPointingPos.h"
55#include "MAstroSky2Local.h"
56#include "MStatusDisplay.h"
57#include "MParameters.h"
58#include "MHMatrix.h"
59
60#include "MMath.h"
61#include "MBinning.h"
62#include "MParList.h"
63
64#include "MLog.h"
65#include "MLogManip.h"
66
67ClassImp(MHAlpha);
68
69using namespace std;
70
71// --------------------------------------------------------------------------
72//
73// Default Constructor
74//
75MHAlpha::MHAlpha(const char *name, const char *title)
76 : fAlphaCut(12.5), fBgMean(55), fResult(0), fMatrix(0)
77{
78 //
79 // set the name and title of this object
80 //
81 fName = name ? name : "MHAlpha";
82 fTitle = title ? title : "Alpha plot";
83
84 fHist.SetDirectory(NULL);
85
86 fHist.SetName("Alpha");
87 fHist.SetTitle("Alpha");
88 fHist.SetXTitle("|\\alpha| [\\circ]");
89 fHist.SetYTitle("Counts");
90 fHist.UseCurrentStyle();
91
92 MBinning binsa;
93 binsa.SetEdges(18, 0, 90);
94 binsa.Apply(fHist);
95
96 fSigInt=15;
97 fSigMax=75;
98 fBgMin=45;
99 fBgMax=90;
100 fPolynom=1;
101}
102
103Bool_t MHAlpha::SetupFill(const MParList *pl)
104{
105 fHist.Reset();
106
107 fResult = (MParameterD*)pl->FindObject("Significance", "MParameterD");
108 if (!fResult)
109 *fLog << warn << "Significance [MParameterD] not found... ignored." << endl;
110
111 return kTRUE;
112}
113
114// --------------------------------------------------------------------------
115//
116// Fill the histogram. For details see the code or the class description
117//
118Bool_t MHAlpha::Fill(const MParContainer *par, const Stat_t w)
119{
120 Double_t alpha;
121
122 if (fMatrix)
123 alpha = (*fMatrix)[fMap];
124 else
125 {
126 const MHillasSrc *hil = dynamic_cast<const MHillasSrc*>(par);
127 if (!par)
128 {
129 *fLog << err << dbginf << "MHillasSrc not found... abort." << endl;
130 return kFALSE;
131 }
132
133 alpha = hil->GetAlpha();
134 }
135
136 fHist.Fill(TMath::Abs(alpha), w);
137
138 return kTRUE;
139}
140
141// --------------------------------------------------------------------------
142//
143// Update the projections
144//
145void MHAlpha::Paint(Option_t *opt)
146{
147 DoFit();
148}
149
150// --------------------------------------------------------------------------
151//
152// Draw the histogram
153//
154void MHAlpha::Draw(Option_t *opt)
155{
156 TVirtualPad *pad = gPad ? gPad : MakeDefCanvas(this);
157 pad->SetBorderMode(0);
158
159 fHist.Draw();
160
161 AppendPad("");
162}
163
164// --------------------------------------------------------------------------
165//
166// This is a preliminary implementation of a alpha-fit procedure for
167// all possible source positions. It will be moved into its own
168// more powerfull class soon.
169//
170// The fit function is "gaus(0)+pol2(3)" which is equivalent to:
171// [0]*exp(-0.5*((x-[1])/[2])^2) + [3] + [4]*x + [5]*x^2
172// or
173// A*exp(-0.5*((x-mu)/sigma)^2) + a + b*x + c*x^2
174//
175// Parameter [1] is fixed to 0 while the alpha peak should be
176// symmetric around alpha=0.
177//
178// Parameter [4] is fixed to 0 because the first derivative at
179// alpha=0 should be 0, too.
180//
181// In a first step the background is fitted between bgmin and bgmax,
182// while the parameters [0]=0 and [2]=1 are fixed.
183//
184// In a second step the signal region (alpha<sigmax) is fittet using
185// the whole function with parameters [1], [3], [4] and [5] fixed.
186//
187// The number of excess and background events are calculated as
188// s = int(0, sigint, gaus(0)+pol2(3))
189// b = int(0, sigint, pol2(3))
190//
191// The Significance is calculated using the Significance() member
192// function.
193//
194Bool_t MHAlpha::DoFit(Double_t &sig, Bool_t paint)
195{
196 Float_t sigint=fSigInt;
197 Float_t sigmax=fSigMax;
198 Float_t bgmin=fBgMin;
199 Float_t bgmax=fBgMax;
200 Byte_t polynom=fPolynom;
201
202 // Implementing the function yourself is only about 5% faster
203 TF1 func("", Form("gaus(0) + pol%d(3)", polynom), 0, 90);
204 //TF1 func("", Form("[0]*(TMath::Gaus(x, [1], [2])+TMath::Gaus(x, -[1], [2]))+pol%d(3)", polynom), 0, 90);
205 TArrayD maxpar(func.GetNpar());
206
207 func.FixParameter(1, 0);
208 func.FixParameter(4, 0);
209 func.SetParLimits(2, 0, 90);
210 func.SetParLimits(3, -1, 1);
211
212 TH1 *h=&fHist;
213 const Double_t alpha0 = h->GetBinContent(1);
214 const Double_t alphaw = h->GetXaxis()->GetBinWidth(1);
215
216 // Check for the regios which is not filled...
217 if (alpha0==0)
218 return kFALSE; //*fLog << warn << "Histogram empty." << endl;
219
220 // First fit a polynom in the off region
221 func.FixParameter(0, 0);
222 func.FixParameter(2, 1);
223 func.ReleaseParameter(3);
224
225 for (int i=5; i<func.GetNpar(); i++)
226 func.ReleaseParameter(i);
227
228 h->Fit(&func, "N0Q", "", bgmin, bgmax);
229
230 const Double_t chisq1 = func.GetChisquare()/func.GetNDF();
231
232 // ------------------------------------
233 if (paint)
234 {
235 func.SetRange(0, 90);
236 func.SetLineColor(kRed);
237 func.Paint("same");
238 }
239 // ------------------------------------
240
241 func.ReleaseParameter(0);
242 //func.ReleaseParameter(1);
243 func.ReleaseParameter(2);
244 func.FixParameter(3, func.GetParameter(3));
245 for (int i=5; i<func.GetNpar(); i++)
246 func.FixParameter(i, func.GetParameter(i));
247
248 // Do not allow signals smaller than the background
249 const Double_t A = alpha0-func.GetParameter(3);
250 const Double_t dA = TMath::Abs(A);
251 func.SetParLimits(0, -dA*4, dA*4);
252 func.SetParLimits(2, 0, 90);
253
254 // Now fit a gaus in the on region on top of the polynom
255 func.SetParameter(0, A);
256 func.SetParameter(2, sigmax*0.75);
257
258 h->Fit(&func, "N0Q", "", 0, sigmax);
259
260 const Double_t chisq2 = func.GetChisquare()/func.GetNDF();
261 const Double_t sigmagaus = func.GetParameter(2);
262
263 // ------------------------------------
264 if (paint)
265 {
266 func.SetLineColor(kGreen);
267 func.Paint("same");
268 }
269 // ------------------------------------
270
271 const Double_t s = func.Integral(0, sigint)/alphaw;
272 func.SetParameter(0, 0);
273 func.SetParameter(2, 1);
274 const Double_t b = func.Integral(0, sigint)/alphaw;
275
276 sig = MMath::SignificanceLiMaSigned(s, b);
277
278 // ------------------------------------
279 // This is always draw one update too late... why?
280 //fHist.SetTitle(Form("\\sigma_{Li/Ma}=%.1f (\\alpha<%.1f\\circ) \\omega=%.1f\\circ E=%d (\\chi_{b}^{2}/N=%.1f \\chi_{s}^{2}/N=%.1f)",
281 // sig, fSigInt, sigmagaus, (int)(s-b), chisq1, chisq2));
282
283 if (paint)
284 {
285 TLatex text;
286 text.PaintLatex(3, fHist.GetMaximum()*1.11, 0, 0.04,
287 Form("\\sigma_{Li/Ma}=%.1f (\\alpha<%.1f\\circ) \\omega=%.1f\\circ E=%d (\\chi_{b}^{2}/N=%.1f \\chi_{s}^{2}/N=%.1f)",
288 sig, fSigInt, sigmagaus, (int)(s-b), chisq1, chisq2));
289 }
290 // ------------------------------------
291
292 return kTRUE;
293}
294
295Bool_t MHAlpha::Finalize()
296{
297 Double_t sig = 0;
298
299 if (!DoFit(sig))
300 {
301 *fLog << warn << "Histogram empty." << endl;
302 return kFALSE;
303 }
304
305 if (fResult)
306 fResult->SetVal(sig);
307
308 return kTRUE;
309}
310
311// --------------------------------------------------------------------------
312//
313// You can use this function if you want to use a MHMatrix instead of
314// MMcEvt. This function adds all necessary columns to the
315// given matrix. Afterward you should fill the matrix with the corresponding
316// data (eg from a file by using MHMatrix::Fill). If you now loop
317// through the matrix (eg using MMatrixLoop) MHHadronness::Fill
318// will take the values from the matrix instead of the containers.
319//
320void MHAlpha::InitMapping(MHMatrix *mat)
321{
322 if (fMatrix)
323 return;
324
325 fMatrix = mat;
326
327 fMap = fMatrix->AddColumn("MHillasSrc.fAlpha");
328}
329
330void MHAlpha::StopMapping()
331{
332 fMatrix = NULL;
333}
Note: See TracBrowser for help on using the repository browser.