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

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