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

Last change on this file since 9875 was 9851, checked in by tbretz, 14 years ago
Changed MH::SetBinning and similar functions to take references instead of pointers as arguments. For convenience wrappers for the old style functions are provided.
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 const MBinning binsd(50, -max, max);
149 const MBinning binsa(50, -1, 1);
150
151 SetBinning(fHistXY, binsd, binsd);
152 SetBinning(fHistUV, binsa, binsa);
153 SetBinning(fHistT, binsd, binsd);
154}
155
156// --------------------------------------------------------------------------
157//
158// Creates and initializes the histograms.
159//
160MHPhotonEvent::MHPhotonEvent(Int_t type, const char *name, const char *title)
161 : fHistT("", "", 1, 0, 1, 1, 0, 1), fType(type), fPermanentReset(kFALSE)
162{
163 // pre-initialization of the profile is necessary to get fZmin and fZmax set
164
165 Init(name, title);
166
167 const MBinning bins(50, -1, 1);
168
169 SetBinning(fHistUV, bins, bins);
170}
171
172// --------------------------------------------------------------------------
173//
174// Find good limits for a binning num x [-max;max]
175// and apply it to fHistXY and fHistT.
176//
177void MHPhotonEvent::SetBinningXY(Int_t num, Double_t max)
178{
179 Double_t min = -max;
180
181 MH::FindGoodLimits(num, num, min, max, kFALSE);
182 MH::FindGoodLimits(num, num, min, max, kFALSE);
183
184 const MBinning binsd(num, min, max);
185
186 SetBinning(fHistXY, binsd, binsd);
187 SetBinning(fHistT, binsd, binsd);
188}
189
190// --------------------------------------------------------------------------
191//
192// Search for MRflEvtData, MRflEvtHeader and MGeomCam
193//
194Bool_t MHPhotonEvent::SetupFill(const MParList *pList)
195{
196 Double_t xmax = -1;
197 Int_t num = 100;
198
199 const Int_t f = fPermanentReset ? 2 : 1;
200 MBinning(100/f, 0, 25).Apply(fHistH);
201 MBinning(70, 275, 625).Apply(fHistWL);
202
203 switch (fType)
204 {
205 case -1:
206 return kTRUE;
207 // case0: Take a value defined by the user
208 case 1:
209 xmax = 25000;
210 break;
211 case 2:
212 {
213 MReflector *r = (MReflector*)pList->FindObject("Reflector", "MReflector");
214 if (!r)
215 {
216 *fLog << err << "Reflector [MReflector] not found... aborting." << endl;
217 return kFALSE;
218 }
219 xmax = r->GetMaxR();
220 break;
221 }
222 case 3: // The maximum radius (mm)
223 fHistXY.SetXTitle("X [mm]");
224 fHistXY.SetYTitle("Y [mm]");
225 fHistT.SetXTitle("X [mm]");
226 fHistT.SetYTitle("Y [mm]");
227 // *Fallthrough*
228
229 case 4: // Two times the pixel-0 traversal size
230 case 5: // The maximum radius (cm)
231 {
232 MGeomCam *c = (MGeomCam*)pList->FindObject("MGeomCam");
233 if (!c)
234 {
235 *fLog << err << "MGeomCam not found... aborting." << endl;
236 return kFALSE;
237 }
238 // Type 3: Define ~10 bins per pixel
239 xmax = fType==3 ? c->GetMaxRadius() : 4*(*c)[0].GetT()/10;
240 num = fType==3 ? TMath::Nint(10*(2*c->GetMaxRadius())/(2*(*c)[0].GetT())) : 101;
241
242 if (fType==5)
243 xmax /= 10;
244
245 break;
246 }
247 default:
248 *fLog << err << "No valid binning (Type=" << fType << ") given... aborting." << endl;
249 return kFALSE;
250 }
251
252 SetBinningXY(num, xmax);
253
254 return kTRUE;
255}
256
257// --------------------------------------------------------------------------
258//
259// ReInit overwrites the binning of the Wavelength histogram
260// by the wavlenegth band from MCorsikaRunHeader.
261// The bin-width is 5nm (fPermanentReset==kTRUE) or 10nm (kFALSE).
262//
263Bool_t MHPhotonEvent::ReInit(MParList *pList)
264{
265 MCorsikaRunHeader *h = (MCorsikaRunHeader*)pList->FindObject("MCorsikaRunHeader");
266 if (!h)
267 {
268 *fLog << err << "MCorsikaRunHeader not found... aborting." << endl;
269 return kFALSE;
270 }
271
272 /*
273 // What is the size of the light pool onm the ground?
274 if (fType==1)
275 SetBinningXY(100, h->GetImpactMax());
276 */
277
278 const Int_t f = fPermanentReset ? 10 : 2;
279
280 Double_t xmin = h->GetWavelengthMin()-20;
281 Double_t xmax = h->GetWavelengthMax()+20;
282 Int_t num = TMath::CeilNint((xmax-xmin)/f);
283
284 MH::FindGoodLimits(num, num, xmin, xmax, kTRUE);
285
286 MBinning(TMath::Abs(num), xmin-.5, xmax-.5).Apply(fHistWL);
287
288 return kTRUE;
289}
290
291// --------------------------------------------------------------------------
292//
293// Fill contents of MPhotonEvent into histograms
294//
295Int_t MHPhotonEvent::Fill(const MParContainer *par, const Stat_t weight)
296{
297 const MPhotonEvent *evt = dynamic_cast<const MPhotonEvent*>(par);
298 if (!evt)
299 {
300 *fLog << err << dbginf << "No MPhotonEvent found..." << endl;
301 return kERROR;
302 }
303
304 // Check if we want to use this class as a single event display
305 if (fPermanentReset && evt->GetNumPhotons()>0)
306 Clear();
307
308 // Get number of photons
309 const Int_t num = evt->GetNumPhotons();
310
311 // Set minimum to maximum possible value
312 Double_t min = FLT_MAX;
313
314 // Loop over all photons and determine the time of the first photon
315 // FIXME: Should we get it from some statistics container?
316 for (Int_t idx=0; idx<num; idx++)
317 min = TMath::Min(min, (*evt)[idx].GetTime());
318
319 // Now fill all histograms
320 for (Int_t idx=0; idx<num; idx++)
321 {
322 const MPhotonData &ph = (*evt)[idx];
323
324 if (ph.GetPrimary()==MMcEvtBasic::kNightSky)
325 continue;
326
327 const Double_t x = ph.GetPosX();
328 const Double_t y = ph.GetPosY();
329 const Double_t u = ph.GetCosU();
330 const Double_t v = ph.GetCosV();
331 const Double_t t = ph.GetTime()-min;
332 const Double_t w = ph.GetWavelength();
333 const Double_t h = ph.GetProductionHeight()/100000;
334
335 //TVector3 dir = dat->GetDir3();
336 //dir *= -1./dir.Z();
337
338 fHistXY.Fill(x, y);
339 fHistUV.Fill(u, v);
340 fHistT.Fill(x, y, t);
341 fHistWL.Fill(w);
342 fHistH.Fill(h);
343 }
344
345 return kTRUE;
346}
347
348// --------------------------------------------------------------------------
349//
350/*
351Bool_t MHPhotonEvent::Finalize()
352{
353 const TAxis &axey = *fHistRad.GetYaxis();
354 for (int y=1; y<=fHistRad.GetNbinsY(); y++)
355 {
356 const Double_t lo = axey.GetBinLowEdge(y);
357 const Double_t hi = axey.GetBinLowEdge(y+1);
358
359 const Double_t A = (hi*hi-lo*lo)*TMath::Pi()*TMath::Pi();
360
361 for (int x=1; x<=fHistRad.GetNbinsX(); x++)
362 fHistRad.SetBinContent(x, y, fHistRad.GetBinContent(x, y)/A);
363 }
364 return kTRUE;
365}
366*/
367
368// --------------------------------------------------------------------------
369//
370// Make sure that the TProfile2D doesn't fix it's displayed minimum at 0.
371// Set the pretty-palette.
372//
373void MHPhotonEvent::Paint(Option_t *opt)
374{
375 SetPalette("pretty");
376
377 fHistT.SetMinimum();
378 fHistT.SetMinimum(fHistT.GetMinimum(0));
379}
380
381// --------------------------------------------------------------------------
382//
383void MHPhotonEvent::Draw(Option_t *o)
384{
385 TVirtualPad *pad = gPad ? gPad : MakeDefCanvas(this);
386 pad->SetBorderMode(0);
387
388 AppendPad();
389
390 pad->Divide(3,2);
391
392 pad->cd(1);
393 gPad->SetBorderMode(0);
394 gPad->SetGrid();
395 fHistXY.Draw("colz");
396
397 pad->cd(2);
398 gPad->SetBorderMode(0);
399 gPad->SetGrid();
400 fHistT.Draw("colz");
401
402 pad->cd(4);
403 gPad->SetBorderMode(0);
404 gPad->SetGrid();
405 fHistUV.Draw("colz");
406
407 pad->cd(5);
408 gPad->SetBorderMode(0);
409 gPad->SetGrid();
410 fHistWL.Draw();
411
412 pad->cd(6);
413 gPad->SetBorderMode(0);
414 gPad->SetGrid();
415 fHistH.Draw();
416}
417
418// --------------------------------------------------------------------------
419//
420// PermanentReset: Off
421//
422Int_t MHPhotonEvent::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
423{
424 Bool_t rc = kFALSE;
425 if (IsEnvDefined(env, prefix, "PermanentReset", print))
426 {
427 rc = kTRUE;
428 fPermanentReset = GetEnvValue(env, prefix, "PermanentReset", fPermanentReset);
429 }
430
431 return rc;
432}
Note: See TracBrowser for help on using the repository browser.