#ifndef HMDCSELFTRACKING_H
#define HMDCSELFTRACKING_H
#include "hreconstructor.h"
class TDirectory;
class TFile;
class HCategory;
class HIterator;
class HEventHeader;
class TH1F;
class TH1D;
class TH2S;
class TH3F;
class TProfile;
#define HMDCSELFTRACKING_CUTBRIDGE_NUMBER 20
#define HMDCSELFTRACKING_STARTSTRIP_NUMBER 9
class HMdcSelfTracking : public HReconstructor {
public:
protected:
  
  
  
  
  
  
     enum selftrackingCut  {
	                    NO_CUT = 0,
			    TOF_BIT_CUT = 1,
			    START_CUT = 2,
			    TIME1_CUT = 3,
			    TIME2_CUT = 4,
			    TIME_ABOVE_THRESHOLD_CUT = 5,
			    MISC_6  =  6,
			    MISC_7  =  7,
			    MISC_8  =  8,
			    MISC_9  =  9,
			    MISC_10 = 10,
			    MISC_11 = 11,
			    MISC_12 = 12,
			    MISC_13 = 13,
			    MISC_14 = 14,
			    MISC_15 = 15,
			    MISC_16 = 16,
			    MISC_17 = 17,
			    MISC_18 = 18,
			    MISC_19 = 19,
			    MISC_20 = 20};
  
  enum flags  {NEIGHBOURS                 = 0,
               LEFT_CELL_HIT              = 1,
               RIGHT_CELL_HIT             = 2,
               ANALYSISLAYER2_HITS        = 1,
               ANALYSISLAYER2_DOUBLE_HITS = 2,
               RESIDUAL_CUT               = 3 };
  enum selftrackingStartStrip  {START_STRIP_1 = 1,
				START_STRIP_2 = 2,
				START_STRIP_3 = 3,
				START_STRIP_4 = 4,
				START_STRIP_5 = 5,
				START_STRIP_6 = 6,
				START_STRIP_7 = 7,
				START_STRIP_8 = 8 };
  enum rightleft {LEFT  = 1,
                  RIGHT = 2};
  Int_t setLeft[4];  
  Int_t setRight[4]; 
  
  Float_t A[4],B[4],C[4]; 
  Float_t CorrWindow[4][3]; 
  Float_t tdifmin[5]; 
  Float_t tdifmax[5]; 
  Float_t tdifcut; 
  Float_t tmin; 
  Float_t tmax; 
  Int_t cellmin; 
  Int_t cellmax; 
  Float_t startmin[HMDCSELFTRACKING_STARTSTRIP_NUMBER]; 
  Float_t startmax[HMDCSELFTRACKING_STARTSTRIP_NUMBER]; 
  Bool_t cutbridge[HMDCSELFTRACKING_CUTBRIDGE_NUMBER]; 
  Bool_t cut[20]; 
  Int_t monitorCell;  
  Int_t monitorLayer; 
  
  
  Float_t hitTime1[7][200]; 
  Float_t hitTime2[7][200]; 
  Float_t time1;
  Float_t time2;
  Float_t timesum;
  Float_t timediff;
  Float_t timeDiffMax;
  Int_t  setmodule, setsector;   
  
  Bool_t noStart;                        
  
  Bool_t noCorrSector;   
  Bool_t noCheckCorrSector;   
  Int_t module, sector, cell, layer;
  Int_t hitCells[7][200];              
  Int_t nhit[7];                
  Int_t cell0[5][200]; 
  Int_t ncell0[5];
  
  Bool_t relevant_data; 
  Bool_t flag[4];  
  Int_t alreadyUsedCellFlag_AnalysisLayer1[200];
  Int_t alreadyUsedCellFlag_AnalysisLayer2[200];
 
  Int_t lhit[3];
  
  Int_t analysisLayer1;
  Int_t analysisLayer2;
  Int_t cntHitslayer1;
  Int_t cntHitslayer2;
  Int_t cntHitsWithoutNeighbours;
  Int_t cntHitsAnalysislayer2;
  Int_t cntDoubleHitsAnalysislayer2;
  Int_t eventCounter;
  
  Float_t counter[3][160];
  Double_t ctrl[11];
  
  Int_t start_strip, nstartstrip;
  Float_t start_time;
  
  HCategory     *calCatMdc;           
  HCategory     *calCatStart;         
  HIterator     *iterMdc;             
  HIterator     *iterStart;           
  
  HEventHeader  *evheader;            
  
  Char_t *fNameRoot;                  
  
  
  
  TH1F *pinfo; 
  TH1D *player[7]; 
  TH1D *pNhitlayer[7]; 
  TH1D *player0[3]; 
  TH1F *peff; 
  
  TH1D *pTime_cut[7]; 
  TH2S *pTime0_cell[7]; 
  TH2S *pTime0_diff; 
  TH2S *pTime_cell[7];  
  TH1D *pTime_diff[2]; 
  TH2S *pTime0diff_cell[3]; 
  TH2S *pTimesum_adj_cell3; 
  TH2S *pTimesum_adj_cell4; 
  TH2S *pTimesum_cell[3]; 
  TH2S *pFish[3][120];    
  TH2S *pTsum_ev[3][120]; 
  TProfile *pTsum_ev_prof[3][120]; 
  
  TH2S *pStart_time_strip; 
  TH1F *pStart_time[9]; 
  TH1F *pStart_mult; 
  
  TH3F *pCorrSector; 
  TH1F *pCorrDiff[2][4]; 
  
  TFile *fout; 
  
 public:
  HMdcSelfTracking();
  HMdcSelfTracking(const Text_t* name,const Text_t* title);
  ~HMdcSelfTracking();
  Bool_t init(void);
  Bool_t finalize(void);
  Int_t execute();
  
  void setOutputRoot (const Char_t*);
  void setActiveModule (Int_t sec,Int_t mod){setsector=sec;setmodule=mod;} 
  void setNoStart() {noStart=kTRUE;}
  void setNoCorrSector() {noCorrSector=kTRUE;}
  void setNoCheckCorrSector() {noCheckCorrSector=kTRUE;}
  
  Bool_t setCutbridge(UInt_t, Bool_t);
  Bool_t getCutbridge(UInt_t index);
  void clearCutbridges(void){for (Int_t i=0; i < HMDCSELFTRACKING_CUTBRIDGE_NUMBER; i++) setCutbridge(i,kFALSE);}
  void printCutbridge(void);
  
  Bool_t setStartTimeCutWindow(UInt_t, Float_t, Float_t);
  Bool_t setStartTimeCutMax(UInt_t, Float_t);
  Bool_t setStartTimeCutMin(UInt_t, Float_t);
  Float_t getStartTimeCutMax(UInt_t);
  Float_t getStartTimeCutMin(UInt_t);
  void printStartTimeCutWindow(void);
  
  void setTimeCutWindow(Float_t min, Float_t max){setTimeCutMin(min);setTimeCutMax(max);return;} 
  void setTimeCutMax(Float_t f){tmax = f; return;} 
  void setTimeCutMin(Float_t f){tmin = f; return;} 
  Float_t getTimeCutMax(){return tmax;} 
  Float_t getTimeCutMin(){return tmin;} 
  void printTimeCutWindow(void);
  
  void setTimeAboveThresholdCutWindow(Int_t i, Float_t a, Float_t b){setTimeAboveThresholdCutMin(i,a);setTimeAboveThresholdCutMax(i,b);return;} 
  void setTimeAboveThresholdCutMax(Int_t i, Float_t f){tdifmax[i] = f; return;} 
  void setTimeAboveThresholdCutMin(Int_t i, Float_t f){tdifmin[i] = f; return;} 
  Float_t getTimeAboveThresholdCutMax(Int_t i){return tdifmax[i];} 
  Float_t getTimeAboveThresholdCutMin(Int_t i){return tdifmin[i];} 
  void printTimeAboveThresholdCutWindow(void);
  void setCorrelationFct(Int_t i, Float_t a, Float_t b, Float_t c){setCorrelationFctA(i,a);setCorrelationFctB(i,b);setCorrelationFctC(i,c);return;}
  void setCorrelationFctA(Int_t i, Float_t f){A[i] = f; return;} 
  void setCorrelationFctB(Int_t i, Float_t f){B[i] = f; return;} 
  void setCorrelationFctC(Int_t i, Float_t f){C[i] = f; return;} 
  Float_t getCorrelationFctA(Int_t i){return A[i];} 
  Float_t getCorrelationFctB(Int_t i){return B[i];} 
  Float_t getCorrelationFctC(Int_t i){return C[i];} 
  void printCorrelationFct(void);
  void setCorrelationWindow(Int_t i, Float_t a, Float_t b){setCorrelationWmin(i,a);setCorrelationWmax(i,b);return;}
  void setCorrelationWmin(Int_t i, Float_t f){CorrWindow[i][1] = f; return;} 
  void setCorrelationWmax(Int_t i, Float_t f){CorrWindow[i][2] = f; return;} 
  Float_t getCorrelationWmin(Int_t i){return CorrWindow[i][1];} 
  Float_t getCorrelationWmax(Int_t i){return CorrWindow[i][2];} 
  void printCorrelationWindow(void);
 
  void setAnalysisCellCutWindow(UInt_t a, UInt_t b){setAnalysisCellCutMin(a);setAnalysisCellCutMax(b);return;}
  void setAnalysisCellCutMax(UInt_t f){cellmax = f; return;}
  void setAnalysisCellCutMin(UInt_t f){cellmin = f; return;}
  UInt_t getAnalysisCellCutMax(){return cellmax;}
  UInt_t getAnalysisCellCutMin(){return cellmin;}
  void printAnalysisCellCutWindow(void);
  
  void setTimeDiffL3L4Cut(Float_t f){tdifcut = f; return;} 
  Float_t getTimeDiffL3L4Cut(){return tdifcut;} 
  void printTimeDiffL3L4Cut();
  void  setMonitor(UInt_t layer, UInt_t cellNumber){setMonitorCell(cellNumber);setMonitorLayer(layer);return;}
  void  setMonitorCell(UInt_t cell){monitorCell=(Int_t)cell;return;}
  Int_t getMonitorCell(){return monitorCell;}
  void  setMonitorLayer(UInt_t layer){monitorLayer=(Int_t)layer;return;}
  Int_t getMonitorLayer(){return monitorLayer;}
  void setTimeDiffMax(Float_t time){timeDiffMax = time;return;}
  Float_t getTimeDiffMax(){return timeDiffMax;}
protected:
  void createHist();
  void resetCounters();
  void fillControlHists();
  void fillHist  ();
  void fillAnalysisHists(Int_t);
  void checkAdjacentCellAnalysisLayer1(Int_t, Int_t);
  void checkAdjacentCellAnalysisLayer2(Int_t, Int_t);
  void findCorrelatedHits(Int_t);
  void checkCorrSector(Int_t, Int_t);
  void writeHist ();
  void setDefault ();
  void executeStart();
  void executeMdc();
  void executeCorrSector();
  void executeEventHeaderCheck();
  void executeReset();
  
 public: 
  ClassDef(HMdcSelfTracking, 0)  
    };
    
#endif