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

CaloDoubleShower::CaloDoubleShower(PamLevel2 *l2p){  
  //
  L2 = l2p;
  //
  if ( !L2->IsORB() ) printf(" WARNING: OrbitalInfo Tree is needed, the plugin could not work properly without it \n");
  //
  OBT = 0;
  PKT = 0;
  atime = 0;
  //
  // Default variables
  //
  extern struct Calo2sh sdouble_;
  c2s = &sdouble_;
  event = new CaloLevel0();
  cstrip = new CaloStrip(false);
  debug = false;
  simulation = false;
  //
  Clear();
  //
};

void CaloDoubleShower::LoadMagneticField(){
  //
  // loading magnetic field...  
  //
  TrkLevel2 *trk = new TrkLevel2();
  GL_PARAM *q4 = new GL_PARAM();
  TSQLServer *dbc = 0;
  TString host = "mysql://localhost/pamelaprod";
  TString user = "anonymous";
  TString psw = "";
  const char *pamdbhost=gSystem->Getenv("PAM_DBHOST");
  const char *pamdbuser=gSystem->Getenv("PAM_DBUSER");
  const char *pamdbpsw=gSystem->Getenv("PAM_DBPSW");
  if ( !pamdbhost ) pamdbhost = "";
  if ( !pamdbuser ) pamdbuser = "";
  if ( !pamdbpsw ) pamdbpsw = "";
  if ( strcmp(pamdbhost,"") ) host = pamdbhost;
  if ( strcmp(pamdbuser,"") ) user = pamdbuser;
  if ( strcmp(pamdbpsw,"") ) psw = pamdbpsw;
  dbc = TSQLServer::Connect(host.Data(),user.Data(),psw.Data());
  q4->Query_GL_PARAM(1,1,dbc);
  printf(" Reading magnetic field maps at %s\n",(q4->PATH+q4->NAME).Data());
  trk->LoadField(q4->PATH+q4->NAME);
  //
};

void CaloDoubleShower::Clear(){
  //
  dbls = 0;
  qdbls = 0.;
  //
};

void CaloDoubleShower::Print(){
  Print(0);
};

void CaloDoubleShower::Print(UInt_t nt){
  //
  Process(nt);
  //
  printf("========================================================================\n");
  printf(" OBT: %u PKT: %u ATIME: %u \n",OBT,PKT,atime);
  printf(" debug                [debug flag]:.. %i\n",debug);
  printf(" simulation      [simulation flag]:.. %i\n",simulation);
  printf(" dbls         [double shower flag]:.. %i\n",dbls);
  printf(" qdbls      [double shower energy]:.. %f\n",qdbls);
  printf("========================================================================\n");
  //
};

void CaloDoubleShower::Delete(){
  Clear();
};


void CaloDoubleShower::Process(){
  Process(0);
};

void CaloDoubleShower::Process(UInt_t ntr){
  //  
  if ( !L2 ){
    printf(" ERROR: cannot find PamLevel2 object, use the correct constructor or check your program!\n");
    printf(" ERROR: CaloDoubleShower variables _NOT_ filled \n");
    return;
  };
  //
  Bool_t newentry = false;
  //
  if ( L2->IsORB() ){
    if ( L2->GetOrbitalInfo()->pkt_num != PKT || L2->GetOrbitalInfo()->OBT != OBT || L2->GetOrbitalInfo()->absTime != atime  || ntr != sntr){
      newentry = true;
      OBT = L2->GetOrbitalInfo()->OBT;
      PKT = L2->GetOrbitalInfo()->pkt_num;
      atime = L2->GetOrbitalInfo()->absTime;
      sntr = ntr;
   };
  } else {
    newentry = true;
  };
  //
  if ( !newentry ) return;
  //
  // check track
  //
  PamTrack *ptrack = 0;
  if ( ntr >= 0 ){
    ptrack = L2->GetTrack(ntr);
  };
  //
  if ( !ptrack ){
    printf(" ERROR: cannot find requested track!\n");
    printf(" ERROR: CaloDoubleShower variables _NOT_ filled \n");    
    return;
  };
  //
  tr = ntr;
  //
  if ( debug ) printf(" Processing event at OBT %u PKT %u time %u \n",OBT,PKT,atime);
  //
  this->Clear();
  //
  // Some variables
  //

  //
  if ( debug ) printf(" Fill estrip matrix needed to calculate variables \n");
  //
  // Fill the estrip matrix
  //
  memset(event->clevel1->estrip, 0, 2*22*96*sizeof(Float_t));
  Int_t view = 0;
  Int_t plane = 0;
  Int_t strip = 0;
  Float_t mip = 0.;
  for ( Int_t i=0; i<L2->GetCaloLevel1()->istrip; i++ ){
    //
    mip = L2->GetCaloLevel1()->DecodeEstrip(i,view,plane,strip);
    event->clevel1->estrip[strip][plane][view] = mip;
    //
  };
  //
  // if data comes from the simulation we must use mechanical alignment parameters (default is flight parameters)
  //
  if ( simulation ){
    cstrip->UseMechanicalAlig();
  };
  //
  // Set alignment parameter 
  //
  event->clevel1->xalig = cstrip->GetXalig();
  event->clevel1->yalig = cstrip->GetYalig();
  event->clevel1->zalig = cstrip->GetZalig();
  //
  event->clevel1->emin = 0.7;
  event->clevel1->npla = 22;
  event->clevel1->reverse = 0; // if the number of planes is even we have taken away a full module no need to do anything strange...
  //
  if ( debug ) printf(" xalig = %f \n",event->clevel1->xalig);
  if ( debug ) printf(" yalig = %f \n",event->clevel1->yalig);
  if ( debug ) printf(" zalig = %f \n",event->clevel1->zalig);
  //
  // let's go
  //
  TrkTrack *ptt = ptrack->GetTrkTrack(); 
  //
  // Copy the alpha vector in the input structure
  //
  for (Int_t e = 0; e < 5 ; e++){
    event->clevel1->al_p[e][0] = ptt->al[e];
  };	  
  //
  Float_t m = (ptrack->GetToFTrack()->xtr_tof[0] - ptrack->GetToFTrack()->xtr_tof[3])/(ZTOF11-ZTOF21);
  Float_t q = ptrack->GetToFTrack()->xtr_tof[3] - m * ZTOF21;
  //
  c2s->pos = (m * event->clevel1->zalig + q)*10. + event->clevel1->xalig;
  c2s->angol = m;
  //
  // call fortran routine
  //
  getdblsh();
  //
  // retrieve calculated variables;
  //
  dbls = (Int_t)c2s->dbls;
  qdbls = c2s->dblsq;
  //
  if ( debug ) this->Print();
  if ( debug ) printf(" exit \n");
  //
};