// =====================================================================
//  $Id: OFFcti.cc,v 1.5 2003/10/06 16:28:18 goiwai Exp $
//  $Name: CLDAQ-1-14-03 $
//  $Log: OFFcti.cc,v $
//  Revision 1.5  2003/10/06 16:28:18  goiwai
//  *** empty log message ***
//
//  Revision 1.4  2003/07/30 16:16:10  goiwai
//  ファイルにコミットログをつけることにしました.
//
// =====================================================================
#include "TEnvironmentVariableTable.hh"
#include "Trootinit.h"
#include "St01SinglePixelInterface.hh"

int main( int argc, char** argv, char** envv )
{
  Tbool isprint = Tfalse;
  if ( argc != 2 && argc != 3 ) {
    Tcerr << "usage: " << argv[ 0 ] << " <dataset> [1|0]" << Tendl;
    return -1;
  }
  if ( argc == 3 ) {
    isprint = (Tbool)strtol( argv[ 2 ], 0, 0 );
  }

  TApplication* theApplication = rootinit();
  TCanvas CVcti( "CVcti", "CTI", 960, 720 );
  CVcti.ToggleEventStatus();
  CVcti.Divide( 2, 2 );
  TH1D H1Dspx( "H1Dspx", "Single Pixel Events", 100, 0.0, 500.0 );
  TGaxis::SetMaxDigits( 2 );
  H1Dspx.GetXaxis()->SetTitle("Pulseheight (ADU)");
  H1Dspx.GetXaxis()->CenterTitle();
  H1Dspx.GetXaxis()->SetNoExponent();
  H1Dspx.GetYaxis()->SetTitle("Counts");
  H1Dspx.GetYaxis()->CenterTitle();




  Tstring dataset = argv[ 1 ];
  St01SinglePixelInterface spif( dataset );
  St01SinglePixelList splist = spif.GetSinglePixelList();

  TEnvironmentVariableTable envtable( "st01setup" );
  //Tdouble left = envtable.GetDoubleValue( "ST01_MANUALCUT_LEFT" );
  //Tdouble right = envtable.GetDoubleValue( "ST01_MANUALCUT_RIGHT" );
  // 分割方式のパラメーター
  const Tint hdivide = envtable.GetIntegerValue( "ST01_CTI_HDIVIDE" );
  const Tint vdivide = envtable.GetIntegerValue( "ST01_CTI_VDIVIDE" );
  Tint nh = envtable.GetIntegerValue( "ST01_HPIXEL" );
  Tint nv = envtable.GetIntegerValue( "ST01_VPIXEL" );
  Tint hpitch = nh / vdivide;
  Tint vpitch = nv / hdivide;


  for ( Tsize_t i = 0; i < splist.size(); i ++ ) {
    H1Dspx.Fill( splist[ i ].GetSignal() );
  }


  CVcti.cd( 1 );
  H1Dspx.Fit("gaus", "qm");
  CVcti.Update();
  ((TPaveStats*)(H1Dspx.FindObject( "stats" )))->SetY1NDC(0.2);





  //==================================================================
  //                                          ___________
  // 縦方向にフレームを分割しHCTIを求める    |  |  |  |  |
  //                                         |  |  |  |  |
  //                                         |  |  |  |  |
  //                                         |  |  |  |  |
  //                                         |__|__|__|__|
  //
  //==================================================================
  //領域分のヒストを作って表示する
  TH1D* H1Dvdivide = new TH1D[ vdivide ];
  for ( Tint i = 0; i < vdivide; i ++ ) {
    H1Dvdivide[ i ].SetBins( 100, 0.0, 500.0 );

    Tstring title = "Vertical Partition(for HCTI): " + itostr( i, 0 );
    H1Dvdivide[ i ].SetTitle( title.c_str() );

    Tstring name = "H1Dvdivide" + itostr( i, 3 );
    H1Dvdivide[ i ].SetName( name.c_str() );
    H1Dvdivide[ i ].GetXaxis()->SetTitle("Pulseheight (ADU)");
    H1Dvdivide[ i ].GetXaxis()->CenterTitle();
    H1Dvdivide[ i ].GetXaxis()->SetNoExponent();
    H1Dvdivide[ i ].GetYaxis()->SetTitle("Counts");
    H1Dvdivide[ i ].GetYaxis()->CenterTitle();
  }
  for ( Tsize_t i = 0; i < splist.size(); i ++ ) {
    Tint h = splist[ i ].GetHorizontalID() ;
    Tdouble s = splist[ i ].GetSignal();
    H1Dvdivide[ h/hpitch ].Fill( s );
  }

  TCanvas CVvdivide( "CVvdivide", "Divide Vertical Direction for HCTI", 960, 720 );
  CVvdivide.ToggleEventStatus();
  CVvdivide.Divide( 4, 4 );

  Tdouble* nHt = new Tdouble[ vdivide ];       // 水平転送の回数
  Tdouble* nHt_e = new Tdouble[ vdivide ];     // 水平転送のエラー初期値
  Tdouble* adcV = new Tdouble[ vdivide ];      // 縦に切った範囲でのADC中心値
  Tdouble* adcV_e = new Tdouble[ vdivide ];    // ADCのエラー初期値
  for ( Tint i = 0; i < vdivide; i ++ ) {
    CVvdivide.cd( i + 1 );
    H1Dvdivide[ i ].Fit( "gaus", "qm" );
    TF1* f = H1Dvdivide[ i ].GetFunction( "gaus" );

    nHt[ i ] = ((hpitch-1)/2.0) + hpitch*i;
    //nHt_e[ i ] = (hpitch-1)/2.0;
    nHt_e[ i ] = 0.0;
    adcV[ i ] = f -> GetParameter( 1 );      // Mean
    adcV_e[ i ] = f -> GetParError( 1 );     // Mean Error

    CVvdivide.Modified();
    CVvdivide.Update();
  }




  //各領域の転送回数とその領域で観測されたADCカウントをプロットする
  CVcti.cd(2);
  gPad -> DrawFrame( 0.0, 0.0, 256.0, 500.0 );
  TH1F* hframe = (TH1F*)( gPad -> FindObject( "hframe" ) );
  hframe->GetXaxis() -> SetTitle( "Average Horizontal Transfer" );
  hframe->GetXaxis() -> CenterTitle();
  hframe->GetXaxis() -> SetNoExponent();
  //hframe.GetXaxis() -> SetTitleOffset( 1.2 );
  hframe->GetYaxis() -> SetTitle( "Pulseheight (ADU)" );
  hframe->GetYaxis() -> CenterTitle();
  hframe->GetYaxis() -> SetNoExponent();
  hframe->SetTitle( "Horizontal Charge Transfer Inefficiency" );

  TGraphErrors GEHCTI( vdivide, nHt, adcV, nHt_e, adcV_e );
  GEHCTI.SetName( "GEHCTI" );
  GEHCTI.Draw( "p" );
  TF1 myfitHCTI( "myfitHCTI", "[0] * pow( ( 1.0 - [ 1 ] ), x )", 0, 512 );
  myfitHCTI.SetParameters( 350.0, 0.0 );
  myfitHCTI.SetParNames( "Q0", "HCTI" );
  GEHCTI.Fit( "myfitHCTI", "qm" );

  Tdouble Q0H = myfitHCTI.GetParameter( 0 );
  Tdouble Q0H_e = myfitHCTI.GetParError( 0 );
  Tdouble HCTI = myfitHCTI.GetParameter( 1 );
  Tdouble HCTI_e = myfitHCTI.GetParError( 1 );
  Tstring myfitHCTItitle = myfitHCTI.GetTitle();








  //==================================================================
  //                                         ________
  // 横方向にフレームを分割しVCTIを求める   |________|
  //                                        |________|
  //                                        |________|
  //                                        |________|
  //
  //==================================================================
  //領域分のヒストを作って表示する
  TH1D* H1Dhdivide = new TH1D[ hdivide ];
  for ( Tint i = 0; i < hdivide; i ++ ) {
    H1Dhdivide[ i ].SetBins( 100, 0.0, 500.0 );

    Tstring title = "Horizontal Partition(for VCTI): " + itostr( i, 0 );
    H1Dhdivide[ i ].SetTitle( title.c_str() );

    Tstring name = "H1Dhdivide" + itostr( i, 3 );
    H1Dhdivide[ i ].SetName( name.c_str() );
    H1Dhdivide[ i ].GetXaxis()->SetTitle("Pulseheight (ADU)");
    H1Dhdivide[ i ].GetXaxis()->CenterTitle();
    H1Dhdivide[ i ].GetXaxis()->SetNoExponent();
    H1Dhdivide[ i ].GetYaxis()->SetTitle("Counts");
    H1Dhdivide[ i ].GetYaxis()->CenterTitle();
  }
  for ( Tsize_t i = 0; i < splist.size(); i ++ ) {
    Tint v = splist[ i ].GetVerticalID();
    Tdouble s = splist[ i ].GetSignal();
    H1Dhdivide[ v/vpitch ].Fill( s );
  }

  TCanvas CVhdivide( "CVhdivide", "Divide Horizontal Direction for VCTI", 960, 720 );
  CVhdivide.ToggleEventStatus();
  CVhdivide.Divide( 4, 4 );

  Tdouble* nVt = new Tdouble[ hdivide ];       // 鉛直転送の回数
  Tdouble* nVt_e = new Tdouble[ hdivide ];     // 鉛直転送のエラー初期値
  Tdouble* adcH = new Tdouble[ hdivide ];      // 横に切った範囲でのADC中心値
  Tdouble* adcH_e = new Tdouble[ hdivide ];    // ADCのエラー初期値
  for ( Tint i = 0; i < hdivide; i ++ ) {
    CVhdivide.cd( i + 1 );
    H1Dhdivide[ i ].Fit( "gaus", "qm" );
    TF1* f = H1Dhdivide[ i ].GetFunction( "gaus" );

    nVt[ i ] = ((vpitch-1)/2.0) + vpitch*i;
    //nVt_e[ i ] = (vpitch-1)/2.0;
    nVt_e[ i ] = 0.0;
    adcH[ i ] = f -> GetParameter( 1 );    // Mean
    adcH_e[ i ] = f -> GetParError( 1 );   // Mean Error

    CVhdivide.Modified();
    CVhdivide.Update();
  }


  //各領域の転送回数とその領域で観測されたADCカウントをプロットする
  CVcti.cd(4);
  gPad -> DrawFrame( 0.0, 0.0, 256.0, 500.0 );
  hframe = (TH1F*)( gPad -> FindObject( "hframe" ) );
  hframe->GetXaxis() -> SetTitle( "Average Vertical Transfer" );
  hframe->GetXaxis() -> CenterTitle();
  hframe->GetXaxis() -> SetNoExponent();
  //hframe.GetXaxis() -> SetTitleOffset( 1.2 );
  hframe->GetYaxis() -> SetTitle( "Pulseheight (ADU)" );
  hframe->GetYaxis() -> CenterTitle();
  hframe->GetYaxis() -> SetNoExponent();
  hframe->SetTitle( "Vertical Charge Transfer Inefficiency" );

  TGraphErrors GEVCTI( hdivide, nVt, adcH, nVt_e, adcH_e );
  GEVCTI.SetName( "GEVCTI" );
  GEVCTI.Draw( "p" );
  TF1 myfitVCTI( "myfitVCTI", "[0] * pow( ( 1.0 - [ 1 ] ), x )", 0, 512 );
  myfitVCTI.SetParameters( 350.0, 0.0 );
  myfitVCTI.SetParNames( "Q0", "VCTI" );
  GEVCTI.Fit( "myfitVCTI", "qm" );

  Tdouble Q0V = myfitVCTI.GetParameter( 0 );
  Tdouble Q0V_e = myfitVCTI.GetParError( 0 );
  Tdouble VCTI = myfitVCTI.GetParameter( 1 );
  Tdouble VCTI_e = myfitVCTI.GetParError( 1 );
  Tstring myfitVCTItitle = myfitVCTI.GetTitle();





  //==================================================================
  //
  // SUMMARYを埋め込む
  //
  //==================================================================
  TPaveText PTsum( 0.0, 0.0, 1.0, 1.0 );
  PTsum.SetFillColor( 10 );
  PTsum.SetFillStyle( 0 );
  PTsum.SetBorderSize( 0 );
  PTsum.SetTextAlign( 12 );
  //PTainfo.SetTextSize( 0.06 );
  TstringList summary;
  summary.push_back( "FILE: " + dataset );
  summary.push_back( "ST01_CTI_HDIVIDE: " + itostr( hdivide,0 ) );
  summary.push_back( "ST01_CTI_VDIVIDE: " + itostr( vdivide,0 ) );

  summary.push_back( "Divide Vertical " + itostr( vdivide, 0 ) + " Region" );
  summary.push_back( "  #Rightarrow Function: " + myfitHCTItitle );
  summary.push_back( "  #Rightarrow Q: " + dtostr( Q0H ) + " #pm " + dtostr( Q0H_e ) );
  summary.push_back( "  #Rightarrow HCTI: " + dtostr( HCTI ) + " #pm " + dtostr( HCTI_e ) );
  summary.push_back( "Divide Horizontal " + itostr( hdivide, 0 ) + " Region" );
  summary.push_back( "  #Rightarrow Function: " +  myfitVCTItitle );
  summary.push_back( "  #Rightarrow Q: " + dtostr( Q0V ) + " #pm " + dtostr( Q0V_e ) );
   summary.push_back( "  #Rightarrow VCTI: " + dtostr( VCTI ) + " #pm " + dtostr( VCTI_e ) );

  for ( Tsize_t i = 0; i < summary.size(); i ++ ) {
    PTsum.AddText( summary[ i ].c_str() );
  }
  PTsum.AddText( "" );
  CVcti.cd( 3 );
  PTsum.Draw();

  CVcti.cd();
  CVcti.Modified();
  CVcti.Update();




  //印刷したけりゃ
  // % ../../../bin/OFFcti /xxx/xxx/xxx.dat 1
  if ( isprint ) {
    CVcti.Print( "CTIspselect.ps" );
    CVcti.Print( "CTIspselect.gif" );
    CVcti.Print( "CTIspselect.C" );
    CVcti.Print( "CTIspselect.root" );
    CVvdivide.Print( "CTIvdivide.ps" );
    CVvdivide.Print( "CTIvdivide.gif" );
    CVvdivide.Print( "CTIvdivide.C" );
    CVvdivide.Print( "CTIvdivide.root" );
    CVhdivide.Print( "CTIhdivide.ps" );
    CVhdivide.Print( "CTIhdivide.gif" );
    CVhdivide.Print( "CTIhdivide.C" );
    CVhdivide.Print( "CTIhdivide.root" );
  }

  theApplication -> Run();
  return 0;
}
