source: trunk/Mars/msim/MPhotonEvent.cc@ 9943

Last change on this file since 9943 was 9942, checked in by tbretz, 15 years ago
Implemented reading of a single telescope from an eventio file.
File size: 24.2 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, 12/2000 <mailto:tbretz@astro.uni-wuerzburg.de>
19! Author(s): Qi Zhe, 06/2007 <mailto:qizhe@astro.uni-wuerzburg.de>
20!
21! Copyright: CheObs 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// ---------------------------------------------------------------------
60//
61// Int_t cnt = 0;
62//
63// const Int_t num = event->GetNumPhotons();
64// for (Int_t idx=0; idx<num; idx++)
65// {
66// if (idx%2==0)
67// continue;
68//
69// MPhotonData *dat = (*event)[idx];
70//
71// (*event)[cnt++] = *dat;
72// }
73//
74// event->Shrink(cnt);
75//
76// ---------------------------------- or -------------------------------
77//
78// TClonesArray &arr = MPhotonEvent->GetArray();
79//
80// Int_t cnt = 0;
81//
82// const Int_t num = arr.GetEntriesFast();
83// for (Int_t idx=0; idx<num; idx++)
84// {
85// if (idx%2==0)
86// continue;
87//
88// MPhotonData *dat = static_cast<MPhotonData*>(arr.UncheckedAt(idx));
89//
90// *static_cast<MPhotonData*>(arr.UncheckedAt(cnt++)) = *dat;
91// }
92//
93// MPhotonEvent->Shrink(cnt);
94//
95// ---------------------------------------------------------------------
96//
97// The flag for a sorted array is for speed reasons not in all conditions
98// maintained automatically. Especially Add() doesn't reset it.
99//
100// So be sure that if you want to sort your array it is really sorted.
101//
102//
103// Version 1:
104// ----------
105// - First implementation
106//
107/////////////////////////////////////////////////////////////////////////////
108#include "MPhotonEvent.h"
109
110#include <fstream>
111#include <iostream>
112
113#include <TMarker.h>
114
115#include <MMath.h>
116
117#include "MArrayF.h"
118
119#include "MLog.h"
120#include "MLogManip.h"
121
122#include "MPhotonData.h"
123#include "MCorsikaFormat.h"
124
125ClassImp(MPhotonEvent);
126
127using namespace std;
128
129// ==========================================================================
130
131class MyClonesArray : public TClonesArray
132{
133public:
134 TObject **FirstRef() { return fCont; }
135
136 // --------------------------------------------------------------------------
137 //
138 // This is an extremly optimized version of ExpandCreateFast. It only resets
139 // the marker for the last element (fLast) to n-1 and doen't change anything
140 // else. This implicitly assumes that the stored objects don't allocate
141 // memory. It does not necessarily mean that the slots after fLast
142 // are empty (set to 0). This is what is assumed in the TClonesArray.
143 // We also don't call Changed() because it would reset Sorted. If the
144 // array was sorted before it is also sorted now. You MUST make sure
145 // that you only set n in a range for which valid entries have been
146 // created before (e.g. by ExpandCreateFast).
147 //
148 void FastShrink(Int_t n)
149 {
150 fLast = n - 1;
151 }
152
153 // --------------------------------------------------------------------------
154 //
155 // This is a optimized (faster) version of Delete which deletes consequtive
156 // entries from index idx1 to idx2 (both included) and calls their
157 // destructor. Note that there is no range checking done!
158 //
159 void FastRemove(Int_t idx1, Int_t idx2)
160 {
161 // Remove object at index idx.
162
163 //if (!BoundsOk("RemoveAt", idx1)) return 0;
164 //if (!BoundsOk("RemoveAt", idx2)) return 0;
165
166 Long_t dtoronly = TObject::GetDtorOnly();
167
168 idx1 -= fLowerBound;
169 idx2 -= fLowerBound;
170
171 for (TObject **obj=fCont+idx1; obj<=fCont+idx2; obj++)
172 {
173 if (!*obj)
174 continue;
175
176 if ((*obj)->TestBit(kNotDeleted)) {
177 // Tell custom operator delete() not to delete space when
178 // object fCont[i] is deleted. Only destructors are called
179 // for this object.
180 TObject::SetDtorOnly(*obj);
181 delete *obj;
182 }
183
184 *obj = 0;
185 // recalculate array size
186 }
187 TObject::SetDtorOnly((void*)dtoronly);
188
189 if (idx1<=fLast && fLast<=idx2)
190 {
191 do {
192 fLast--;
193 } while (fLast >= 0 && fCont[fLast] == 0);
194 }
195
196 Changed();
197 }
198
199
200 //void SetSorted() { fSorted = kTRUE; }
201
202 // --------------------------------------------------------------------------
203 //
204 // This is an optimized version of Sort which doesn't check the
205 // IsSortable flag before. It only sorts the entries from 0
206 // to GetEntriesFast().
207 //
208 void UncheckedSort()
209 {
210 if (fSorted)
211 return;
212
213 const Int_t nentries = GetEntriesFast();
214 if (nentries <= 0)
215 return;
216
217 QSort(GetObjectRef(First()), fKeep->GetObjectRef(fKeep->First()),
218 0, TMath::Min(nentries, kMaxInt-fLowerBound));
219
220 fSorted = kTRUE;
221 }
222};
223
224// ==========================================================================
225
226// --------------------------------------------------------------------------
227//
228// Default constructor. It initializes all arrays with zero size.
229//
230MPhotonEvent::MPhotonEvent(const char *name, const char *title)
231 : fData("MPhotonData", 1)
232{
233 fName = name ? name : "MPhotonEvent";
234 fTitle = title ? title : "Corsika Event Data Information";
235
236 fData.SetBit(TClonesArray::kForgetBits);
237 fData.BypassStreamer(kFALSE);
238}
239
240// --------------------------------------------------------------------------
241//
242// This is an extremly optimized version of ExpandCreateFast. It only resets
243// the marker for the last element (fLast) to n-1 and doen't change anything
244// else. This has the advantage that the allocated memory is kept but only
245// valid entries are written to a file.
246//
247// If the array was sorted before it is also sorted now. You MUST make sure
248// that you only set n in a range for which valid entries have been
249// created before (e.g. by ExpandCreateFast).
250//
251Int_t MPhotonEvent::Shrink(Int_t n)
252{
253 /*
254 // The number of object written by the streamer is defined by
255 // GetEntriesFast(), i.e. this number must be shrinked to
256 // the real array size. We use RemoveAt instead of ExpandCreate
257 // because RemoveAt doesn't free memory. Thus in the next
258 // iteration it can be reused and doesn't need to be reallocated.
259 // Do not change this. It is optimized for execution speed
260 // for (int i=fData.GetSize()-1; i>=n; i--)
261 // fData.RemoveAt(i);
262 const Bool_t sorted = fData.IsSorted();
263
264 MyClonesArray &loc = static_cast<MyClonesArray&>(fData);
265
266 loc.FastRemove(n, fData.GetSize()-1);
267
268 // If it was sorted before it is also sorted now.
269 if (sorted)
270 loc.SetSorted();
271 */
272
273 // fData.ExpandCreateFast(n); // Just set fLast = n -1
274
275 // Just set fLast = n -1
276 static_cast<MyClonesArray&>(fData).FastShrink(n);
277 return fData.GetEntriesFast();
278}
279
280// --------------------------------------------------------------------------
281//
282// The resized the array. If it has to be increased in size it is done
283// with ExpandCreateFast. If it should be shrinked it is done with
284// ExpandCreateFast if n>fData.GetSize()/100 or n==0. This keeps the allocated
285// memory and just sets the marker for the last element in the array (fLast).
286//
287// If the allocated memory grew to huge we reset the allocated memory
288// by calling ExpandCreate(n) (frees the allocated storage for the
289// objects) and Expand(n) (frees the allocated memory for the list
290// of pointers to the objects)
291//
292// 100 hundred is an arbitrary number taking into account that todays
293// computers have a lot of memory and we don't want to free and allocate
294// new memory too often.
295//
296// In priciple there might be more clever methods to handle the memory.
297//
298void MPhotonEvent::Resize(Int_t n)
299{
300 if (n==0 || n*100>fData.GetSize())
301 fData.ExpandCreateFast(n); // Just set fLast = n -1
302 else
303 {
304 fData.ExpandCreate(n); // Free memory of allocated MPhotonData
305 fData.Expand(n); // Free memory of allocated pointers
306 }
307}
308
309// --------------------------------------------------------------------------
310//
311// If n is smaller than the current allocated array size a reference to
312// the n-th entry is returned, otherwise an entry at n is created
313// calling the default constructor. Note, that there is no range check
314// but it is not recommended to call this function with
315// n>fData.GetSize()
316//
317MPhotonData &MPhotonEvent::Add(Int_t n)
318{
319 // Do not modify this. It is optimized for execution
320 // speed and flexibility!
321 TObject *o = 0;
322 if (n<fData.GetSize() && fData.UncheckedAt(n))
323 {
324 o=fData.UncheckedAt(n);
325 static_cast<MyClonesArray&>(fData).FastShrink(n+1);
326 }
327 else
328 {
329 o=fData.New(n);
330 }
331 return static_cast<MPhotonData&>(*o);
332}
333
334// --------------------------------------------------------------------------
335//
336// Add a new photon (MPhtonData) at the end of the array.
337// In this case the default constructor of MPhotonData is called.
338//
339// A reference to the new object is returned.
340//
341MPhotonData &MPhotonEvent::Add()
342{
343 return Add(GetNumPhotons());
344}
345
346void MPhotonEvent::Sort(Bool_t force)
347{
348 if (force)
349 fData.UnSort();
350
351 static_cast<MyClonesArray&>(fData).UncheckedSort(); /*Sort(GetEntriesFast())*/
352}
353
354// --------------------------------------------------------------------------
355//
356// Get the i-th photon from the array. Not, for speed reasons there is no
357// range check so you are responsible that you do not excess the number
358// of photons (GetNumPhotons)
359//
360MPhotonData &MPhotonEvent::operator[](UInt_t idx)
361{
362 return *static_cast<MPhotonData*>(fData.UncheckedAt(idx));
363}
364
365// --------------------------------------------------------------------------
366//
367// Get the i-th photon from the array. Not, for speed reasons there is no
368// range check so you are responsible that you do not excess the number
369// of photons (GetNumPhotons)
370//
371const MPhotonData &MPhotonEvent::operator[](UInt_t idx) const
372{
373 return *static_cast<MPhotonData*>(fData.UncheckedAt(idx));
374}
375
376// --------------------------------------------------------------------------
377//
378// Return a pointer to the first photon if available.
379//
380MPhotonData *MPhotonEvent::GetFirst() const
381{
382 return fData.GetEntriesFast()==0 ? 0 : static_cast<MPhotonData*>(fData.First());
383}
384
385// --------------------------------------------------------------------------
386//
387// Return a pointer to the last photon if available.
388//
389MPhotonData *MPhotonEvent::GetLast() const
390{
391 return fData.GetEntriesFast()==0 ? 0 : static_cast<MPhotonData*>(fData.Last());
392}
393
394// --------------------------------------------------------------------------
395//
396// Return the number of "external" photons, i.e. which are not NightSky
397//
398Int_t MPhotonEvent::GetNumExternal() const
399{
400 Int_t n=0;
401
402 for (int i=0; i<GetNumPhotons(); i++)
403 if ((*this)[i].GetPrimary()!=MMcEvtBasic::kNightSky)
404 n++;
405
406 return n;
407}
408
409// --------------------------------------------------------------------------
410//
411// Return time of first photon, 0 if none in array.
412// Note: If you want this to be the earliest make sure that the array
413// is properly sorted.
414//
415Float_t MPhotonEvent::GetTimeFirst() const
416{
417 const MPhotonData *dat=GetFirst();
418 return dat ? dat->GetTime() : 0;
419}
420
421// --------------------------------------------------------------------------
422//
423// Return time of first photon, 0 if none in array.
424// Note: If you want this to be the latest make sure that the array
425// is properly sorted.
426//
427Float_t MPhotonEvent::GetTimeLast() const
428{
429 const MPhotonData *dat=GetLast();
430 return dat ? dat->GetTime() : 0;
431}
432
433// --------------------------------------------------------------------------
434//
435// Return the median devian from the median of all arrival times.
436// The median deviation is calculated using MMath::MedianDev.
437// It is the half width in which one sigma (~68%) of all times are
438// contained around the median.
439//
440Double_t MPhotonEvent::GetTimeMedianDev() const
441{
442 const UInt_t n = GetNumPhotons();
443
444 MArrayF arr(n);
445 for (UInt_t i=0; i<n; i++)
446 arr[i] = operator[](i).GetTime();
447
448 return MMath::MedianDev(n, arr.GetArray()/*, Double_t &med*/);
449}
450
451Double_t MPhotonEvent::GetMeanX() const
452{
453 const UInt_t n = GetNumPhotons();
454 if (n==0)
455 return 0;
456
457 Double_t mean = 0;
458 for (UInt_t i=0; i<n; i++)
459 mean += operator[](i).GetPosX();
460
461 return mean / n;
462}
463
464Double_t MPhotonEvent::GetMeanY() const
465{
466 const UInt_t n = GetNumPhotons();
467 if (n==0)
468 return 0;
469
470 Double_t mean = 0;
471 for (UInt_t i=0; i<n; i++)
472 mean += operator[](i).GetPosY();
473
474 return mean / n;
475}
476
477Double_t MPhotonEvent::GetMeanT() const
478{
479 const UInt_t n = GetNumPhotons();
480 if (n==0)
481 return 0;
482
483 Double_t mean = 0;
484 for (UInt_t i=0; i<n; i++)
485 mean += operator[](i).GetTime();
486
487 return mean / n;
488}
489
490void MPhotonEvent::AddXY(Double_t x, Double_t y)
491{
492 const UInt_t n = GetNumPhotons();
493
494 for (UInt_t i=0; i<n; i++)
495 {
496 MPhotonData &p = operator[](i);
497 p.SetPosition(p.GetPosX()+x, p.GetPosY()+y);
498 }
499}
500
501void MPhotonEvent::SimWavelength(Float_t wmin, Float_t wmax)
502{
503 const UInt_t n = GetNumPhotons();
504
505 for (UInt_t i=0; i<n; i++)
506 operator[](i).SimWavelength(wmin, wmax);
507}
508
509// --------------------------------------------------------------------------
510//
511// Read the Event section from the file
512//
513Int_t MPhotonEvent::ReadCorsikaEvt(MCorsikaFormat *fInFormat, Int_t id)
514{
515 Int_t n = 0;
516
517 // --- old I/O ---
518 // Read only + Reflector (no absorption)
519 // Muons: 1.06GB/115s = 9.2MB/s (100kEvs)
520 // Gammas: 1.57GB/275s = 5.7MB/s ( 1kEvs)
521
522 // Read only:
523 // Gammas: 1.57GB/158s = 9.9MB/s ( 1kEvs)
524 // Muons: 1.06GB/ 77s = 13.8MB/s (100kEvs)
525
526 // --- new I/O ---
527 // Read only (don't allocate storage space):
528 // Gammas: 1.57GB/143s = 11.0MB/s ( 1kEvs)
529 // Muons: 1.06GB/ 77s = 13.8MB/s (100kEvs)
530
531 // Read only in blocks (with storage allocation):
532 // Gammas: 1.57GB/28s = 56MB/s ( 1kEvs)
533 // Muons: 1.06GB/5.2s = 204MB/s (100kEvs)
534
535 // Read only in blocks (without storage allocation):
536 // similar to just copy
537
538 // Copy with cp
539 // 1.57GB/ 5s CPU
540 // 1.57GB/28s REAL
541 // 1.06GB/ 3s CPU
542 // 1.06GB/22s REAL
543 Float_t *buffer = 0;
544
545 if (fInFormat->IsEventioFormat())
546 {
547 while (1)
548 {
549 const Int_t rc = fInFormat->GetNextEvent(&buffer, id);
550 if (rc==kERROR)
551 return kERROR;
552 if (rc==kFALSE)
553 break;
554
555 // Loop over number of photons in bunch
556 while (Add(n).FillEventIO(buffer))
557 n++;
558 }
559 }
560 else
561 {
562 while (1)
563 {
564 const Int_t rc1 = fInFormat->GetNextEvent(&buffer);
565 if (rc1==kERROR)
566 return kERROR;
567 if (rc1==kFALSE)
568 break;
569
570 const Int_t rc2 = Add(n).FillCorsika(buffer, id);
571 switch (rc2)
572 {
573 case kCONTINUE: continue; // No data in this bunch... skip it.
574 case kERROR: return kERROR; // Error occured
575 //case kFALSE: return kFALSE; // End of stream
576 }
577
578 // This is a photon we would like to keep later.
579 // Increase the counter by one
580 n++;
581 }
582 }
583
584/*
585
586 while (1)
587 {
588 Float_t buffer[273];
589 Float_t * ptr = buffer;
590
591
592 if (!fInFormat->ReadData(273, buffer))
593 return kFALSE;
594
595 if (!memcmp(ptr, "EVTE", 4))
596 {
597
598 fInFormat->UnreadLastData();
599 break;
600 }
601
602 Float_t *end = ptr + 273;
603
604 // Loop over all sub-blocks (photons) in the block and if
605 // they contain valid data add them to the array
606 while (ptr<end)
607 {
608 // Get/Add the n-th entry from the array and
609 // fill it with the current 7 floats
610 const Int_t rc = Add(n).FillCorsika(ptr);
611 ptr += 7;
612
613 switch (rc)
614 {
615 case kCONTINUE: continue; // No data in this bunch... skip it.
616 case kERROR: return kERROR; // Error occured
617 //case kFALSE: return kFALSE; // End of stream
618 }
619
620 // This is a photon we would like to keep later.
621 // Increase the counter by one
622 n++;
623 }
624 }
625
626*/
627 Resize(n);
628 fData.UnSort();
629
630 SetReadyToSave();
631
632 //*fLog << all << "Number of photon bunches: " << fData.GetEntriesFast() << endl;
633 return kTRUE;
634
635}
636
637Int_t MPhotonEvent::ReadCorsikaEvt(istream &fin, Int_t i)
638{
639 Int_t n = 0;
640
641 // --- old I/O ---
642 // Read only + Reflector (no absorption)
643 // Muons: 1.06GB/115s = 9.2MB/s (100kEvs)
644 // Gammas: 1.57GB/275s = 5.7MB/s ( 1kEvs)
645
646 // Read only:
647 // Gammas: 1.57GB/158s = 9.9MB/s ( 1kEvs)
648 // Muons: 1.06GB/ 77s = 13.8MB/s (100kEvs)
649
650 // --- new I/O ---
651 // Read only (don't allocate storage space):
652 // Gammas: 1.57GB/143s = 11.0MB/s ( 1kEvs)
653 // Muons: 1.06GB/ 77s = 13.8MB/s (100kEvs)
654
655 // Read only in blocks (with storage allocation):
656 // Gammas: 1.57GB/28s = 56MB/s ( 1kEvs)
657 // Muons: 1.06GB/5.2s = 204MB/s (100kEvs)
658
659 // Read only in blocks (without storage allocation):
660 // similar to just copy
661
662 // Copy with cp
663 // 1.57GB/ 5s CPU
664 // 1.57GB/28s REAL
665 // 1.06GB/ 3s CPU
666 // 1.06GB/22s REAL
667
668 while (1)
669 {
670 // Stprage for one block
671 char c[273*4];
672
673 // Read the first four byte to check whether the next block
674 // doen't belong to the event anymore
675 fin.read(c, 4);
676 if (!fin)
677 return kFALSE;
678
679 // Check if the event is finished
680 if (!memcmp(c, "EVTE", 4))
681 break;
682
683 // Now read the rest of the data
684 fin.read(c+4, 272*4);
685
686 Float_t *ptr = reinterpret_cast<Float_t*>(c);
687 Float_t *end = ptr + 273;
688
689 // Loop over all sub-blocks (photons) in the block and if
690 // they contain valid data add them to the array
691 while (ptr<end)
692 {
693 // Get/Add the n-th entry from the array and
694 // fill it with the current 7 floats
695 const Int_t rc = Add(n).FillCorsika(ptr, i);
696 ptr += 7;
697
698 switch (rc)
699 {
700 case kCONTINUE: continue; // No data in this bunch... skip it.
701 case kERROR: return kERROR; // Error occured
702 //case kFALSE: return kFALSE; // End of stream
703 }
704
705 // This is a photon we would like to keep later.
706 // Increase the counter by one
707 n++;
708 }
709 }
710/*
711 while (1)
712 {
713 // Check the first four bytes
714 char c[4];
715 fin.read(c, 4);
716
717 // End of stream
718 if (!fin)
719 return kFALSE;
720
721 // Check if we found the end of the event
722 if (!memcmp(c, "EVTE", 4))
723 break;
724
725 // The first for byte contained data already --> go back
726 fin.seekg(-4, ios::cur);
727
728 // Do not modify this. It is optimized for execution
729 // speed and flexibility!
730 MPhotonData &ph = Add(n);
731 // It checks how many entries the lookup table has. If it has enough
732 // entries and the entry was already allocated, we can re-use it,
733 // otherwise we have to allocate it.
734
735 // Now we read a single cherenkov bunch. Note that for speed reason we have not
736 // called the constructor if the event was already constructed (virtual table
737 // set), consequently we must make sure that ReadCorsikaEvent does reset
738 // all data mebers no matter whether they are read or not.
739 const Int_t rc = ph.ReadCorsikaEvt(fin);
740
741 // Evaluate result from reading event
742 switch (rc)
743 {
744 case kCONTINUE: continue; // No data in this bunch... skip it.
745 case kFALSE: return kFALSE; // End of stream
746 case kERROR: return kERROR; // Error occured
747 }
748
749 // FIXME: If fNumPhotons!=1 add the photon more than once
750
751 // Now increase the number of entries which are kept,
752 // i.e. keep this photon(s)
753 n++;
754 }
755 */
756
757 Resize(n);
758 fData.UnSort();
759
760 SetReadyToSave();
761
762 //*fLog << all << "Number of photon bunches: " << fData.GetEntriesFast() << endl;
763 return kTRUE;
764}
765
766// --------------------------------------------------------------------------
767/*
768Int_t MPhotonEvent::ReadRflEvt(std::istream &fin, Int_t i)
769{
770 Int_t n = 0;
771
772 while (1)
773 {
774 // Check the first four bytes
775 char c[13];
776 fin.read(c, 13);
777
778 // End of stream
779 if (!fin)
780 return kFALSE;
781
782 // Check if we found the end of the event
783 if (!memcmp(c, "\nEND---EVENT\n", 13))
784 break;
785
786 // The first for byte contained data already --> go back
787 fin.seekg(-13, ios::cur);
788
789 // Do not modify this. It is optimized for execution
790 // speed and flexibility!
791 //TObject *o = n<fData.GetSize() && fData.UncheckedAt(n) ? fData.UncheckedAt(n) : fData.New(n);
792
793 // Now we read a single cherenkov bunch
794 //const Int_t rc = static_cast<MPhotonData*>(o)->ReadRflEvt(fin);
795 const Int_t rc = Add(n).ReadRflEvt(fin, i);
796
797 // Evaluate result from reading event
798 switch (rc)
799 {
800 case kCONTINUE: continue; // No data in this bunch... skip it.
801 case kFALSE: return kFALSE; // End of stream
802 case kERROR: return kERROR; // Error occured
803 }
804
805 // Now increase the number of entries which are kept,
806 // i.e. keep this photon(s)
807 n++;
808 }
809
810 Shrink(n);
811
812 SetReadyToSave();
813
814 // *fLog << all << "Number of photon bunches: " << fData.GetEntriesFast() << endl;
815 return kTRUE;
816}
817*/
818// --------------------------------------------------------------------------
819//
820// Print the array
821//
822void MPhotonEvent::Print(Option_t *) const
823{
824 fData.Print();
825}
826
827// ------------------------------------------------------------------------
828//
829// You can call Draw() to add the photons to the current pad.
830// The photons are painted each tim ethe pad is updated.
831// Make sure that you use the right (world) coordinate system,
832// like created, eg. by the MHCamera histogram.
833//
834void MPhotonEvent::Paint(Option_t *)
835{
836 MPhotonData *ph=NULL;
837
838 TMarker m;
839 m.SetMarkerStyle(kFullDotMedium); // Gtypes.h
840
841 TIter Next(&fData);
842 while ((ph=(MPhotonData*)Next()))
843 {
844 m.SetX(ph->GetPosY()*10); // north
845 m.SetY(ph->GetPosX()*10); // east
846 m.Paint();
847 }
848}
Note: See TracBrowser for help on using the repository browser.