/**
 * \file CaloFranzini.cpp
 * \author Emiliano Mocchiutti (2007/07/18)
 */
//
// headers
//
#include <CaloFranzini.h>
//--------------------------------------
/**
 * Default constructor 
 */
CaloFranzini::CaloFranzini(){
  Clear();
}

CaloFranzini::CaloFranzini(PamLevel2 *l2p){  
  //
  file = NULL;
  brig = NULL;
  nbin = 0;
  //
  L2 = l2p;
  //
  if ( !L2->IsORB() ) printf(" WARNING: OrbitalInfo Tree is needed, the plugin could not work properly without it \n");
  //
  // Default variables
  //
  debug = false;
  dolong = true;
  dofull = false;
  //
  Clear();
  //
}

void CaloFranzini::Clear(){
  //
  OBT = 0;
  PKT = 0;
  atime = 0;
  longtzeta = 0.;
  fulltzeta = 0.;
  memset(estrip, 0, 2*22*96*sizeof(Float_t));
  memset(qplane, 0, 2*22*sizeof(Float_t));
  //
}

void CaloFranzini::Print(){
  //
  Process();
  //
  printf("========================================================================\n");
  printf(" OBT: %u PKT: %u ATIME: %u \n",OBT,PKT,atime);
  printf(" debug                [debug flag]:.. %i\n",debug);
  printf(" longtzeta                        :.. %f\n",longtzeta);  
  printf(" fulltzeta                        :.. %f\n",fulltzeta);  
  printf("========================================================================\n");
  //
}

void CaloFranzini::Delete(){
  if ( file ) file->Close();
  Clear();
    printf(" ERROR: CaloFranzini variables _NOT_ filled \n");
  };  
  //
  if ( debug ) this->Print();
  if ( debug ) printf(" exit \n");
  //
}

Bool_t CaloFranzini::CreateMatrixFile(TString matrixfile){  
  //
  file = new TFile(matrixfile.Data(),"READ");
  //
  if ( !file || file->IsZombie() ){
    file = new TFile(matrixfile.Data(),"RECREATE"); 
  } else {
    printf(" ERROR: file %s already existing!\n Choose another name or delete the old file\n",matrixfile.Data());
    return(false);
  };
  //
  return(true);
  //
}

void CaloFranzini::WriteNumBin(Int_t numbin){
  TArrayI nbi(1, &numbin);
  file->WriteObject(&nbi, "nbinenergy");
}

void CaloFranzini::WriteRigBin(TArrayF *rigbin){
  file->WriteObject(&rigbin, "binrig");
}

void CaloFranzini::WriteLongMean(TArrayF *qpl, Int_t bin){
  TString name = Form("qplmeann%i",bin);
  file->WriteObject(&qpl,name.Data());
}

void CaloFranzini::WriteLongMatrix(TMatrixD *mat, Int_t bin){
  TString name = Form("matrixn%i",bin);
  file->WriteObject(&(*mat),name.Data());
}

void CaloFranzini::CloseMatrixFile(){
  file->Close();
}


Bool_t CaloFranzini::Open(TString matrixfile){  
  //
  // find matrix file
  //
  if ( !strcmp(matrixfile.Data(),"") ){
    if (dolong) matrixfile = (TString)gSystem->ExpandPathName("$PAM_CALIB")+"/cal-param/covmatrix_longel.root";    
    if (dofull) matrixfile = (TString)gSystem->ExpandPathName("$PAM_CALIB")+"/cal-param/covmatrix_fullel.root";    
  };
  //
  file = new TFile(matrixfile.Data(),"READ");
  //
  if ( !file || file->IsZombie() ){
    printf(" ERROR: cannot open file %s \n",matrixfile.Data());
    return(false);
  };
  //
  TArrayI *numbin = (TArrayI*)file->Get("nbinenergy");
  if ( !numbin ){
    printf(" ERROR: cannot read number of bins from file %s \n",matrixfile.Data());
    return(false);
  };
  nbin = (Int_t)numbin->At(0);
  if ( nbin <= 0 ){
    printf(" ERROR: cannot work with 0 energy bins (from file %s) \n",matrixfile.Data());
    return(false);
  };
  //
  brig = (TArrayF*)file->Get("binrig");
  if ( !brig ){
    printf(" ERROR: cannot read rigidity binning from file %s \n",matrixfile.Data());
    return(false);
  };
  //
  return(true);
  //
}

TMatrixD *CaloFranzini::LoadCovarianceMatrix(Float_t rig){
  //
  TString name;
  for (Int_t i = 0; i<nbin-1; i++){
    if ( rig>=brig->At(i) && rig < brig->At(i+1) ){
      name = Form("matrixn%i",i);
      break;
    };
  };
  if ( rig < brig->At(0) ){
    printf(" WARNING: Event with rigidity lower than the first covariance matrix bin (rig = %f, lower limit = %f)\n",rig,brig->At(0));
    name = "matrixn0";
    printf(" Using matrix %s \n",name.Data());
  };
  if ( rig >= brig->At(nbin) ){
    printf(" WARNING: Event with rigidity higher than the last covariance matrix bin (rig = %f, upper limit = %f)\n",rig,brig->At(nbin));
    name = Form("matrixn%i",nbin-1);
    printf(" Using matrix %s \n",name.Data());
  };
  //
  TMatrixD *matrix = (TMatrixD*)file->Get(name.Data());
  //
  return(matrix);
  //
}


TArrayF *CaloFranzini::LoadLongAverage(Float_t rig){
  //
  TString name;
  for (Int_t i = 0; i<nbin-1; i++){
    if ( rig>=brig->At(i) && rig < brig->At(i+1) ){
      name = Form("qplmeann%i",i);
      break;
    };
  };
  if ( rig < brig->At(0) ){
    printf(" WARNING: Event with rigidity lower than the first qplmean bin (rig = %f, lower limit = %f)\n",rig,brig->At(0));
    name = "qplmeann0";
    printf(" Using qplmean %s \n",name.Data());
  };
  if ( rig >= brig->At(nbin) ){
    printf(" WARNING: Event with rigidity higher than the last qplmean bin (rig = %f, upper limit = %f)\n",rig,brig->At(nbin));
    name = Form("qplmeann%i",nbin-1);
    printf(" Using qplmean %s \n",name.Data());
  };
  //
  TArrayF *qplmean = (TArrayF*)file->Get(name.Data());
  //
  return(qplmean);
  //
}
