/**
 * \file TrkStruct.h
 * \author Elena Vannuccini
 * \date
 */
#ifndef trkstruct_h
#define trkstruct_h

#define NPLANE 6
#define NVIEW 12
#define NVK 24
#define NLADDER 3

#define NCLMAX_VIEW 200         //max n.clusters per view
#define NCLSTR 20               //max n.strip per cluster
#define NCLMAX (NCLMAX_VIEW*12) //max n.clusters total
#define NCLBUFF (NCLMAX*NCLSTR)

#define NDBLT_MAX_NT 1000   // 0.2*ndblt_max 
#define NTRPT_MAX_NT 10000   // 0.2*ntrpt_max
#define NCLOYZ_MAX 200 
#define NCLOXZ_MAX 200    

#define NTRKMAX 10
#define NSINGMAX NCLMAX //100

#define NANGMAX 21
#define NETAVALMAX 500


#include <CalibTrk1Event.h>
#include <CalibTrk2Event.h>
using namespace pamela;
//#include <TrkCalib.h>

#include <TString.h>
#include <TFile.h>
#include <TTree.h>


#include <fstream>
#include <iostream>
/**
 * \brief Struct to pass calibration parameters to F77 routines
 */
struct cTrkCalib {

    float pedestal[128][24][12];
    float pedestal_t[128][24][12];
    float sigma[128][24][12];
    float sigma_t[128][24][12];
    int bad[128][24][12];

/*     void FillACalibFrom(TFile* , Int_t , Int_t ); */
/*     void FillFCalibFrom(TFile* , Int_t , Int_t ); */
/*     void FillTCalibFrom(TFile* , Int_t , Int_t ); */
/*     void FillTCalibFrom(TString); */

};
// ==================================================================
/**
 * \brief Struct to pass tracker LEVEL0 data to F77 routines
 */
struct cTrkLevel0 {
    int DAQmode[12];
    int DSPnumber[12];
    int DATAlength[12];
    int eventn[12];
    int nclust[12];
    int cutc[12];
    int cutcl[12];
    int addrcluster[3][12];
    int signcluster[3][12];
    int fc[12];
    int compressiontime[12];
    int fl5[12]; 
    int fl4[12];
    int fl3[12];
    int fl2[12];
    int fl1[12];
    int fl6[12];
    int checksum[12];
    int TOTDATAlength;
    int datatracker[49152];
    int pnum[12];    
    int cmdnum[12];
    int bid[12];
    int alarm[12];
    int aswr[12]; 
    int good0;
    int crc[12]; 
};
// ==================================================================
/**
 * \brief Struct to pass tracker LEVEL1 data to F77 routines
 */
struct cTrkLevel1 {
//    int good1;
    int good[12];
    int nclstr1;
    int view[NCLMAX];
    int ladder[NCLMAX];
    int maxs[NCLMAX];
    int mult[NCLMAX];
    float dedx[NCLMAX];
    int indstart[NCLMAX];
    int indmax[NCLMAX];
    int totCLlength;
    float clsignal[NCLBUFF];
    float clsigma[NCLBUFF];
    int cladc[NCLBUFF];
    int clbad[NCLBUFF];
    float cnev[24][12];
    int cnnev[24][12];
    float cnrmsev[24][12];
    int fshower[12];
    int whichtrack[NCLMAX];

};
// ==================================================================
/**
 * \brief Struct to pass tracker LEVEL2 data to F77 routines
 */
struct cTrkLevel2 {
//    int good2;
//    int crc[12];
    int good[12];
    int vkflag[24][12];
//  ----------------------------
    int nclsx;
    int planex[NSINGMAX];
    float xs[NSINGMAX][2];
    float signlxs[NSINGMAX];
    int clsx[NSINGMAX];
//  ----------------------------
    int nclsy;
    int planey[NSINGMAX];
    float ys[NSINGMAX][2];
    float signlys[NSINGMAX];
    int clsy[NSINGMAX];
//  ----------------------------
    int ntrk;
    int image[NTRKMAX];
    float xm_nt[NTRKMAX][6];
    float ym_nt[NTRKMAX][6];
    float zm_nt[NTRKMAX][6];
    float resx_nt[NTRKMAX][6];
    float resy_nt[NTRKMAX][6];
    float tailx[NTRKMAX][6];
    float taily[NTRKMAX][6];
    float al_nt[NTRKMAX][5];
    float coval[NTRKMAX][5][5];
    float chi2_nt[NTRKMAX];
    int nstep_nt[NTRKMAX];
    int xgood_nt[NTRKMAX][6];
    int ygood_nt[NTRKMAX][6];
    int ls[NTRKMAX][6];
    int xbad[NTRKMAX][6];
    int ybad[NTRKMAX][6];
    float xv_nt[NTRKMAX][6];
    float yv_nt[NTRKMAX][6];
    float zv_nt[NTRKMAX][6];
    float axv_nt[NTRKMAX][6];
    float ayv_nt[NTRKMAX][6];
    float dedx_x[NTRKMAX][6];
    float dedx_y[NTRKMAX][6];
    int cltrx[NTRKMAX][6];
    int cltry[NTRKMAX][6];
//	float bdl[NTRKMAX];

    void InitcTrkLevel2(){
	
//    good2 = 0;
	for(Int_t i=0; i<12 ; i++){
	    good[i] = 0;
	    for(Int_t ii=0; ii<24 ; ii++)vkflag[ii][i]=0;
	}
	//  ----------------------------
	nclsx = 0;
	nclsy = 0;
	for(Int_t i=0; i<NSINGMAX ; i++){
	    planex[i]  = 0;
	    xs[i][0]   = 0;
	    xs[i][1]   = 0;
	    signlxs[i] = 0;
	    planey[i]  = 0;
	    ys[i][0]   = 0;
	    ys[i][1]   = 0;
	    signlys[i] = 0;
	}
	//  ----------------------------
	ntrk =0 ;
	
	for(Int_t i=0; i<NTRKMAX ; i++){
	    image[i]   = 0; 
	    chi2_nt[i] = 0;
//      bdl[i]     = 0;
	    
	    for(Int_t ii=0; ii<5 ; ii++){
		al_nt[i][ii] = 0;
		for(Int_t iii=0; iii<5 ; iii++)
		    coval[i][ii][iii] = 0;
	    }
	    
	    for(Int_t ii=0; ii<6 ; ii++){
		xm_nt[i][ii]    = 0;
		ym_nt[i][ii]    = 0;
		zm_nt[i][ii]    = 0;
		resx_nt[i][ii]  = 0;
		resy_nt[i][ii]  = 0;
		xgood_nt[i][ii] = 0;
		ygood_nt[i][ii] = 0;
		xv_nt[i][ii]    = 0;
		yv_nt[i][ii]    = 0;
		zv_nt[i][ii]    = 0;
		axv_nt[i][ii]   = 0;
		ayv_nt[i][ii]   = 0;
		dedx_x[i][ii]   = 0;
		dedx_y[i][ii]   = 0;
	    }
	}
    }
    
};
// ==================================================================
/**
 * \brief Struct to pass calibration/parameter file paths to F77 routines
 */
struct cPath {
    char path[256];
    int  pathlen;
    int  error;
/**
 * Fill the struct variables from a TString object
 */
    void FillWith(TString s){
        pathlen = s.Length();
        const char *pc = s.Data();
        for(Int_t i=0; i<=pathlen; i++) path[i] = *pc++;
    };
	
};

// ==================================================================
/* /\** */
/*  * \brief Struct to pass magnetic-field file paths to F77 routines */
/*  *\/ */
/* struct cBPath { */
/*     char b_path[256]; */
/*     int  b_pathlen; */
/*     int  b_error; */
/*     int  b_loaded; */
/* /\** */
/*  * Fill the struct variables from a TString object and set  */
/*  * the load flag to FALSE. */
/*  *\/ */
/*     void FillWith(TString s){ */
/* 	b_loaded  = 0; */
/* 	b_pathlen = s.Length(); */
/* 	const char *pc = s.Data(); */
/* 	for(Int_t i=0; i<=b_pathlen; i++) b_path[i] = *pc++; */
/*     }; */
/* /\** */
/*  * Fill the struct variables from a TString object */
/*  *\/ */
/*     int BIsLoaded(){ return b_loaded; }; */
	
/* }; */

// ==================================================================
/**
 * \brief Struct to set debug mode in F77 routines
 */
struct cDbg {
    int debug;
    int verbose;
    int warning;
//    bool debug;
//    bool verbose;
    void SetNone()   {debug=0; verbose=0; warning=0;};
    void SetWarning(){debug=0; verbose=0; warning=1;};
    void SetVerbose(){debug=0; verbose=1; warning=1;};
    void SetDebug()  {debug=1; verbose=1; warning=1;};
};


// ==================================================================
/**
 * \brief Struct to pass mini2 track parameters to F77 routines
 */
struct cMini2track {
    double al[5];
    double xm[NPLANE],ym[NPLANE],zm[NPLANE];
    double xm_a[NPLANE],ym_a[NPLANE];
    double xm_b[NPLANE],ym_b[NPLANE];
    double resx[NPLANE],resy[NPLANE];
    double xgood[NPLANE],ygood[NPLANE];
    double dedxtrk_x[NPLANE];
    double dedxtrk_y[NPLANE];
    double zini;
    double pfixed;
    double chi2;
    double xv[NPLANE],yv[NPLANE],zv[NPLANE];
    double axv[NPLANE],ayv[NPLANE];
    double cov[5][5];
    double fact;
    int nstep;
    int idcand;
    int trackmode;
    int istepmin;

/*     cMini2track(){ */
/* //  -------------------------- */
/* //  fitting routine parameters */
/* //  -------------------------- */
/* 	zini = 23.5; */
/* 	trackmode = 0; */
/* 	istepmin = 3; */
/* //  -------------------------- */
/* 	pfixed = 0.; */
/* 	chi2  = 0; */
/* 	nstep = 0; */
/* 	for(int it1=0;it1<5;it1++){ */
/* 	    al[it1] = 0; */
/* 	    for(int it2=0;it2<5;it2++)cov[it1][it2] = 0; */
/* 	}; */
/* 	for(int ip=0;ip<6;ip++){ */
/* 	    xgood[ip]  = 0; */
/* 	    ygood[ip]  = 0; */
/* 	    xm[ip]     = 0; */
/* 	    ym[ip]     = 0; */
/* 	    xm_a[ip]     = 0; */
/* 	    ym_a[ip]     = 0; */
/* 	    xm_b[ip]     = 0; */
/* 	    ym_b[ip]     = 0; */
/* 	    zm[ip]     = 0; */
/* 	    resx[ip]   = 0; */
/* 	    resy[ip]   = 0; */
/* 	    xv[ip]     = 0; */
/* 	    yv[ip]     = 0; */
/* 	    zv[ip]     = 0; */
/* 	    axv[ip]    = 0; */
/* 	    ayv[ip]    = 0; */
/* 	    dedxtrk_x[ip] = 0; */
/* 	    dedxtrk_y[ip] = 0; */
/* 	}; */
	
/*     } */


};
//
/**
 * \Struct for the hough transform variables
 */

struct cTrkHough {

  int ndblt_nt;
  float alfayz1_nt[NDBLT_MAX_NT];
  float alfayz2_nt[NDBLT_MAX_NT];
  int db_cloud_nt[NDBLT_MAX_NT];
  int ntrpt_nt;
  float alfaxz1_nt[NTRPT_MAX_NT];
  float alfaxz2_nt[NTRPT_MAX_NT];
  float alfaxz3_nt[NTRPT_MAX_NT];
  int tr_cloud_nt[NTRPT_MAX_NT];
  int nclouds_yz_nt;
  float alfayz1_av_nt[NCLOYZ_MAX];
  float alfayz2_av_nt[NCLOYZ_MAX];
  int ptcloud_yz_nt[NCLOYZ_MAX];
  int nclouds_xz_nt;
  float alfaxz1_av_nt[NCLOXZ_MAX];
  float alfaxz2_av_nt[NCLOXZ_MAX];
  float alfaxz3_av_nt[NCLOXZ_MAX];
  int ptcloud_xz_nt[NCLOXZ_MAX];
  int nclstr;
  float totaltime;
  float houghtime;
  float fittime;


  void InitcTrkHough(){

    ndblt_nt = 0;
    ntrpt_nt = 0;
    nclouds_yz_nt = 0;
    nclouds_xz_nt = 0;
    nclstr = 0;
    totaltime = 0;
    houghtime = 0;
    fittime = 0;
    for(int i=0;i<NDBLT_MAX_NT ;i++){
      alfayz1_nt[i] = 0;
      alfayz2_nt[i] = 0;
      db_cloud_nt[i] = 0;
    }
    for(int i=0;i<NTRPT_MAX_NT ;i++){
      alfaxz1_nt[i] = 0;
      alfaxz2_nt[i] = 0;
      alfaxz3_nt[i] = 0;
      tr_cloud_nt[i] = 0;
    }
    for(int i=0;i<NCLOYZ_MAX ;i++){
      alfayz1_av_nt[i] = 0;
      alfayz2_av_nt[i] = 0;
      ptcloud_yz_nt[i] = 0;
    }
    for(int i=0;i<NCLOXZ_MAX ;i++){
      ptcloud_xz_nt[i] = 0;
      alfaxz1_av_nt[i] = 0;
      alfaxz2_av_nt[i] = 0;
      alfaxz3_av_nt[i] = 0;
    }
  }
  
};

/**
 * \brief Struct to pass VA1-mask to F77 routines
 */
struct cTrkMask {

    int mask_vk[NVK][NVIEW];
    int mask_vk_run[NVK][NVIEW];

//    void Set(TFile* , Int_t , Int_t );

};

/**
 * \brief Struct for pfa parameters
 */
struct cTrkETA {

    int nangbin;
    float angL[NANGMAX],angR[NANGMAX];
    int netaval;
    float eta2[NANGMAX][NETAVALMAX];
    float feta2[NANGMAX][NLADDER][NVIEW][NETAVALMAX];
    float eta3[NANGMAX][NETAVALMAX];
    float feta3[NANGMAX][NLADDER][NVIEW][NETAVALMAX];
    float eta4[NANGMAX][NETAVALMAX];
    float feta4[NANGMAX][NLADDER][NVIEW][NETAVALMAX];

};
/**
 * \brief Struct to configure data reduction
 */
struct cTrkSW{
    int pfaid;
};

extern "C" {

    extern struct cTrkCalib   pedsigbad_;
    extern struct cTrkMask    mask_; 
    extern struct cTrkLevel0  level0event_;
    extern struct cTrkLevel1  level1event_;
    extern struct cTrkLevel2  level2event_;
    extern struct cPath       path_;
    extern struct cDbg        dbg_;
    extern struct cTrkHough   houghevent_;
    extern struct cMini2track track_; 
    extern struct cTrkETA     pfa_; 
    extern struct cTrkSW      sw_;

    void fillpedsigfromdefault_();
    int readmipparam_(); 
    int readchargeparam_(); 
    int readvkmask_(); 
    int readalignparam_(); 
    int readetaparam_(); 
    void reductionflight_(int*);
    int analysisflight_();
    int  readb_();
    void gufld_(float*, float*);
    void xyzpam_(int*,int*,int*,int*,int*,float*,float*,float*,float*);
    float riseta_(int*,float*);

}

#endif
