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

Last change on this file since 19669 was 19661, checked in by tbretz, 5 years ago
Removed a stray cout
File size: 13.3 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 "MOptics.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 MOptics *r = (MOptics*)pList->FindObject("Reflector", "MOptics");
218 if (!r)
219 {
220 *fLog << err << "Reflector [MOptics] 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 case 9: // The maximum radius (cm) -- ~ 50 bins / pix
239 {
240 MGeomCam *c = (MGeomCam*)pList->FindObject("MGeomCam");
241 if (!c)
242 {
243 *fLog << err << "MGeomCam not found... aborting." << endl;
244 return kFALSE;
245 }
246 // Type 3: Define ~10 bins per pixel
247 xmax = fType!=4 ? c->GetMaxRadius() : 4*(*c)[0].GetT()/10;
248
249 switch (fType)
250 {
251 case 3:
252 case 5:
253 // ~10 bins per pixel
254 num = TMath::Nint(10*c->GetMaxRadius()/(*c)[0].GetT());
255 break;
256 case 6:
257 // ~5 bins per pixel
258 num = TMath::Nint(5*c->GetMaxRadius()/(*c)[0].GetT());
259 break;
260 case 7:
261 // ~3 bins per pixel
262 num = TMath::Nint(3*c->GetMaxRadius()/(*c)[0].GetT());
263 break;
264 case 8:
265 // ~2 bins per pixel
266 num = TMath::Nint(2*c->GetMaxRadius()/(*c)[0].GetT());
267 break;
268 case 4:
269 num = 101;
270 break;
271 case 9:
272 // ~50 bins per pixel
273 num = TMath::Nint(50*c->GetMaxRadius()/(*c)[0].GetT());
274 break;
275 }
276
277 if (fType==5 || fType==6 || fType==7 || fType==9)
278 xmax /= 10;
279
280 break;
281 }
282 default:
283 *fLog << err << "No valid binning (Type=" << fType << ") given... aborting." << endl;
284 return kFALSE;
285 }
286
287 SetBinningXY(num, xmax);
288
289 return kTRUE;
290}
291
292// --------------------------------------------------------------------------
293//
294// ReInit overwrites the binning of the Wavelength histogram
295// by the wavlenegth band from MCorsikaRunHeader.
296// The bin-width is 5nm (fPermanentReset==kTRUE) or 10nm (kFALSE).
297//
298Bool_t MHPhotonEvent::ReInit(MParList *pList)
299{
300 MCorsikaRunHeader *h = (MCorsikaRunHeader*)pList->FindObject("MCorsikaRunHeader");
301 if (!h)
302 {
303 *fLog << err << "MCorsikaRunHeader not found... aborting." << endl;
304 return kFALSE;
305 }
306
307 if (fType==1)
308 {
309 // N=100: see SetupFill
310 MBinning *bins = (MBinning*)pList->FindObject("BinningImpact", "MBinning");
311 if (bins)
312 SetBinningXY(100, bins->GetEdgeHi()*100);
313 }
314
315 /*
316 // What is the size of the light pool onm the ground?
317 if (fType==1)
318 SetBinningXY(100, h->GetImpactMax());
319 */
320
321 const Int_t f = fPermanentReset ? 10 : 2;
322
323 Double_t xmin = h->GetWavelengthMin()-20;
324 Double_t xmax = h->GetWavelengthMax()+20;
325 Int_t num = TMath::CeilNint((xmax-xmin)/f);
326
327 MH::FindGoodLimits(num, num, xmin, xmax, kTRUE);
328
329 MBinning(TMath::Abs(num), xmin-.5, xmax-.5).Apply(fHistWL);
330
331 return kTRUE;
332}
333
334// --------------------------------------------------------------------------
335//
336// Fill contents of MPhotonEvent into histograms
337//
338Int_t MHPhotonEvent::Fill(const MParContainer *par, const Stat_t weight)
339{
340 const MPhotonEvent *evt = dynamic_cast<const MPhotonEvent*>(par);
341 if (!evt)
342 {
343 *fLog << err << dbginf << "No MPhotonEvent found..." << endl;
344 return kERROR;
345 }
346
347 // Check if we want to use this class as a single event display
348 if (fPermanentReset && evt->GetNumPhotons()>0)
349 Clear();
350
351 // Get number of photons
352 const Int_t num = evt->GetNumPhotons();
353
354 // Set minimum to maximum possible value
355 Double_t min = FLT_MAX;
356
357 // Loop over all photons and determine the time of the first photon
358 // FIXME: Should we get it from some statistics container?
359 for (Int_t idx=0; idx<num; idx++)
360 min = TMath::Min(min, (*evt)[idx].GetTime());
361
362 // Now fill all histograms
363 for (Int_t idx=0; idx<num; idx++)
364 {
365 const MPhotonData &ph = (*evt)[idx];
366
367 if (ph.GetPrimary()==MMcEvtBasic::kNightSky || ph.GetPrimary()==MMcEvtBasic::kArtificial)
368 continue;
369
370 const Double_t x = ph.GetPosX();
371 const Double_t y = ph.GetPosY();
372 const Double_t u = ph.GetCosU();
373 const Double_t v = ph.GetCosV();
374 const Double_t t = ph.GetTime()-min;
375 const Double_t w = ph.GetWavelength();
376 const Double_t h = ph.GetProductionHeight()/100000;
377
378 //TVector3 dir = dat->GetDir3();
379 //dir *= -1./dir.Z();
380
381 fHistXY.Fill(x, y);
382 fHistUV.Fill(u, v);
383 fHistT.Fill(x, y, t);
384 fHistWL.Fill(w);
385 fHistH.Fill(h);
386 }
387
388 return kTRUE;
389}
390
391// --------------------------------------------------------------------------
392//
393/*
394Bool_t MHPhotonEvent::Finalize()
395{
396 const TAxis &axey = *fHistRad.GetYaxis();
397 for (int y=1; y<=fHistRad.GetNbinsY(); y++)
398 {
399 const Double_t lo = axey.GetBinLowEdge(y);
400 const Double_t hi = axey.GetBinLowEdge(y+1);
401
402 const Double_t A = (hi*hi-lo*lo)*TMath::Pi()*TMath::Pi();
403
404 for (int x=1; x<=fHistRad.GetNbinsX(); x++)
405 fHistRad.SetBinContent(x, y, fHistRad.GetBinContent(x, y)/A);
406 }
407 return kTRUE;
408}
409*/
410
411// --------------------------------------------------------------------------
412//
413// Make sure that the TProfile2D doesn't fix it's displayed minimum at 0.
414// Set the pretty-palette.
415//
416void MHPhotonEvent::Paint(Option_t *opt)
417{
418 SetPalette("pretty");
419
420 fHistT.SetMinimum();
421 fHistT.SetMinimum(fHistT.GetMinimum(0));
422}
423
424// --------------------------------------------------------------------------
425//
426void MHPhotonEvent::Draw(Option_t *o)
427{
428 TVirtualPad *pad = gPad ? gPad : MakeDefCanvas(this);
429 pad->SetBorderMode(0);
430
431 AppendPad();
432
433 pad->Divide(3,2);
434
435 pad->cd(1);
436 gPad->SetBorderMode(0);
437 gPad->SetGrid();
438 fHistXY.Draw("colz");
439
440 pad->cd(2);
441 gPad->SetBorderMode(0);
442 gPad->SetGrid();
443 fHistT.Draw("colz");
444
445 pad->cd(4);
446 gPad->SetBorderMode(0);
447 gPad->SetGrid();
448 fHistUV.Draw("colz");
449
450 pad->cd(5);
451 gPad->SetBorderMode(0);
452 gPad->SetGrid();
453 fHistWL.Draw();
454
455 pad->cd(6);
456 gPad->SetBorderMode(0);
457 gPad->SetGrid();
458 fHistH.Draw();
459}
460
461// --------------------------------------------------------------------------
462//
463// PermanentReset: Off
464//
465Int_t MHPhotonEvent::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
466{
467 Bool_t rc = kFALSE;
468 if (IsEnvDefined(env, prefix, "PermanentReset", print))
469 {
470 rc = kTRUE;
471 fPermanentReset = GetEnvValue(env, prefix, "PermanentReset", fPermanentReset);
472 }
473 if (IsEnvDefined(env, prefix, "MaxImpact", print))
474 {
475 rc = kTRUE;
476 fMaxImpact = GetEnvValue(env, prefix, "MaxImpact", fMaxImpact);
477 }
478
479 return rc;
480}
Note: See TracBrowser for help on using the repository browser.