source: trunk/MagicSoft/Mars/msim/MPhotonEvent.cc@ 9235

Last change on this file since 9235 was 9232, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 11.9 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC 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 appear 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, 12/2000 <mailto:tbretz@astro.uni-wuerzburg.de>
19! Author(s): Qi Zhe, 06/2007 <mailto:qizhe@astro.uni-wuerzburg.de>
20!
21! Copyright: Software Development, 2000-2009
22!
23!
24\* ======================================================================== */
25
26/////////////////////////////////////////////////////////////////////////////
27//
28// MPhotonEvent
29//
30// Storage container to store photon collections
31//
32// The class is designed to be extremely fast which is important taking into
33// account the extremely high number of photons. This has some impacts on
34// its handling.
35//
36// The list has to be kept consistent, i.e. without holes.
37//
38// There are two ways to achieve this:
39//
40// a) Use RemoveAt to remove an entry somewhere
41// b) Compress() the TClonesArray afterwards
42//
43// Compress is not the fastes, so there is an easier way.
44//
45// a) When you loop over the list and want to remove an entry copy all
46// following entry backward in the list, so that the hole will
47// be created at its end.
48// b) Call Shrink(n) with n the number of valid entries in your list.
49//
50// To loop over the TClonesArray you can use a TIter which has some
51// unnecessary overhead and therefore is slower than necessary.
52//
53// Since the list is kept consistent you can use a simple loop saving
54// a lot of CPU time taking into account the high number of calls to
55// TObjArrayIter::Next which you would create.
56//
57// Here is an example (how to remove every second entry)
58//
59// Int_t cnt = 0;
60//
61// const Int_t num = event->GetNumPhotons();
62// for (Int_t idx=0; idx<num; idx++)
63// {
64// if (idx%2==0)
65// continue;
66//
67// MPhotonData *dat = (*event)[idx];
68//
69// (*event)[cnt++] = *dat;
70// }
71//
72// event->Shrink(cnt);
73//
74// ---------------------------------- or -------------------------------
75//
76// TClonesArray &arr = MPhotonEvent->GetArray();
77//
78// Int_t cnt = 0;
79//
80// const Int_t num = arr.GetEntriesFast();
81// for (Int_t idx=0; idx<num; idx++)
82// {
83// if (idx%2==0)
84// continue;
85//
86// MPhotonData *dat = static_cast<MPhotonData*>(arr.UncheckedAt(idx));
87//
88// *static_cast<MPhotonData*>(arr.UncheckedAt(cnt++)) = *dat;
89// }
90//
91// MPhotonEvent->Shrink(cnt);
92//
93//
94// Version 1:
95// ----------
96// - First implementation
97//
98/////////////////////////////////////////////////////////////////////////////
99#include "MPhotonEvent.h"
100
101#include <fstream>
102#include <iostream>
103
104#include <TMarker.h>
105
106#include "MLog.h"
107#include "MLogManip.h"
108
109#include "MPhotonData.h"
110
111ClassImp(MPhotonEvent);
112
113using namespace std;
114
115// --------------------------------------------------------------------------
116//
117// Default constructor. It initializes all arrays with zero size.
118//
119MPhotonEvent::MPhotonEvent(const char *name, const char *title)
120 : fData("MPhotonData", 1)
121{
122 fName = name ? name : "MPhotonEvent";
123 fTitle = title ? title : "Corsika Event Data Information";
124
125 fData.SetBit(TClonesArray::kForgetBits);
126 fData.BypassStreamer(kFALSE);
127}
128
129const char *MPhotonEvent::GetClassName() const
130{
131 return static_cast<TObject*>(fData.GetClass())->GetName();
132}
133
134// --------------------------------------------------------------------------
135//
136// If n is smaller than the current allocated array size a reference to
137// the n-th entry is returned, otherwise an entry at n is created
138// calling the default constructor. Note, that there is no range check
139// but it is not recommended to call this function with
140// n>fData.GetSize()
141//
142MPhotonData &MPhotonEvent::Add(Int_t n)
143{
144 // Do not modify this. It is optimized for execution
145 // speed and flexibility!
146 TObject *o = n<fData.GetSize() && fData.UncheckedAt(n) ? fData.UncheckedAt(n) : fData.New(n);
147
148 // Now we read a single cherenkov bunch
149 return static_cast<MPhotonData&>(*o);
150}
151
152// --------------------------------------------------------------------------
153//
154// Add a new photon (MPhtonData) at the end of the array.
155// In this case the default constructor of MPhotonData is called.
156//
157// A reference to the new object is returned.
158//
159MPhotonData &MPhotonEvent::Add()
160{
161 return Add(GetNumPhotons());
162}
163
164// --------------------------------------------------------------------------
165//
166// Get the i-th photon from the array. Not, for speed reasons there is no
167// range check so you are responsible that you do not excess the number
168// of photons (GetNumPhotons)
169//
170MPhotonData &MPhotonEvent::operator[](UInt_t idx)
171{
172 return *static_cast<MPhotonData*>(fData.UncheckedAt(idx));
173}
174
175// --------------------------------------------------------------------------
176//
177// Get the i-th photon from the array. Not, for speed reasons there is no
178// range check so you are responsible that you do not excess the number
179// of photons (GetNumPhotons)
180//
181const MPhotonData &MPhotonEvent::operator[](UInt_t idx) const
182{
183 return *static_cast<MPhotonData*>(fData.UncheckedAt(idx));
184}
185
186Int_t MPhotonEvent::ReadCorsikaEvt(istream &fin)
187{
188 Int_t n = 0;
189
190 while (1)
191 {
192 // Check the first four bytes
193 char c[4];
194 fin.read(c, 4);
195
196 // End of stream
197 if (!fin)
198 return kFALSE;
199
200 // Check if we found the end of the event
201 if (!memcmp(c, "EVTE", 4))
202 break;
203
204 // The first for byte contained data already --> go back
205 fin.seekg(-4, ios::cur);
206
207 // Do not modify this. It is optimized for execution
208 // speed and flexibility!
209 MPhotonData &ph = Add(n);
210 // It checks how many entries the lookup table has. If it has enough
211 // entries and the entry was already allocated, we can re-use it,
212 // otherwise we have to allocate it.
213
214 // Now we read a single cherenkov bunch. Note that for speed reason we have not
215 // called the constructor if the event was already constructed (virtual table
216 // set), consequently we must make sure that ReadCorsikaEvent does reset
217 // all data mebers no matter whether they are read or not.
218 const Int_t rc = ph.ReadCorsikaEvt(fin);
219
220 // Evaluate result from reading event
221 switch (rc)
222 {
223 case kCONTINUE: continue; // No data in this bunch... skip it.
224 case kFALSE: return kFALSE; // End of stream
225 case kERROR: return kERROR; // Error occured
226 }
227
228 // FIXME: If fNumPhotons!=1 add the photon more than once
229
230 // Now increase the number of entries which are kept,
231 // i.e. keep this photon(s)
232 n++;
233 }
234
235 Shrink(n);
236
237 SetReadyToSave();
238
239 //*fLog << all << "Number of photon bunches: " << fData.GetEntriesFast() << endl;
240 return kTRUE;
241}
242
243Int_t MPhotonEvent::ReadRflEvt(std::istream &fin)
244{
245 Int_t n = 0;
246
247 while (1)
248 {
249 // Check the first four bytes
250 char c[13];
251 fin.read(c, 13);
252
253 // End of stream
254 if (!fin)
255 return kFALSE;
256
257 // Check if we found the end of the event
258 if (!memcmp(c, "\nEND---EVENT\n", 13))
259 break;
260
261 // The first for byte contained data already --> go back
262 fin.seekg(-13, ios::cur);
263
264 // Do not modify this. It is optimized for execution
265 // speed and flexibility!
266 //TObject *o = n<fData.GetSize() && fData.UncheckedAt(n) ? fData.UncheckedAt(n) : fData.New(n);
267
268 // Now we read a single cherenkov bunch
269 //const Int_t rc = static_cast<MPhotonData*>(o)->ReadRflEvt(fin);
270 const Int_t rc = Add(n).ReadRflEvt(fin);
271
272 // Evaluate result from reading event
273 switch (rc)
274 {
275 case kCONTINUE: continue; // No data in this bunch... skip it.
276 case kFALSE: return kFALSE; // End of stream
277 case kERROR: return kERROR; // Error occured
278 }
279
280 // Now increase the number of entries which are kept,
281 // i.e. keep this photon(s)
282 n++;
283 }
284
285 Shrink(n);
286
287 SetReadyToSave();
288
289 //*fLog << all << "Number of photon bunches: " << fData.GetEntriesFast() << endl;
290 return kTRUE;
291}
292
293void MPhotonEvent::Print(Option_t *) const
294{
295 fData.Print();
296}
297
298/*
299// --------------------------------------------------------------------------
300//
301// Fills all photon distances scaled with scale (default=1) into a TH1
302//
303void MPhotonEvent::FillRad(TH1 &hist, Float_t scale) const
304{
305 MPhotonData *ph=NULL;
306
307 TIter Next(&fData);
308 while ((ph=(MPhotonData*)Next()))
309 ph->FillRad(hist, scale);
310}
311
312// --------------------------------------------------------------------------
313//
314// Fills all photon distances scaled with scale (default=1) versus x
315// into a TH2
316//
317void MPhotonEvent::FillRad(TH2 &hist, Double_t x, Float_t scale) const
318{
319 MPhotonData *ph=NULL;
320
321 TIter Next(&fData);
322 while ((ph=(MPhotonData*)Next()))
323 ph->FillRad(hist, x, scale);
324}
325
326// --------------------------------------------------------------------------
327//
328// Fills all photons (x,y) scaled with scale (default=1) into a TH2.
329//
330void MPhotonEvent::Fill(TH2 &hist, Float_t scale) const
331{
332 MPhotonData *ph=NULL;
333
334 TIter Next(&fData);
335 while ((ph=(MPhotonData*)Next()))
336 ph->Fill(hist, scale);
337}
338
339// --------------------------------------------------------------------------
340//
341// Fills all photons (x,y) scaled with scale (default=1) versus z into a TH3
342//
343void MPhotonEvent::Fill(TH3 &hist, Double_t z, Float_t scale) const
344{
345 MPhotonData *ph=NULL;
346
347 TIter Next(&fData);
348 while ((ph=(MPhotonData*)Next()))
349 ph->Fill(hist, z, scale);
350}
351
352void MPhotonEvent::DrawPixelContent(Int_t num) const
353{
354}
355
356#include "MHexagon.h"
357#include "MGeomCam.h"
358#include <TMarker.h>
359
360// ------------------------------------------------------------------------
361//
362// Fill a reflector event. Sums all pixels in each pixel as the
363// pixel contents.
364//
365// WARNING: Due to the estimation in DistanceToPrimitive and the
366// calculation in pixels instead of x, y this is only a
367// rough estimate.
368//
369Bool_t MPhotonEvent::GetPixelContent(Double_t &val, Int_t idx, const MGeomCam &cam, Int_t type) const
370{
371 //
372 // sum the photons content in each pixel
373 //
374 val = 0;
375
376 MHexagon hex(cam[idx]);
377
378 MPhotonData *ph=NULL;
379
380 TIter Next(&fData);
381
382 switch (type)
383 {
384
385 case 1: // time
386 while ((ph=(MPhotonData*)Next()))
387 if (hex.DistanceToPrimitive(ph->GetPosY(), ph->GetPosX())<=0)
388 val += ph->GetTime();
389 return val/fData.GetEntriesFast()>0;
390
391 default: // signal
392 while ((ph=(MPhotonData*)Next()))
393 if (hex.DistanceToPrimitive(ph->GetPosY()*10, ph->GetPosX()*10)<=0)
394 val += cam.GetPixRatio(idx);
395 return val>0;
396 }
397
398 return kFALSE;
399
400}
401*/
402
403// ------------------------------------------------------------------------
404//
405// You can call Draw() to add the photons to the current pad.
406// The photons are painted each tim ethe pad is updated.
407// Make sure that you use the right (world) coordinate system,
408// like created, eg. by the MHCamera histogram.
409//
410void MPhotonEvent::Paint(Option_t *)
411{
412 MPhotonData *ph=NULL;
413
414 TMarker m;
415 m.SetMarkerStyle(kFullDotMedium); // Gtypes.h
416
417 TIter Next(&fData);
418 while ((ph=(MPhotonData*)Next()))
419 {
420 m.SetX(ph->GetPosY()*10); // north
421 m.SetY(ph->GetPosX()*10); // east
422 m.Paint();
423 }
424}
Note: See TracBrowser for help on using the repository browser.