#include "TDC.h"

//constructor
TDC::TDC( int ch_num , int tdc_num ){  //{{{
   _ch_num = ch_num;
   _tdc_num = tdc_num;

   ch_num = 0;
   tdc_num = 0;
   pdf_min = 0.;

   pdf_filename = "";
   b_pdffile = false;

   sum_all_pdf = 0;

   stat = 1;
   l_col = 1;
   l_w = 1 ;
   l_sty = 1;
   scale = 1.;
   title = "PDF";
   xtitle = "";
   ytitle = "";

   h_pdf.resize( _ch_num );
   flag_ring = false;

   pdf.resize( _ch_num );

} //}}}


//Public Function
void TDC::Print( void ){ //{{{
   for( int tdc = 0;tdc < _tdc_num;tdc++){
      std::cout << tdc << ": " ;
      for( int ch = 0;ch < _ch_num;ch++){
         std::cout << pdf[ch][tdc] << " " ;
      }
      std::cout << std::endl;
   }
} //}}}


void TDC::Write( std::string outpdf_file , std::string header ){  //{{{ Output pdf[][] to file
   std::ofstream ofs( outpdf_file.c_str() );

   ofs << header << std::endl << std::endl;
   for( int ch = 0;ch < _ch_num;ch++)ofs << ch << " ";
   ofs << std::endl;

   for( int tdc = 0;tdc < _tdc_num;tdc++){
      ofs << tdc << ": ";
      for( int ch = 0;ch < _ch_num;ch++){
         ofs << pdf[ ch ][ tdc ] << " " ;
      }
      ofs << std::endl;
   }

   ofs.close();
} //}}}


float TDC::Integral( int ch , int start_bin , int end_bin ){  //{{{
   float sum = 0.;
   if( ch < 0 ){
      sum = sum_all_pdf;
   }else{
      for( int tdc = start_bin;tdc < end_bin;tdc++)sum += pdf[ ch ][ tdc ];
   }
   return sum;
} //}}}


void TDC::Clear( void ){ //{{{

   pdf_filename = "";
   b_pdffile = false;

   pdf_min = 0.;
   sum_all_content = 0;
   sum_all_pdf = 0;

   for( int ch = 0;ch < _ch_num;ch++)pdf[ch].clear();
   pdf.clear();

   sum_ch_pdf.clear();

} //}}}


//PDF from Data root file 
void TDC::SetRootFile( TFile *root_file , std::string cut , int start_bin , int end_bin ){ //{{{

   //Iitialize pdf matrix
   pdf.resize( _ch_num );
   sum_ch_pdf.resize( _ch_num );
   for( int ch = 0;ch < _ch_num;ch++){
      pdf[ch].resize( _tdc_num );
      sum_ch_pdf[ch] = 0.;
      for( int tdc = 0;tdc < _tdc_num;tdc++)pdf[ch][tdc] = 0.;
   }
   sum_all_content = 0.;
   sum_all_pdf = 0.;
  
   int start_data = start_bin;
   int end_data = end_bin;
   int nbin_data = end_bin - start_bin;


   TH1F *tdc_root[_ch_num];
   TTree *tr_root;
   tr_root = (TTree*)root_file->Get("ana");
   TH1F *h_noe;

   for(int ch = 0;ch < _ch_num;ch++){

      TString obj = "tdc_";obj += ch;
      TString draw = "tdc[";draw += ch;draw += "] - tdc_tc1 >>";draw += obj;
              draw += "(";draw += nbin_data;draw += ",";draw += start_data;draw += ",";draw += end_data;draw += ")";
      TString s_cut = "tdc[";s_cut += ch;
              s_cut += "] < ";s_cut += _tdc_num;s_cut += " ";s_cut += cut;

      std::cout << "Cut option:" << s_cut << std::endl;

      tr_root->Draw( draw , s_cut );

      tdc_root[ch] = (TH1F*)gROOT->FindObject(obj);
      tdc_root[ch]->Draw();

      for(int tdc = 1;tdc < _tdc_num;tdc++){
         pdf[ch][tdc-1] = tdc_root[ch]->GetBinContent(tdc);
         sum_ch_pdf[ch] += pdf[ ch ][ tdc - 1 ];
         sum_all_content += pdf[ ch ][ tdc - 1 ];
      }
      
      std::cout << ch << "," << std::flush;

   }

   for(int tdc = 0;tdc < _tdc_num;tdc++){
     for(int ch = 0;ch < _ch_num;ch++){
       pdf[ch][tdc] /= sum_all_content;
       sum_all_pdf += pdf[ch][tdc];
     }
   }

   tr_root->Draw("nhit>>noe", (TString)cut );
   h_noe = (TH1F*)gROOT->FindObject("noe");
   std::cout << std::endl;

}//}}}


void TDC::SetRootMCFile( TFile *f , std::string cut ){ //{{{

   TCanvas *c_root = new TCanvas( "c_root","c_root" );

   //Iitialize pdf matrix
   pdf.resize( _ch_num );
   sum_ch_pdf.resize( _ch_num );
   for( int ch = 0;ch < _ch_num;ch++){
      pdf[ch].resize( _tdc_num );
      sum_ch_pdf[ch] = 0.;
      for( int tdc = 0;tdc < _tdc_num;tdc++)pdf[ch][tdc] = 0.;
   }
   sum_all_content = 0.;
   sum_all_pdf = 0.;
  
   int start_data = 0 , end_data = _tdc_num , nbin_data;
   nbin_data = end_data - start_data;

   f->cd();
   TTree *t_top;
   t_top = (TTree*)gROOT->FindObject("top");
   TH1F *tdc[_ch_num];

   for(Int_t ch = 0;ch < _ch_num;ch++){
      TString obj = "tdc_simu";obj +=  ch;
      TString draw = "tdc[";draw +=  ch;draw += "] >>";draw += obj;
                  draw += "(";draw += nbin_data;draw += ",";draw += start_data;draw += ",";draw += end_data;draw += ")";
      TString opt = "tdc[";opt += ch;opt += "] < 4000";opt += (TString)cut;

      t_top->Draw(draw,opt);

      tdc[ch] = (TH1F*)gROOT->FindObject(obj);
      tdc[ch]->Draw();

      for(int i = 1;i <= _tdc_num;i++){
        pdf[ch][i-1] = tdc[ch]->GetBinContent(i);
        sum_ch_pdf[ch] += pdf[ ch ][ i - 1 ];
        sum_all_content += pdf[ ch ][ i - 1 ];
      }
   }

   for(int tdc = 0;tdc < _tdc_num;tdc++){
     for(int ch = 0;ch < _ch_num;ch++){
       pdf[ch][tdc] /= sum_all_content;
       sum_all_pdf += pdf[ch][tdc];
     }
   }

   delete c_root;

} //}}}


void TDC::SetPdfFile( std::string file ){ //{{{
   pdf_filename = file;
   //Initialize matrix
   pdf.resize( _ch_num );
   sum_ch_pdf.resize( _ch_num );
   for( int ch = 0;ch < _ch_num;ch++){
      pdf[ch].resize( _tdc_num );
      sum_ch_pdf[ch] = 0.;
   }
   sum_all_pdf = 0.;

   //Read pdf file 
   std::ifstream ifs_pdf( pdf_filename.c_str() );
   if( !ifs_pdf.is_open() ){
      std::cout << "[TDC][SetPdfFile]Error:: Can not open \" " << pdf_filename << " \" " << std::endl;
   }

   //fill pdf values 
   std::string buf;
   getline( ifs_pdf , buf );
   getline( ifs_pdf , buf );
   getline( ifs_pdf , buf );

   for( int tdc = 0;tdc < _tdc_num;tdc++){
      getline( ifs_pdf , buf );
      std::stringstream ss( buf );
      float p;

      ss >> buf;
      for( int ch = 0;ch < _ch_num;ch++){
         ss >> p;
         if( p > pdf_min ){
            pdf[ ch ][ tdc ] = p;
         }else{
            pdf[ ch ][ tdc ] = pdf_min;
         }

         sum_all_pdf += pdf[ ch ][ tdc ];
         sum_ch_pdf[ch] += pdf[ ch ][ tdc ];
      }

   }

   ifs_pdf.close();

} //}}}


void TDC::SetTdcOffset( int offset ){ //{{{
   std::vector<int> of;
   for( int ch = 0;ch < _ch_num;ch++)of.push_back( offset );
   SetTdcOffset( of );
} //}}}


void TDC::SetTdcOffset( std::vector<int> offset ){ //{{{

   std::vector< std::vector<float> > tmp_pdf;
   tmp_pdf.resize( _ch_num );
   for( int ch = 0;ch < _ch_num;ch++){
      tmp_pdf[ch].resize( _tdc_num );
   }

   for( int ch = 0;ch < _ch_num;ch++){
      for( int tdc = 0;tdc < _tdc_num;tdc++){

         if( ( ( tdc - offset[ch] ) > 0 ) && ( ( tdc - offset[ch] ) < _tdc_num ) ){
            tmp_pdf[ ch ][ tdc ] = pdf[ ch ][ tdc - offset[ch] ];
         }else{
            tmp_pdf[ ch ][ tdc ] = pdf_min;
         }

      }
   }

   for( int ch = 0;ch < _ch_num;ch++){
      for( int tdc = 0;tdc < _tdc_num;tdc++){
         pdf[ ch ][ tdc ] = tmp_pdf[ ch ][ tdc ];
      }
   }

} //}}}


//-- Draw Histgram --//
void TDC::DrawPdf( int ch , int start_bin , int end_bin , TString option ){ //{{{

   TString str_title = title;str_title += "_";str_title += ch;str_title += "ch";
   h_pdf[ch] = new TH1F( str_title , title , (Int_t)(end_bin - start_bin) , (Float_t)start_bin , (Float_t)end_bin );
   for( int tdc = start_bin;tdc < end_bin;tdc++){
      h_pdf[ch]->SetBinContent( tdc-start_bin , pdf[ ch ][ tdc ] );
   }

   h_pdf[ch]->SetStats(stat);
   h_pdf[ch]->SetLineWidth( l_w );
   h_pdf[ch]->SetLineStyle( l_sty );
   h_pdf[ch]->SetLineColor( l_col );
   h_pdf[ch]->SetTitle( title );
   h_pdf[ch]->SetXTitle( xtitle );
   h_pdf[ch]->Scale( scale );
   h_pdf[ch]->Draw( option );

} //}}}


void TDC::Draw( int ch , int start_bin , int end_bin , TString option ){ //{{{
   Scale( sum_all_content );
   DrawPdf( ch , start_bin , end_bin , option );
} //}}}


void TDC::DrawRingImage( TString option , int tdc_start_bin , int tdc_end_bin , int ch_start , int ch_end ){ //{{{

   TString str_title = title;str_title += "(RingImage)";
   if( !flag_ring ){
      h_ring = new TH2F( str_title , title , ch_end - ch_start , ch_start , ch_end , tdc_end_bin - tdc_start_bin , tdc_start_bin , tdc_end_bin );
      flag_ring = true;
   }

   for( int ch = ch_start;ch < ch_end;ch++){
      for( int tdc = tdc_start_bin;tdc < tdc_end_bin;tdc++){
         h_ring->SetBinContent( ch - ch_start + 1 , tdc - tdc_start_bin , pdf[ ch ][ tdc ] );
      }
   }

   h_ring->SetStats(stat);
   h_ring->SetTitle( title );
   h_ring->SetXTitle( xtitle );
   h_ring->SetYTitle( ytitle );
   h_ring->Draw(option);
   
} //}}}


