#ifndef MARS_MPhotonEvent #define MARS_MPhotonEvent #ifndef MARS_MParContainer #include "MParContainer.h" #endif #ifndef ROOT_TClonesArray #include #endif #include class MPhotonData; class MCorsikaRunHeader; class MyClonesArray : public TClonesArray { public: TObject **FirstRef() { return fCont; } void FastRemove(Int_t idx1, Int_t idx2) { // Remove object at index idx. //if (!BoundsOk("RemoveAt", idx1)) return 0; //if (!BoundsOk("RemoveAt", idx2)) return 0; Long_t dtoronly = TObject::GetDtorOnly(); idx1 -= fLowerBound; idx2 -= fLowerBound; for (TObject **obj=fCont+idx1; obj<=fCont+idx2; obj++) { if (!*obj) continue; if ((*obj)->TestBit(kNotDeleted)) { // Tell custom operator delete() not to delete space when // object fCont[i] is deleted. Only destructors are called // for this object. TObject::SetDtorOnly(*obj); delete *obj; } *obj = 0; // recalculate array size } TObject::SetDtorOnly((void*)dtoronly); if (idx1<=fLast && fLast<=idx2) { do { fLast--; } while (fLast >= 0 && fCont[fLast] == 0); } Changed(); } void SetSorted() { fSorted = kTRUE; } }; class MPhotonEvent : public MParContainer { private: TClonesArray fData; public: MPhotonEvent(const char *name=NULL, const char *title=NULL); // TObjArray, FIXME: This could be improved if checking for IsSortable is omitted void Sort(Bool_t force=kFALSE) { if (force) fData.UnSort(); fData.Sort(); } Bool_t IsSorted() const { return fData.IsSorted(); } // Getter/Setter Int_t GetNumPhotons() const { return fData.GetEntriesFast(); } Int_t GetNumExternal() const; TClonesArray &GetArray() { return fData; } const TClonesArray &GetArray() const { return fData; } MPhotonData &Add(Int_t n); MPhotonData &Add(); MPhotonData *GetFirst() const; MPhotonData *GetLast() const; MPhotonData &operator[](UInt_t idx); const MPhotonData &operator[](UInt_t idx) const; Int_t Shrink(Int_t n) { // The number of object written by the streamer is defined by // GetEntriesFast(), i.e. this number must be shrinked to // the real array size. We use RemoveAt instead of ExpandCreate // because RemoveAt doesn't free memory. Thus in the next // iteration it can be reused and doesn't need to be reallocated. // Do not change this. It is optimized for execution speed // for (int i=fData.GetSize()-1; i>=n; i--) // fData.RemoveAt(i); const Bool_t sorted = fData.IsSorted(); MyClonesArray &loc = static_cast(fData); loc.FastRemove(n, fData.GetSize()-1); // If it was sorted before it is also sorted now. if (sorted) loc.SetSorted(); return fData.GetEntriesFast(); } // I/O Int_t ReadCorsikaEvt(istream &fin); Int_t ReadRflEvt(istream &fin); // TObject void Paint(Option_t *o=""); void Print(Option_t * = NULL) const; //void Clear(Option_t * = NULL); ClassDef(MPhotonEvent, 1) //Container to store the raw Event Data }; // FIXME: Should we merge this into MPhotonEvent? class MPhotonStatistics : public MParContainer { private: Float_t fTimeFirst; Float_t fTimeLast; // Float_t fOffset; // Float_t fWindow; Int_t fMaxIndex; public: MPhotonStatistics(const char *name=NULL, const char *title=NULL) : fMaxIndex(-1) { fName = name ? name : "MPhotonStatistics"; fTitle = title ? title : "Corsika Event Data Information"; } void SetTime(Float_t first, Float_t last) { fTimeFirst=first; fTimeLast=last; } void SetMaxIndex(UInt_t idx) { fMaxIndex=idx; } // Float_t GetRawTimeFirst() const { return fTimeFirst; } // Float_t GetRawTimeLast() const { return fTimeLast; } Float_t GetTimeFirst() const { return fTimeFirst; } Float_t GetTimeLast() const { return fTimeLast; } Int_t GetMaxIndex() const { return fMaxIndex; } // Bool_t IsValid() const { return fTimeLast>=fTimeFirst; } ClassDef(MPhotonStatistics, 1) }; #endif