// ESAF : Euso Simulation and Analysis Framework
// this class is a container for input event
// it describes raw data both coming from ESAF Root file, ESAF Telemetry
// or Real EUSO Data
// $Id: RecoEvent.hh,v 1.22 2005/06/16 14:55:11 stutz Exp $
// Marco Pallavicini created Oct, 16 2003

#ifndef __RECOEVENT_HH_
#define __RECOEVENT_HH_

#include <vector>
#include <map>
#include "euso.hh"
#include <string>
#include "EsafMsgSource.hh"

class RecoCellInfo;
class RecoPixelData;
class RecoAnalogData;
class RecoPhotoElectronData;
class RecoPhotonOnPupilData;

#include "RecoEventHeader.hh"
#include "RecoModuleData.hh"

class RecoEvent:public EsafMsgSource {
public:
    
    // ctor
    RecoEvent();

    // dtor
    virtual ~RecoEvent();

    // get header: general infos about event
    inline const RecoEventHeader &GetHeader() const { return fHeader; }

    // get a specified module data
    const RecoModuleData *GetModuleData( const string& );

    // put a module data in the module data map
    void PutRecoModuleData( const string& name, const RecoModuleData* md );

    // number of macrocells with data
    inline Int_t GetNumActiveMacroCells() const { return fCellData.size(); }

    // number of triggering macrocells
    Int_t GetNumTriggeringMacroCells() const { return 0; }

    // return info object of a given macrocell id
    RecoCellInfo *GetRecoCellInfo( Int_t cell_id );

    // return data of a photoelectron
    RecoPhotoElectronData *GetRecoPhotoElectronData( Int_t ph_id );

    // return data of a front end chip pixel
    RecoPixelData *GetRecoPixelData( Int_t px_id );
    
    // return data of a front end chip pixels in a vector
    inline const vector<RecoPixelData*> &GetRecoPixels() {return fPixelData;}
    
    // insert an entry in photoelectron data
    inline void PutRecoPhotoElectronData( RecoPhotoElectronData *data) { fPhotoElectronData.push_back(data); }

    // insert an entry in macrocell data
    void PutRecoCellInfo( Int_t cell_id, RecoCellInfo *cell_info );

    // insert an entry in front end chip pixel data
    inline void PutRecoPixelData( RecoPixelData *data ) { fPixelData.push_back(data); }

    // insert an entry in analog data
    inline void PutRecoAnalogData( RecoAnalogData *data ) {fAnalogData.push_back(data); }

    // methods of sorting
    void SortPhGtu();
    
    // find the main macrocell by pixel data
    Int_t GetMainMacroCell(Int_t hits_minimum);

    // give the number of photoelectrons in macrocell cell_id
    Int_t GetNumPh( Int_t cell_id );  

    // give the number of active pixels in macrocell cell_id
    Int_t GetNumPx( Int_t cell_id, Int_t hits_miminum );
    
    // find min and max theta of pixel FOV in macrocell cell_id
    Float_t GetThetaMin( Int_t cell_id, Int_t hm );
    Float_t GetThetaMax( Int_t cell_id, Int_t hm );
    Float_t GetThetaRange( Int_t cell_id, Int_t hm );

    // find min and max Y pos of photoelectrons in macrocell cell_id
    Float_t GetPhiMin( Int_t cell_id, Int_t hm );
    Float_t GetPhiMax( Int_t cell_id, Int_t hm );
    Float_t GetPhiRange( Int_t cell_id, Int_t hm );

    // find first and last gtu of photoelectrons in macrocell cell_id
    Int_t GetFirstGtu( Int_t cell_id, Int_t hm );
    Int_t GetLastGtu( Int_t cell_id, Int_t hm );
    Int_t GetGtuRange( Int_t cell_id, Int_t hm );

    //find first and last gtu of entire event
    Int_t GetStartGtu();
    Int_t GetEndGtu();

    // insert an entry in photons on pupil data
    inline void PutRecoPhotonOnPupilData( RecoPhotonOnPupilData *data) { fPhotonOnPupilData.push_back(data); }

    // return data of a photoelectron
    RecoPhotonOnPupilData *GetRecoPhotonOnPupilData( Int_t ph_id );

private:
    RecoEventHeader fHeader;

    // map of reco module data
    map<string,const RecoModuleData*> fModuleData;

    // photons on pupil data
    vector<RecoPhotonOnPupilData*> fPhotonOnPupilData;

    // photoelectrons data
    vector<RecoPhotoElectronData*> fPhotoElectronData;

    // macrocell data; one RecoCellInfo object per MacroCell
    map<Int_t,RecoCellInfo*> fCellData;
    
    // front end chip pixel data (no ghosts, digital info DFEE )
    vector<RecoPixelData*> fPixelData;

    // analog data (AFEE)
    vector<RecoAnalogData*> fAnalogData;
    
    friend class RootInputModule;

    ClassDef(RecoEvent,0)
};

#endif  /* __RECOEVENT_HH_ */