////////////////////////////////////////////////////////////////
//
//  MFadc
//
//  
#include "MFadc.hxx"

#include "MMcEvt.hxx"

#include "TROOT.h"
#include <TApplication.h>
#include <TVirtualX.h>
#include <TGClient.h>

#include "TH1.h"
#include "TObjArray.h"

#include "MGFadcSignal.hxx"

MFadc::MFadc(Int_t pix, Float_t integral, Float_t fwhm, Float_t integralout, Float_t fwhmout, Float_t trigger_delay) {
  //
  //  Constructor overloaded II 
  //  
  //  Input variables:
  //  1. integral(out) = integration of the single phe response for inner 
  // (outer) pixels.
  //  2. fwhm(out) = width at half high of the single phe response for
  // inner (outer) pixels.
  //
  // trigger_delay: shift of signals towards later times in FADC, in order
  // to center the signals in a good range. It acts as a sort of delay of 
  // the signals (before being sent to the FADC) with respect to the trigger.
  //
  //  The procedure is the following: 
  //  1. some parameters of the trigger are set to default.   
  //     this parameters of the trigger may be changed
  //  3. Then the all signals are set to zero

  numpix=pix;
  
  fwhm_resp = fwhm; 
  integ_resp = integral; 
  fwhm_resp_outer = fwhmout; 
  integ_resp_outer = integralout; 

  cout<< "[MFadc]  Setting up the MFadc with this values "<< endl ; 
  cout<< "[MFadc]    - Inner pixels :  "<< endl ; 
  cout<< "[MFadc]       Response Area : "<<integral<<" adc counts"<< endl ; 
  cout<< "[MFadc]       Response FWHM : "<<fwhm<<" ns"<< endl ; 
  cout<< "[MFadc]    - Inner pixels :  "<< endl ; 
  cout<< "[MFadc]       Response Area : "<<integralout<<" adc counts"<< endl ; 
  cout<< "[MFadc]       Response FWHM : "<<fwhmout<<" ns"<< endl ; 
  
  //
  //    set up the response shape
  // 
  Int_t  i ;
  
  Float_t   sigma ; 
  Float_t   x, x0 ; 

  sigma = fwhm_resp / 2.35 ; 
  x0 = 3*sigma;
  
  fadc_time_offset = trigger_delay-x0; // ns


  Float_t   dX, dX2 ; 

  dX  = WIDTH_FADC_TIMESLICE / SUBBINS ; 
  dX2 = dX/2. ; 


  
  for (i=0; i< RESPONSE_SLICES_MFADC ; i++ ) {  

    x = i * dX + dX2 ; 
    
    //
    //   the value 1/(2*Pi*sigma^2) was introduced to normalize 
    //   the area at the input value. After this, the integral
    //   of the response will be integ_resp.
    //
    sing_resp[i] = integ_resp / sqrt(2*3.1415926*sigma*sigma)*  
       expf(-0.5 * (x-x0)*(x-x0) / (sigma*sigma) ) ; 

    //   
    //   The integral of the response above would be the sum of all
    //   sing_resp[i] values times the bin width WIDTH_RESPONSE_MFADC,
    //   and it would now equal "integ_resp". 
    //   We want however that our actual measurement, the sum of FADC 
    //   slices contents, is equal to integ_resp. Since in each FADC 
    //   slice we will put the content of just one response bin, and 
    //   there are a number SUBBINS of such response bins within 1 FADC 
    //   slice, the needed factor is then:
    //
    sing_resp[i] *= (WIDTH_RESPONSE_MFADC*SUBBINS);

  } 


  sigma = fwhm_resp_outer / 2.35 ; 
  x0 = 3*sigma ; 
  
  dX  = WIDTH_FADC_TIMESLICE / SUBBINS ; 
  dX2 = dX/2. ; 
  
  for (i=0; i< RESPONSE_SLICES_MFADC ; i++ ) {  

    x = i * dX + dX2 ; 
    
    //
    //   the value 1/(2*Pi*sigma^2) was introduced to normalize 
    //   the area at the input value After this, the integral
    //   of the response will be integ_resp.
    //
    sing_resp_outer[i] = integ_resp_outer / sqrt(2*3.1415926*sigma*sigma)*  
       expf(-0.5 * (x-x0)*(x-x0) / (sigma*sigma) ) ; 

    //   
    //   The integral of the response above would be the sum of all
    //   sing_resp[i] values times the bin width WIDTH_RESPONSE_MFADC,
    //   and it would now equal "integ_resp". 
    //   We want however that our actual measurement, the sum of FADC 
    //   slices contents, is equal to integ_resp. Since in each FADC 
    //   slice we will put the content of just one response bin, and 
    //   there are a number SUBBINS of such response bins within 1 FADC 
    //   slice, the needed factor is then:
    //  
    sing_resp_outer[i] *= (WIDTH_RESPONSE_MFADC*SUBBINS);
  } 

  //
  //    init the Random Generator for Electonic Noise
  //

  GenElec = new TRandom () ; 

  Reset();

  //
  //  set all pedestals to 0
  //
  
  for ( i =0 ; i <CAMERA_PIXELS ; i++ ) { 
    pedestal[i] = 0.0 ; 
  }

  cout<<" end of MFadc::MFadc()"<<endl;
}
  
void MFadc::Reset() { 
    //
    //  set all values of the signals to zero
    //  set the values of FADC slices that would be read after trigger to zero
    //
    memset(used, 0, CAMERA_PIXELS*sizeof(Bool_t));
    memset(output, 0, CAMERA_PIXELS*FADC_SLICES*sizeof(UChar_t));
    memset(output_lowgain, 0, CAMERA_PIXELS*FADC_SLICES*sizeof(UChar_t));
    // 
    // Added 15 01 2004, AM:
    //
    memset(sig, 0, (Int_t)(CAMERA_PIXELS*SLICES_MFADC*sizeof(Float_t)));
}
void MFadc::Fill( Int_t iPix, Float_t time, 
		  Float_t amplitude, Int_t isinner ) { 

    // AM, Jan 2004 : added delay to shift the signal peak to the desired
    // range in the FADC window (indicated through the trigger_delay command
    // in the camera input card.

  time += fadc_time_offset;

  if(isinner)
    Fill(iPix, time, amplitude);
  else
    FillOuter(iPix, time, amplitude);

}
void MFadc::Fill( Int_t iPix, Float_t time, Float_t amplitude ) { 
  
  //
  // fills the information about one single Phe in the Trigger class
  //
  // parameter is the number of the pixel and the time-difference to the
  // first particle
  //
  //

  Int_t i, ichan, ichanfadc ; 
  
  //
  //   first we have to check if the pixel iPix is used or not until now
  //   if this is the first use, reset all signal for that pixels
  // 
  if ( iPix > numpix ) {
    cout << " WARNING:  MFadc::Fill() :  iPix greater than Pixels in Camera = "
	 << numpix
	 << endl ;
    exit(987) ; 
  }

  if ( used[iPix] == FALSE ) {
    used [iPix] = TRUE ; 
    
    for (i=0; i < (Int_t) SLICES_MFADC; i++ ) {
      sig[iPix][i] = 0. ; 
    }
  }

  //
  //   then select the time slice to use (ican) 
  // 

  if ( time < TOTAL_TRIGGER_TIME+fadc_time_offset ) { 
    //
    //   determine the slices number assuming the WIDTH_RESPONSE_MFADC
    //   ichan marks the start of the pulse, in number of bins of width  
    //   WIDTH_RESPONSE_MFADC (2/3 of a ns), measured from the start of the 
    //   FADC.
    //

    ichan = (Int_t) ( time / ((Float_t) WIDTH_RESPONSE_MFADC )); 

    //
    //   putting the response slices in the right sig slices.
    //   Be carefull, because both slices have different widths. 
    //

    //
    // AM, Jan 2004: Replaced former FADC simulation (integration of signal)
    // with a more realistic one (measuring signal height at discrete points).
    //

    // We take the pulse height in the middle of FADC slices, we start in the
    // first such point after the time "time" (=ichan in response bins). Each
    // FADC slice corresponds to SUBBINS response bins (SUBBINS=5 by default).

    Int_t first_i =  Int_t(SUBBINS/2) - ichan%(Int_t)SUBBINS;
    first_i = first_i < 0 ? (Int_t)SUBBINS+first_i : first_i;


    for ( i = first_i ; i < (Int_t)RESPONSE_SLICES; i += (Int_t)SUBBINS) {	
      ichanfadc = (Int_t) ((ichan+i)/SUBBINS) ; 
      if ( ichanfadc < 0 )
	  continue;

      //
      // SLICES_MFADC is by default 48. sig[][] is not the true FADC, which
      // is filled from sig[][] in MFadc::TriggeredFadc()
      //
      if ( (ichanfadc) < (Int_t)SLICES_MFADC ) {  
	sig[iPix][ichanfadc] += (amplitude * sing_resp[i] )  ; 
      } 
    }

  }
  else {
    cout << "  WARNING!  Fadc::Fill " << time << "  out of TriggerTimeRange " 
	 << TOTAL_TRIGGER_TIME+fadc_time_offset << endl ; 
  }

}

void MFadc::FillOuter( Int_t iPix, Float_t time, Float_t amplitude ) { 
  
  //
  // fills the information about one single Phe in the Trigger class
  // for an outer pixel
  //
  // parameter is the number of the pixel and the time-difference to the
  // first particle
  //
  //

  Int_t i, ichan, ichanfadc ; 
  
  //
  //   first we have to check if the pixel iPix is used or not until now
  //   if this is the first use, reset all signal for that pixels
  // 
  if ( iPix > numpix ) {
    cout << " WARNING:  MFadc::FillOuter() :  iPix greater than CAMERA_PIXELS"
	 << endl ;
    exit(987) ; 
  }

  if ( used[iPix] == FALSE ) {
    used [iPix] = TRUE ; 
    
    for (i=0; i < (Int_t) SLICES_MFADC; i++ ) {
      sig[iPix][i] = 0. ; 
    }
  }

  //
  //   then select the time slice to use (ican) 
  // 


  if ( time < TOTAL_TRIGGER_TIME+fadc_time_offset ) { 
    //
    //   determine the slices number assuming the WIDTH_RESPONSE_MFADC
    //
    ichan = (Int_t) ( time / ((Float_t) WIDTH_RESPONSE_MFADC )); 

    //
    //   putting the response slices in the right sig slices.
    //   Be carefull, because both slices have different widths. 
    //

    //
    // AM, Jan 2004: Replaced former FADC simulation (integration of signal)
    // with a more realistic one (measuring signal height at discrete points).
    //

    // We take the pulse height in the middle of FADC slices, we start in the
    // first such point after the time "time" (=ichan in response bins). Each
    // FADC slice corresponds to SUBBINS response bins (SUBBINS=5 by default).

    Int_t first_i =  Int_t(SUBBINS/2) - ichan%(Int_t)SUBBINS;
    first_i = first_i < 0 ? (Int_t)SUBBINS+first_i : first_i;

    for ( i = first_i ; i < (Int_t)RESPONSE_SLICES; i += (Int_t)SUBBINS) {
      ichanfadc = (Int_t) ((ichan+i)/SUBBINS) ; 

      if ( ichanfadc < 0 )
	  continue;

      if ( (ichanfadc) < (Int_t)SLICES_MFADC ) {  
	sig[iPix][ichanfadc] += (amplitude * sing_resp_outer[i] )  ; 
      } 
    }

  }
  else {
    cout << "  WARNING!  Fadc::FillOuter " << time << "  out of TriggerTimeRange " 
	 << TOTAL_TRIGGER_TIME+fadc_time_offset << endl ; 
  }

}

void MFadc::Set( Int_t iPix, Float_t resp[(Int_t) SLICES_MFADC]) { 
  
  //
  // Sets the information about fadc reponse from a given array
  //
  // parameter is the number of the pixel and the values to be set
  //
  //

  Int_t i ; 
  
  //
  //   first we have to check if the pixel iPix is used or not until now
  //   if this is the first use, reset all signal for that pixels
  // 
  if ( iPix > numpix ) {
    cout << " WARNING:  MFadc::Fill() :  iPix greater than CAMERA_PIXELS"
	 << endl ;
    exit(987) ; 
  }

  if ( used[iPix] == FALSE ) {
    used [iPix] = TRUE ; 
    
    for (i=0; i < (Int_t)SLICES_MFADC; i++ ) {
      sig[iPix][i] = 0. ; 
    }
  }
  for ( i = 0 ; i<(Int_t)SLICES_MFADC; i++ ) {
    sig[iPix][i] = resp[i] ; 
  }

}

void MFadc::AddSignal( Int_t iPix, Float_t resp[(Int_t) SLICES_MFADC]) { 
  
  //
  // Adds signals to the fadc reponse from a given array
  //
  // parameter is the number of the pixel and the values to be added
  //
  //

  Int_t i ; 
  
  //
  //   first we have to check if the pixel iPix is used or not until now
  //   if this is the first use, reset all signal for that pixels
  // 
  if ( iPix > numpix ) {
    cout << " WARNING:  MFadc::Fill() :  iPix greater than CAMERA_PIXELS"
	 << endl ;
    exit(987) ; 
  }

  if ( used[iPix] == FALSE ) {
    used [iPix] = TRUE ; 
    
    for (i=0; i < (Int_t)SLICES_MFADC; i++ ) {
      sig[iPix][i] = 0. ; 
    }
  }
  for ( i = 0 ; i<(Int_t)SLICES_MFADC; i++ ) {
    sig[iPix][i] += resp[i] ; 
  }

}

void MFadc::SetPedestals( Int_t ped) { 
  //  It sets pedestal for each pixel flat randomly dstributed between 0 and ped
  //  It uses the instance of TRandom GenElec.

  Int_t i;

  for(i=0;i<numpix;i++){
    pedestal[i]= (Float_t)(ped* GenElec->Rndm());
  }
}

void MFadc::SetPedestals(  Float_t *ped) { 
  //  It sets pedestal for each pixel from ped array

  Int_t i;

  for(i=0;i<numpix;i++){
    pedestal[i]= ped[i];
  }
}
  

void MFadc::Baseline(){
  //  
  //  It simulates the AC behaviour

  int i,j;
  Float_t baseline;

  for(j=0;j<numpix;j++){
    baseline=0.0;
    for(i=0;i<(Int_t) SLICES_MFADC;i++){
      baseline+=sig[j][i];
    }
    baseline=baseline/SLICES_MFADC;
    for(i=0;i<(Int_t) SLICES_MFADC;i++){
      sig[j][i]=-baseline;
    }
  }
}

void MFadc::Pedestals(){
  // 
  //  It shifts the FADC contents their pedestal values
  //  It shifts the values in the analog signal, 
  //  therefore it has to be done before getting FADC output
  //

  Int_t i, j;

  for(i=0;i<numpix;i++)
    for(j=0;j<(Int_t)SLICES_MFADC;j++)
        sig[i][j]+=pedestal[i];
  //
  // AM 15 01 2003: Formerly the above operation was performed only 
  // for pixels in which used[] was true. But to run camera with no noise
  // and get the right baseline on the pixels with no C-photons, we have 
  // to do it for all pixels.
  //


}

void MFadc::Offset(Float_t offset, Int_t pixel){
  // 
  //  It puts an offset in the FADC signal
  //

  int i,j;
  float fdum;
  TRandom *GenOff = new TRandom () ; 

  if (offset<0) {
    //  It cannot be, so the program assumes that 
    //  it should generate random values for the offset.

    if (pixel<0) {
      // It does not exist, so all pixels will have the same offset

      for(i=0;i<numpix;i++){
	if (used[i]){
	  fdum=(10*GenOff->Rndm());
	  for(j=0;j<(Int_t) SLICES_MFADC;j++)
	    sig[i][j]+=fdum;
	}
      }
    } else {
      // The program will put the specifies offset to the pixel "pixel".

      if (used[pixel]){
	fdum=(10*GenOff->Rndm());
	for(j=0;j<(Int_t) SLICES_MFADC;j++)
	  sig[pixel][j]+=fdum;
	}

    }
  }else {
    //  The "offset" will be the offset for the FADC

    if (pixel<0) {
      // It does not exist, so all pixels will have the same offset

      for(i=0;i<numpix;i++){
	if (used[i]){
	  for(j=0;j<(Int_t) SLICES_MFADC;j++)
	    sig[i][j]+=offset;
	}
      }
    } else {
      // The program will put the specifies offset to the pixel "pixel".

      if (used[pixel]){
	for(j=0;j<(Int_t) SLICES_MFADC;j++)
	  sig[pixel][j]+=offset;
      }
    }
  }
  delete GenOff;
}

void MFadc::SetElecNoise(Float_t value){

  UInt_t i;
 
  cout<<"MFadc::SetElecNoise ... generating database for electronic noise."
      <<endl;

  for (i=0;i<(UInt_t (SLICES_MFADC))*1001;i++){
    noise[i]=GenElec->Gaus(0., value  );
      }

  cout<<"MFadc::SetElecNoise ... done"<<endl;

}

void MFadc::ElecNoise(Float_t value) {
  // ============================================================
  //
  //    adds the noise due to optronic and electronic 
  //    to the signal
  //
  UInt_t startslice;

    for ( Int_t i = 0 ; i < numpix; i++) {
	//
	//  but at the beginning we must check if this pixel is
	//  hitted the first time
	//

      startslice=GenElec->Integer(((Int_t)SLICES_MFADC)*1000);

	if ( used[i] == FALSE ) {
	    used [i] = TRUE ; 
	    
      	    memcpy( (Float_t*)&sig[i][0],
		    (Float_t*)&noise[startslice], 
		    ((Int_t) SLICES_MFADC)*sizeof(Float_t));
      
	  for ( Int_t is=0 ; is< (Int_t)SLICES_MFADC ; is++ ) {

	  }
	}
	//      
	//  Then the noise is introduced for each time slice
	//
	else
	  for ( Int_t is=0 ; is< (Int_t)SLICES_MFADC ; is++ ) {
	    
	    sig[i][is] += noise[startslice+is] ; 
	    
	  }
    }
}

void MFadc::SetDigitalNoise(Float_t value){

  UInt_t i;
  Float_t xrdm;
 
  cout<<"MFadc::SetDigitalNoise ... generating database for electronic noise."
      <<endl;

  for (i=0;i<UInt_t(SLICES_MFADC*1001);i++){
    xrdm=GenElec->Gaus(0., value);
    digital_noise[i]=(xrdm>0?Int_t(xrdm+0.5):Int_t(xrdm-0.5));    
  }
  
  cout<<"MFadc::SetDigitalNoise ... done"<<endl;

}

void MFadc::DigitalNoise() {
  // ============================================================
  //
  //    adds the noise due to optronic and electronic 
  //    to the signal
  //
  UInt_t startslice;

    for ( Int_t i = 0 ; i < numpix; i++) {

      if ( used[i] == TRUE ) {
	startslice=GenElec->Integer((Int_t) SLICES_MFADC*999);
	//      
	//  Then the noise is introduced for each time slice
	//
	for ( Int_t is=0 ; is< FADC_SLICES; is++ ) {
	  
	  if(digital_noise[startslice+is]+Int_t(output[i][is])<0) 
	     output[i][is] = 0;
	  else
	    output[i][is] = 
	      (digital_noise[startslice+is]+Int_t(output[i][is])>255 ?
	       255 :
	       UChar_t(digital_noise[startslice+is]+Int_t(output[i][is])));
	  if(digital_noise[startslice+FADC_SLICES+is]+Int_t(output_lowgain[i][is])<0) 
	    output_lowgain[i][is] = 0;
	  else
	    output_lowgain[i][is] = 
	      (digital_noise[startslice+FADC_SLICES+is]
	       +Int_t(output_lowgain[i][is])>255?
	       255:
	       UChar_t(digital_noise[startslice+FADC_SLICES+is]
		       +Int_t(output_lowgain[i][is])));
	}
      }
    }
}


void MFadc::Scan() {
  

  for ( Int_t ip=0; ip<numpix; ip++ ) {
    
    if ( used[ip] == kTRUE ) {

      printf ("Pid %3d",  ip ) ; 

      for ( Int_t is=0 ; is < (Int_t)SLICES_MFADC; is++ ) {

	if ( sig[ip][is] > 0. ) {
	  printf (" %4.1f/", sig[ip][is] ) ;
	}
	else {
	  printf ("----/" ) ;
	}
      }
      
      printf ("\n"); 

    }
  }
  
} 

void MFadc::Scan(Float_t time) {
  
  //
  //    first of all we subtract from the time a offset (8 ns) 
  // 
  
  Float_t t ; 

  (0 > time - TIME_BEFORE_TRIGGER)? t=fadc_time_offset: t=(time-TIME_BEFORE_TRIGGER+fadc_time_offset) ; // to show also the start of the pulse before the trigger time

  if ( t < 0. ) {
    cout << " WARNING!! FROM MFADC::SCAN(t) " << endl ; 
    exit (776) ;  
  }

  //
  //  calculate the first slice to write out
  // 
  
  Int_t  iFirstSlice ; 

  iFirstSlice = (Int_t) ( t /  WIDTH_FADC_TIMESLICE ) ; 

  for ( Int_t ip=0; ip<numpix; ip++ ) {
    
    if ( used[ip] == kTRUE ) {

      printf ("Pid %3d",  ip ) ; 

      for ( Int_t is=iFirstSlice ; is < (iFirstSlice+15); is++ ) {
	printf (" %5.2f /", sig[ip][is] ) ; 
      }
      
      printf ("\n"); 

    }
  }  
} 

void MFadc::GetResponse( Float_t *resp ) {
  // ============================================================
  //
  //    puts the standard response function into the array resp
  
  for ( Int_t i=0; i< RESPONSE_SLICES; i++ ) {

    resp[i] = sing_resp[i] ; 
  }
}

void MFadc::GetPedestals( Float_t *offset) {
  // ============================================================
  //
  //    puts the pedestal values into the array offset
  
  for ( Int_t i=0; i< numpix; i++ ) {

    offset[i] = pedestal[i] ; 
  }
}

Float_t MFadc::GetPedestalNoise( Int_t pix, Int_t ishigh) {
  // ============================================================
  //
  //    computes the pedestal sigma for channel pix

  Float_t sigma=0;
  UChar_t value=0;
  
  Float_t factor;
  UInt_t startslice;

  factor=(ishigh?1.0:high2low_gain);

  startslice=GenElec->Integer((Int_t) SLICES_MFADC*999);

  for ( Int_t is=0; is <  (Int_t)SLICES_MFADC ; is++ ) {
    if (pedestal[pix]+(sig[pix][is]-pedestal[pix])/factor>0.0){
      value=(pedestal[pix]+(sig[pix][is]-pedestal[pix])/factor > 255. 
	     ? 255 
	     :UChar_t(pedestal[pix]+(sig[pix][is]-pedestal[pix])/factor+0.5));

      if(Int_t(value)+digital_noise[startslice+is]<0.0)
	 value=0;
      else
	value=(Int_t(value)+digital_noise[startslice+is]>255
	       ?255
	       :UChar_t(Int_t(value)+digital_noise[startslice+is]));
    }
    else {
      value= 0;
      if(Int_t(value)+digital_noise[startslice+is]<0.0)
	 value=0;
      else
	value=(Int_t(value)+digital_noise[startslice+is]>255
	       ?255
	       :UChar_t(Int_t(value)+digital_noise[startslice+is]));
    }
    sigma+=((Float_t)value-pedestal[pix])*((Float_t)value-pedestal[pix]);

  }

  sigma=sqrt(sigma/(SLICES_MFADC-1));

  return sigma;
}

void MFadc::TriggeredFadc(Float_t time) {
  
  //
  //  calculate the first slice to write out, according to trigger time: 
  // 
  
  Int_t iFirstSlice ; 
  Int_t i;

  //
  // We had 0.5 for the correct rounding:
  //
  iFirstSlice = (Int_t) ( 0.5 + time /  WIDTH_FADC_TIMESLICE ) ; 

  for ( Int_t ip=0; ip<numpix; ip++ ) {
    
      if ( used[ip] == kTRUE ) { 
	  i=0;
	  for ( Int_t is=iFirstSlice ; is < (iFirstSlice+FADC_SLICES) ; is++ ) 
	  {
	      if (is< (Int_t)SLICES_MFADC && sig[ip][is]>0.0)
	      {
	    
		  output[ip][i]=(sig[ip][is] > 255. ? 255 :(UChar_t) (sig[ip][is]+0.5));
		  output_lowgain[ip][i]= 
		      (Int_t)(pedestal[ip]+(sig[ip][is]-pedestal[ip])/high2low_gain+0.5) > 255. ? 255 :
		      (UChar_t)(pedestal[ip]+(sig[ip][is]-pedestal[ip])/high2low_gain+0.5);
		  i++;
	    
	      }
	      else if(sig[ip][is]>=0.0)
	      {
		  output[ip][i]= (UChar_t)(pedestal[ip]+0.5);
		  output_lowgain[ip][i]= (UChar_t)(pedestal[ip]+0.5);
		  i++;
	      }
	      else 
	      {
		  output[ip][i]= 0;
		  if((pedestal[ip]+(sig[ip][is]-pedestal[ip])/high2low_gain)<0)
		      output_lowgain[ip][i]= 0;
		  else
		      output_lowgain[ip][i]=(UChar_t)(pedestal[ip]+(sig[ip][is]-pedestal[ip])/high2low_gain+0.5);
		  i++;
	      }
	  }
      }
      else  
	  // Pixels with no C-photons in the case that camera is run with
	  // no noise (nor NSB neither electronic)
      {
	  for ( Int_t i=0 ; i < FADC_SLICES ; i++ ) 
	  {
	      output[ip][i]= (UChar_t)(pedestal[ip]+0.5);
	      output_lowgain[ip][i]= (UChar_t)(pedestal[ip]+0.5);
	  } 
      }
  }

} 

void MFadc::ShowSignal (MMcEvt *McEvt, Float_t trigTime) { 
  // ============================================================
  //
  //  This method is used to book the histogram to show the signal in 
  //  a special gui frame (class MGTriggerSignal). After the look onto the
  //  signals for a better understanding of the things we will expect 
  //  the gui frame and all histogramms will be destroyed.   
  //
  
  //
  //  first of all create a list of the histograms to show
  //
  //  take only that one with a entry

  TH1F *hist ; 
  Char_t dumm[10]; 
  Char_t name[256]; 
  
  TObjArray  *AList ;
  AList = new TObjArray(10) ; 

  // the list of analog signal histograms
  // at the beginning we initalise 10 elements
  // but this array expand automaticly if neccessay
  
  Int_t ic = 0 ; 
  for ( Int_t i=0 ; i < numpix; i++  ) {
    if ( used [i] == TRUE ) {

      sprintf (dumm, "FADC_%d", i ) ; 
      sprintf (name, "fadc signal %d", i ) ; 
      
      hist = new TH1F(dumm, name, SLICES_MFADC, fadc_time_offset, TOTAL_TRIGGER_TIME+fadc_time_offset); 
      //
      //  fill the histogram
      //
      
      for (Int_t ibin=1; ibin <=(Int_t)SLICES_MFADC; ibin++) {
	hist->SetBinContent (ibin, sig[i][ibin-1]) ;
      }

      //      hist->SetMaximum( 5.);
      //      hist->SetMinimum(-10.);
      hist->SetStats(kFALSE); 
  
      //      hist->SetAxisRange(0., 80. ) ; 
      
      AList->Add(hist) ; 
      
      ic++ ; 
    }
  }  

  //
  //   create the Gui Tool
  //
  //
  
  new MGFadcSignal(McEvt,
  		   AList,
		   trigTime, 
  		   gClient->GetRoot(), 
		   gClient->GetRoot(), 
  		   400, 400 ) ; 
   
  //
  //   delete the List of histogramms
  //
  AList->Delete() ; 
  
  delete AList ; 
}

UChar_t MFadc::GetFadcSignal(Int_t pixel, Int_t slice){

  //  It returns the analog signal for a given pixel and a given FADC
  //  time slice which would be read.

  return (output[pixel][slice]);
}

 
UChar_t MFadc::GetFadcLowGainSignal(Int_t pixel, Int_t slice){
 
   //  It returns the analog signal for a given pixel and a given FADC
   //  time slice which would be read.
 
   return (output_lowgain[pixel][slice]);
}



