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

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