source: trunk/Mars/msim/MHPhotonEvent.cc@ 9844

Last change on this file since 9844 was 9567, checked in by tbretz, 15 years ago
*** empty log message ***
File size: 11.7 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of CheObs, the Modular 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 appears 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, 1/2009 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: CheObs Software Development, 2000-2009
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MHPhotonEvent
28//
29// This is a histogram class to visualize the contents of a MPhotonEvent.
30//
31// Histograms for the distribution in x/y (z is just ignored), the
32// arrival direction, a profile of the arrival time vs position and
33// a spectrum is filles and displayed.
34//
35// There are several types of histograms (in the sense of binnings)
36// for several purposes:
37//
38// Type 1:
39// The maximum in x and y is determined from MCorsikaRunHeader
40// (not yet implemented. Fixed to 25000, 100 bins)
41//
42// Type 2:
43// The maximum in x and y is determined from MReflector->GetMaxR();
44// (100 bins)
45//
46// Type 3:
47// The maximum in x and y is determined from MGeomCam->GetMaxR();
48// (roughly 10 bins per pixel)
49//
50// Type 4:
51// Two times the traversal size of pixel #0 ( 4*MGeomCam[0].GetT() )
52// (101 bins, units cm)
53//
54// Type 5:
55// As type 3 but in cm instead of mm
56//
57// The binning is optimized using MH::FindGoodLimits.
58//
59// Fill expects a MPhotonEvent (the second argumnet in MFillH).
60//
61//
62// Class Version 2:
63// ----------------
64// + TH1D fHistH;
65//
66// Class Version 3:
67// ----------------
68// + replaced TH1D by TH1F
69// + replaced TH2D by TH2F
70//
71/////////////////////////////////////////////////////////////////////////////
72#include "MHPhotonEvent.h"
73
74#include <TCanvas.h>
75
76#include "MLog.h"
77#include "MLogManip.h"
78
79#include "MBinning.h"
80#include "MParList.h"
81
82#include "MGeomCam.h"
83#include "MGeomPix.h"
84
85#include "MPhotonEvent.h"
86#include "MPhotonData.h"
87
88#include "MCorsikaRunHeader.h"
89
90#include "MReflector.h"
91
92ClassImp(MHPhotonEvent);
93
94using namespace std;
95
96void MHPhotonEvent::Init(const char *name, const char *title)
97{
98 fName = name ? name : "MHPhotonEvent";
99 fTitle = title ? title : "Histogram to display the information of MPhotonEvents";
100
101 fHistXY.SetName("Position");
102 fHistXY.SetTitle("Histogram of position x/y");
103 fHistXY.SetXTitle("X [cm]");
104 fHistXY.SetYTitle("Y [cm]");
105 fHistXY.SetZTitle("Counts");
106 fHistXY.SetDirectory(NULL);
107 fHistXY.Sumw2();
108
109 fHistUV.SetName("Direction");
110 fHistUV.SetTitle("Histogram of arrival direction CosU/CosV");
111 fHistUV.SetXTitle("CosU");
112 fHistUV.SetYTitle("CosV");
113 fHistUV.SetZTitle("Counts");
114 fHistUV.SetDirectory(NULL);
115 fHistUV.Sumw2();
116
117 fHistT.SetName("Time");
118 fHistT.SetTitle("Time profile in x/y");
119 fHistT.SetXTitle("X [cm]");
120 fHistT.SetYTitle("Y [cm]");
121 fHistT.SetZTitle("T [ns]");
122 fHistT.SetDirectory(NULL);
123
124 fHistWL.SetName("Spectrum");
125 fHistWL.SetTitle("Wavelength distribution");
126 fHistWL.SetXTitle("\\lambda [nm]");
127 fHistWL.SetYTitle("Counts");
128 fHistWL.SetDirectory(NULL);
129
130 fHistH.SetName("Height");
131 fHistH.SetTitle("Production Height");
132 fHistH.SetXTitle("h [km]");
133 fHistH.SetYTitle("Counts");
134 fHistH.SetDirectory(NULL);
135}
136
137// --------------------------------------------------------------------------
138//
139// Default constructor. Creates and initializes the histograms.
140//
141MHPhotonEvent::MHPhotonEvent(Double_t max, const char *name, const char *title)
142 : fHistT("", "", 1, 0, 1, 1, 0, 1), fType(-1), fPermanentReset(kFALSE)
143{
144 // pre-initialization of the profile is necessary to get fZmin and fZmax set
145
146 Init(name, title);
147
148 MBinning binsd, binsa;
149 binsd.SetEdges(50, -max, max);
150 binsa.SetEdges(50, -1, 1);
151
152 SetBinning(&fHistXY, &binsd, &binsd);
153 SetBinning(&fHistUV, &binsa, &binsa);
154 SetBinning(&fHistT, &binsd, &binsd);
155}
156
157// --------------------------------------------------------------------------
158//
159// Creates and initializes the histograms.
160//
161MHPhotonEvent::MHPhotonEvent(Int_t type, const char *name, const char *title)
162 : fHistT("", "", 1, 0, 1, 1, 0, 1), fType(type), fPermanentReset(kFALSE)
163{
164 // pre-initialization of the profile is necessary to get fZmin and fZmax set
165
166 Init(name, title);
167
168 MBinning binsd, bins;
169 bins.SetEdges(50, -1, 1);
170
171 SetBinning(&fHistUV, &bins, &bins);
172}
173
174// --------------------------------------------------------------------------
175//
176// Find good limits for a binning num x [-max;max]
177// and apply it to fHistXY and fHistT.
178//
179void MHPhotonEvent::SetBinningXY(Int_t num, Double_t max)
180{
181 Double_t min = -max;
182
183 MH::FindGoodLimits(num, num, min, max, kFALSE);
184 MH::FindGoodLimits(num, num, min, max, kFALSE);
185 MBinning binsd, binsa, binsz;
186 binsd.SetEdges(num, min, max);
187
188 SetBinning(&fHistXY, &binsd, &binsd);
189 SetBinning(&fHistT, &binsd, &binsd);
190}
191
192// --------------------------------------------------------------------------
193//
194// Search for MRflEvtData, MRflEvtHeader and MGeomCam
195//
196Bool_t MHPhotonEvent::SetupFill(const MParList *pList)
197{
198 Double_t xmax = -1;
199 Int_t num = 100;
200
201 const Int_t f = fPermanentReset ? 2 : 1;
202 MBinning(100/f, 0, 25).Apply(fHistH);
203 MBinning(70, 275, 625).Apply(fHistWL);
204
205 switch (fType)
206 {
207 case -1:
208 return kTRUE;
209 // case0: Take a value defined by the user
210 case 1:
211 xmax = 25000;
212 break;
213 case 2:
214 {
215 MReflector *r = (MReflector*)pList->FindObject("Reflector", "MReflector");
216 if (!r)
217 {
218 *fLog << err << "Reflector [MReflector] not found... aborting." << endl;
219 return kFALSE;
220 }
221 xmax = r->GetMaxR();
222 break;
223 }
224 case 3: // The maximum radius (mm)
225 fHistXY.SetXTitle("X [mm]");
226 fHistXY.SetYTitle("Y [mm]");
227 fHistT.SetXTitle("X [mm]");
228 fHistT.SetYTitle("Y [mm]");
229 // *Fallthrough*
230
231 case 4: // Two times the pixel-0 traversal size
232 case 5: // The maximum radius (cm)
233 {
234 MGeomCam *c = (MGeomCam*)pList->FindObject("MGeomCam");
235 if (!c)
236 {
237 *fLog << err << "MGeomCam not found... aborting." << endl;
238 return kFALSE;
239 }
240 // Type 3: Define ~10 bins per pixel
241 xmax = fType==3 ? c->GetMaxRadius() : 4*(*c)[0].GetT()/10;
242 num = fType==3 ? TMath::Nint(10*(2*c->GetMaxRadius())/(2*(*c)[0].GetT())) : 101;
243
244 if (fType==5)
245 xmax /= 10;
246
247 break;
248 }
249 default:
250 *fLog << err << "No valid binning (Type=" << fType << ") given... aborting." << endl;
251 return kFALSE;
252 }
253
254 SetBinningXY(num, xmax);
255
256 return kTRUE;
257}
258
259// --------------------------------------------------------------------------
260//
261// ReInit overwrites the binning of the Wavelength histogram
262// by the wavlenegth band from MCorsikaRunHeader.
263// The bin-width is 5nm (fPermanentReset==kTRUE) or 10nm (kFALSE).
264//
265Bool_t MHPhotonEvent::ReInit(MParList *pList)
266{
267 MCorsikaRunHeader *h = (MCorsikaRunHeader*)pList->FindObject("MCorsikaRunHeader");
268 if (!h)
269 {
270 *fLog << err << "MCorsikaRunHeader not found... aborting." << endl;
271 return kFALSE;
272 }
273
274 /*
275 // What is the size of the light pool onm the ground?
276 if (fType==1)
277 SetBinningXY(100, h->GetImpactMax());
278 */
279
280 const Int_t f = fPermanentReset ? 10 : 2;
281
282 Double_t xmin = h->GetWavelengthMin()-20;
283 Double_t xmax = h->GetWavelengthMax()+20;
284 Int_t num = TMath::CeilNint((xmax-xmin)/f);
285
286 MH::FindGoodLimits(num, num, xmin, xmax, kTRUE);
287
288 MBinning(TMath::Abs(num), xmin-.5, xmax-.5).Apply(fHistWL);
289
290 return kTRUE;
291}
292
293// --------------------------------------------------------------------------
294//
295// Fill contents of MPhotonEvent into histograms
296//
297Int_t MHPhotonEvent::Fill(const MParContainer *par, const Stat_t weight)
298{
299 const MPhotonEvent *evt = dynamic_cast<const MPhotonEvent*>(par);
300 if (!evt)
301 {
302 *fLog << err << dbginf << "No MPhotonEvent found..." << endl;
303 return kERROR;
304 }
305
306 // Check if we want to use this class as a single event display
307 if (fPermanentReset && evt->GetNumPhotons()>0)
308 Clear();
309
310 // Get number of photons
311 const Int_t num = evt->GetNumPhotons();
312
313 // Set minimum to maximum possible value
314 Double_t min = FLT_MAX;
315
316 // Loop over all photons and determine the time of the first photon
317 // FIXME: Should we get it from some statistics container?
318 for (Int_t idx=0; idx<num; idx++)
319 min = TMath::Min(min, (*evt)[idx].GetTime());
320
321 // Now fill all histograms
322 for (Int_t idx=0; idx<num; idx++)
323 {
324 const MPhotonData &ph = (*evt)[idx];
325
326 if (ph.GetPrimary()==MMcEvtBasic::kNightSky)
327 continue;
328
329 const Double_t x = ph.GetPosX();
330 const Double_t y = ph.GetPosY();
331 const Double_t u = ph.GetCosU();
332 const Double_t v = ph.GetCosV();
333 const Double_t t = ph.GetTime()-min;
334 const Double_t w = ph.GetWavelength();
335 const Double_t h = ph.GetProductionHeight()/100000;
336
337 //TVector3 dir = dat->GetDir3();
338 //dir *= -1./dir.Z();
339
340 fHistXY.Fill(x, y);
341 fHistUV.Fill(u, v);
342 fHistT.Fill(x, y, t);
343 fHistWL.Fill(w);
344 fHistH.Fill(h);
345 }
346
347 return kTRUE;
348}
349
350// --------------------------------------------------------------------------
351//
352/*
353Bool_t MHPhotonEvent::Finalize()
354{
355 const TAxis &axey = *fHistRad.GetYaxis();
356 for (int y=1; y<=fHistRad.GetNbinsY(); y++)
357 {
358 const Double_t lo = axey.GetBinLowEdge(y);
359 const Double_t hi = axey.GetBinLowEdge(y+1);
360
361 const Double_t A = (hi*hi-lo*lo)*TMath::Pi()*TMath::Pi();
362
363 for (int x=1; x<=fHistRad.GetNbinsX(); x++)
364 fHistRad.SetBinContent(x, y, fHistRad.GetBinContent(x, y)/A);
365 }
366 return kTRUE;
367}
368*/
369
370// --------------------------------------------------------------------------
371//
372// Make sure that the TProfile2D doesn't fix it's displayed minimum at 0.
373// Set the pretty-palette.
374//
375void MHPhotonEvent::Paint(Option_t *opt)
376{
377 SetPalette("pretty");
378
379 fHistT.SetMinimum();
380 fHistT.SetMinimum(fHistT.GetMinimum(0));
381}
382
383// --------------------------------------------------------------------------
384//
385void MHPhotonEvent::Draw(Option_t *o)
386{
387 TVirtualPad *pad = gPad ? gPad : MakeDefCanvas(this);
388 pad->SetBorderMode(0);
389
390 AppendPad();
391
392 pad->Divide(3,2);
393
394 pad->cd(1);
395 gPad->SetBorderMode(0);
396 gPad->SetGrid();
397 fHistXY.Draw("colz");
398
399 pad->cd(2);
400 gPad->SetBorderMode(0);
401 gPad->SetGrid();
402 fHistT.Draw("colz");
403
404 pad->cd(4);
405 gPad->SetBorderMode(0);
406 gPad->SetGrid();
407 fHistUV.Draw("colz");
408
409 pad->cd(5);
410 gPad->SetBorderMode(0);
411 gPad->SetGrid();
412 fHistWL.Draw();
413
414 pad->cd(6);
415 gPad->SetBorderMode(0);
416 gPad->SetGrid();
417 fHistH.Draw();
418}
419
420// --------------------------------------------------------------------------
421//
422// PermanentReset: Off
423//
424Int_t MHPhotonEvent::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
425{
426 Bool_t rc = kFALSE;
427 if (IsEnvDefined(env, prefix, "PermanentReset", print))
428 {
429 rc = kTRUE;
430 fPermanentReset = GetEnvValue(env, prefix, "PermanentReset", fPermanentReset);
431 }
432
433 return rc;
434}
Note: See TracBrowser for help on using the repository browser.