/**
 * \file TrkHough.cpp
 * \author David Fedele
 */
#include <TrkHough.h>
#include <iostream>
using namespace std;

//--------------------------------------
//
//
//--------------------------------------
TrkHough::TrkHough(){
  
  ndblt=0; 
  alfayz1=0; 
  alfayz2=0; 
  db_cloud=0;
  
  ntrpt=0;  
  alfaxz1=0;
  alfaxz2=0;
  alfaxz3=0;
  tr_cloud=0;
  
  nclouds_yz=0;
  alfayz1_av=0;
  alfayz2_av=0;
  ptcloud_yz=0;
  
  nclouds_xz=0; 
  alfaxz1_av=0;
  alfaxz2_av=0;
  alfaxz3_av=0;
  ptcloud_xz=0;
  
  nclstr=0;
  totaltime=0;
  houghtime=0;
  fittime=0;

//   ntracks=0;
//   al0=0;
//   al1=0;
//   al2=0;
//   al3=0;
//   al4=0;

  Candidates = 0;

};
//--------------------------------------
//
//
//--------------------------------------
void TrkHough::Set(){
    if(!Candidates)Candidates = new TClonesArray("TrkTrack");
}
//--------------------------------------
//
//
//--------------------------------------
/**
 * Fills a TrkHough object with values from a struct cTrkhough (to get data from F77 common).
 */
void TrkHough::SetFromHoughStruct(cTrkHough *lh, cTrkCandidates *lc){

    if(!lh) return;
    // -------------------------
    // fill hough transform info
    // -------------------------
    ndblt          = lh->ndblt_nt;
    ntrpt          = lh->ntrpt_nt;
    nclouds_yz     = lh->nclouds_yz_nt;
    nclouds_xz     = lh->nclouds_xz_nt;
    nclstr         = lh->nclstr;
    totaltime      = lh->totaltime;
    houghtime      = lh->houghtime;
    fittime        = lh->fittime;

    alfayz1        = new Float_t[ndblt];
    alfayz2        = new Float_t[ndblt];
    db_cloud       = new Int_t[ndblt];
    for(int i=0; i<ndblt; i++){
	alfayz1[i]   = (Float_t) lh->alfayz1_nt[i];
	alfayz2[i]   = (Float_t) lh->alfayz2_nt[i];
	db_cloud[i]  = (Int_t) lh->db_cloud_nt[i];
    }

    alfaxz1        = new Float_t[ntrpt];
    alfaxz2        = new Float_t[ntrpt];
    alfaxz3        = new Float_t[ntrpt];
    tr_cloud       = new Int_t[ntrpt];
    for(int i=0; i<ntrpt; i++){
	alfaxz1[i]   = (Float_t) lh->alfaxz1_nt[i];
	alfaxz2[i]   = (Float_t) lh->alfaxz2_nt[i];
	alfaxz3[i]   = (Float_t) lh->alfaxz3_nt[i];
	tr_cloud[i]  = (Int_t) lh->tr_cloud_nt[i];
    }
  
    alfayz1_av        = new Float_t[nclouds_yz];
    alfayz2_av        = new Float_t[nclouds_yz];
    ptcloud_yz        = new Int_t[nclouds_yz];
    for(int i=0; i<nclouds_yz; i++){
	alfayz1_av[i]   = (Float_t) lh->alfayz1_av_nt[i];
	alfayz2_av[i]   = (Float_t) lh->alfayz2_av_nt[i];
	ptcloud_yz[i]   = (Int_t) lh->ptcloud_yz_nt[i];
    }
  
    alfaxz1_av        = new Float_t[nclouds_xz];
    alfaxz2_av        = new Float_t[nclouds_xz];
    alfaxz3_av        = new Float_t[nclouds_xz];
    ptcloud_xz        = new Int_t[nclouds_xz];
    for(int i=0; i<nclouds_xz; i++){
	alfaxz1_av[i]   = (Float_t) lh->alfaxz1_av_nt[i] ;
	alfaxz2_av[i]   = (Float_t) lh->alfaxz2_av_nt[i];
	alfaxz3_av[i]   = (Float_t) lh->alfaxz3_av_nt[i];
	ptcloud_xz[i]   = (Int_t) lh->ptcloud_xz_nt[i];
    }

    if(!lc) return;
    // --------------------------
    // fill track candidates info
    // --------------------------
//     ntracks = lc->ntracks;
//     al0 = new Float_t[ntracks];
//     al1 = new Float_t[ntracks];
//     al2 = new Float_t[ntracks];
//     al3 = new Float_t[ntracks];
//     al4 = new Float_t[ntracks];
//     for(int ii=0; ii<ntracks; ii++){
// 	al0[ii] = (Float_t) lc->al[ii][0];
// 	al1[ii] = (Float_t) lc->al[ii][1];
// 	al2[ii] = (Float_t) lc->al[ii][2];
// 	al3[ii] = (Float_t) lc->al[ii][3];
// 	al4[ii] = (Float_t) lc->al[ii][4];
//    }	
    TrkTrack*   t_track   = new TrkTrack();
    if(!Candidates) Candidates = new TClonesArray("TrkTrack");
    TClonesArray &t = *Candidates;

    for(int i=0; i<lc->ntracks; i++){
//	cout << " - "<<i<<endl;
	t_track->seqno = i;
	t_track->image = 0;
	t_track->chi2  = lc->chi2[i];
	t_track->nstep = 0;
	for(int it1=0;it1<5;it1++){
	    t_track->al[it1] = lc->al[i][it1];
	    for(int it2=0;it2<5;it2++)
		t_track->coval[it1][it2] = 0.;
	};
	for(int ip=0;ip<6;ip++){
	    // ---------------------------------
	    // new implementation of xgood/ygood 
	    // ---------------------------------
	    t_track->xgood[ip]  = (Int_t) lc->xgood[i][ip];
	    t_track->ygood[ip]  = (Int_t) lc->ygood[i][ip];
	    int ssensor = lc->sensor[i][ip];
	    int sladder = lc->ladder[i][ip];
	    if(ip==5&&ssensor!=0)ssensor = 3 - ssensor; //notazione paolo x align
	    t_track->xgood[ip] += 10000000*ssensor+10*sladder ; // ladder+sensor
	    t_track->ygood[ip] += 10000000*ssensor+10*sladder ; // ladder+sensor
//	    if(l2->xbad[i][ip]>0)t_track->xgood[ip]=-t_track->xgood[ip];
//	    if(l2->ybad[i][ip]>0)t_track->ygood[ip]=-t_track->ygood[ip];
	    t_track->xm[ip]     = lc->xm[i][ip];
	    t_track->ym[ip]     = lc->ym[i][ip];
	    t_track->zm[ip]     = lc->zm[i][ip];
	    t_track->resx[ip]   = lc->resx[i][ip];
	    t_track->resy[ip]   = lc->resy[i][ip];
	    t_track->tailx[ip]  = 0.;
	    t_track->taily[ip]  = 0.;
	    t_track->xv[ip]     = lc->xv[i][ip];
	    t_track->yv[ip]     = lc->yv[i][ip];
	    t_track->zv[ip]     = lc->zv[i][ip];
	    t_track->axv[ip]    = lc->axv[i][ip];
	    t_track->ayv[ip]    = lc->ayv[i][ip];
	    t_track->dedx_x[ip] = 0.;
	    t_track->dedx_y[ip] = 0.;
	    t_track->multmaxx[ip] = 0;
	    t_track->multmaxy[ip] = 0;
	    t_track->seedx[ip]  = 0.;
	    t_track->seedy[ip]  = 0.;
	    t_track->xpu[ip]    = 0.;  
	    t_track->ypu[ip]    = 0.;   
	    //-----------------------------------------------------
	    //-----------------------------------------------------
	    //-----------------------------------------------------
	    //-----------------------------------------------------
	};
	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// evaluated coordinates (to define GF)
	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	int    ngf = TrkParams::nGF;
	float *zgf = TrkParams::zGF;
	Trajectory tgf = Trajectory(ngf,zgf);
	tgf.DoTrack2(t_track->al);//<<<< integrate the trajectory
	for(int ip=0; ip<ngf; ip++){
	    t_track->xGF[ip] = tgf.x[ip];
	    t_track->yGF[ip] = tgf.y[ip];
	}
// 	if(t_track->IsSaturated())t_track->Dump();
	new(t[i]) TrkTrack(*t_track);
	t_track->Clear();
    };
//    cout << t.GetEntries() <<" <> "<< Candidates->GetEntries()<<endl;
    
    delete t_track;


};
//--------------------------------------
//
//
//--------------------------------------
TrkTrack *TrkHough::GetCandidate(int it){
    
    if(it >= GetNCandidates()){
	cout << "** TrkHough ** Track-candidate "<< it << "does not exits! " << endl; 
	cout << "               n.candidates = "<< GetNCandidates() << endl;
	return 0;
    }
    if(!Candidates){
	cout << "TrkTrack *TrkHough::GetCandidate(int is) >> (TClonesArray*) Candidate ==0 "<<endl;
    };
    
    TClonesArray &t = *(Candidates);
    TrkTrack *track = (TrkTrack*)t[it];
    return track;
}
//--------------------------------------
//
//
//--------------------------------------
void TrkHough::Clear(){
 

    ndblt = 0;
    ntrpt = 0;
    nclouds_yz = 0;
    nclouds_xz = 0;
    nclstr = 0;
    totaltime = 0;
    houghtime = 0;
    fittime = 0;
//    ntracks = 0;

    if(Candidates)Candidates->Delete();
};
//--------------------------------------
//
//
//--------------------------------------
void TrkHough::Delete(){

    Clear();

    delete [] alfayz1; 
    delete [] alfayz2; 
    delete [] db_cloud;
    
    delete [] alfaxz1;
    delete [] alfaxz2;
    delete [] alfaxz3;
    delete [] tr_cloud;
  
    delete [] alfayz1_av;
    delete [] alfayz2_av;
    delete [] ptcloud_yz;
     
    delete [] alfaxz1_av;
    delete [] alfaxz2_av;
    delete [] alfaxz3_av;
    delete [] ptcloud_xz;

//     delete [] al0;
//     delete [] al1;
//     delete [] al2;
//     delete [] al3;
//     delete [] al4;

    if(Candidates)delete Candidates;

};


ClassImp(TrkHough);
