/********************************************************************************************
*********************************************************************************************/
void rate4siteGL::printRatesML(ostream& out, const Vdouble & rate2print) {
	out<<"#Rates were calculated using Maximum Likelihood"<<endl;
	out<<"#SEQ: The presence(1) or Absence(0) in the reference sequence."<<"Displayed on sequence "<<_refSeq->name()<<endl;
	out<<"#SCORE: The conservation scores. lower value = higher conservation."<<endl;
	out<<"#MSA DATA: The number of aligned sequences having an amino acid (non-gapped) from the overall number of sequences at each position."<<endl;
	out<<endl;
	out<<"========================================================================================================================================================="<<endl;
	out<<"#POS"<<"\t"<<"SEQ"<<"\t"<<"SCORE"<<"\t"<<"MSA DATA"<<endl; // note position start from 1.
	out<<"========================================================================================================================================================="<<endl;

#ifdef unix
	for (int pos=0; pos < _sc.seqLen(); ++pos) {
		out<<pos+1<<"\t"<<_refSeq->getAlphabet()->fromInt((*_refSeq)[pos])<<"\t"<<setprecision(7)<<rate2print[pos]<<"\t";
		out<<_sc.numberOfSequencesWithoutGaps(pos)<<"/"<<_sc.numberOfSeqs()<<endl; // note position start from 1.
	}
#else
	for (int pos=0; pos < _sc.seqLen(); ++pos) {
		out<<left<<pos+1<<left<<"\t"<<_refSeq->getAlphabet()->fromInt((*_refSeq)[pos])<<"\t";
		out<<left<<setprecision(7)<<fixed<<rate2print[pos]<<"\t";
		out<<right<<_sc.numberOfSequencesWithoutGaps(pos)<<"/"<<_sc.numberOfSeqs()<<endl; // note position start from 1. 
	}
#endif
}
/********************************************************************************************
*********************************************************************************************/
void rate4siteGL::printRatesBayes(ostream& out, const Vdouble & rate2print) {
	out<<"# Rates were calculated using the expectation of the posterior rate distribution"<<endl;
	out<<"# Prior distribution is Gamma with "<<gainLossOptions::_numberOfRateCategories<<" discrete categories"<<endl;
	out<<"# SEQ: The presence(1) or Absence(0) in the reference sequence."<<"Displayed on sequence "<<_refSeq->name()<<endl;
	out<<"# SCORE: The conservation scores. lower value = higher conservation."<<endl;
	out<<"# QQ-INTERVAL: the confidence interval for the rate estimates. The default interval is 25-75 percentiles"<<endl;
	out<<"# STD: the standard deviation of the posterior rate distribution."<<endl;
	out<<"# MSA DATA: The number of aligned sequences having an amino acid (non-gapped) from the overall number of sequences at each position."<<endl;
	MDOUBLE AlphaRate = getRateAlpha(_sp->distr());
	//if(dynamic_cast<gammaDistribution*>(_sp->distr()) ) {
	//	AlphaRate = static_cast<gammaDistribution*>(_sp->distr())->getAlpha();
	//}
	//if(dynamic_cast<generalGammaDistributionPlusInvariant*>(_sp->distr())){
	//	AlphaRate = static_cast<generalGammaDistributionPlusInvariant*>(_sp->distr())->getAlpha();
	//}
	//if(dynamic_cast<gammaDistributionFixedCategories*>(_sp->distr())){
	//	AlphaRate = static_cast<gammaDistributionFixedCategories*>(_sp->distr())->getAlpha();
	//}
	out<<"# The alpha parameter "<<AlphaRate<<endl;
	int k=0;
	while (k < _sp->categories()){
		out<<"# sp.rates(j)  j= " <<k<<"\t"<<_sp->rates(k)<<"\t"<<_sp->ratesProb(k)<<endl;
		k++;
	}		


	out<<endl;
	out<<"========================================================================================================================================================="<<endl;
	out<<"#POS"<<"\t"<<"SEQ"<<"\t"<<"SCORE"<<"\t"<<"QQ-INTERVAL"<<"\t"<<"STD"<<"\t"<<"MSA DATA"<<endl; // note position start from 1.
	out<<"========================================================================================================================================================="<<endl;

#ifdef unix	
	for (int pos=0; pos < _sc.seqLen(); ++pos) {
		out<<pos+1<<"\t"<<_refSeq->getAlphabet()->fromInt((*_refSeq)[pos])<<"\t"<<setprecision(7)<<rate2print[pos]<<"\t";
		out<<"["<<setprecision(4)<<_BayesianLowerBound[pos]<<","<<setprecision(4)<<_BayesianUpperBound[pos]<<"]"<<"\t";
		out<<setprecision(4)<<_BayesianSTD[pos]<<"\t";
		out<<_sc.numberOfSequencesWithoutGaps(pos)<<"/"<<_sc.numberOfSeqs()<<endl; // note position start from 1.
	}
#else
	for (int pos=0; pos < _sc.seqLen(); ++pos) {
		out<<left<<pos+1;
		out<<left<<"\t"<<_refSeq->getAlphabet()->fromInt((*_refSeq)[pos])<<"\t";
		out<<left<<setprecision(7)<<fixed<<rate2print[pos]<<"\t";
		out<<right<<"["<<setprecision(4)<<left<<_BayesianLowerBound[pos]<<","<<setprecision(4)<<right<<_BayesianUpperBound[pos]<<"]"<<"\t";
		out<<right<<setprecision(4)<<_BayesianSTD[pos];
		out<<right<<"\t"<<_sc.numberOfSequencesWithoutGaps(pos)<<"/"<<_sc.numberOfSeqs()<<endl; // note position start from 1.
	}
#endif
}
/********************************************************************************************
*********************************************************************************************/
void rate4siteGL::printAveAndStd(ostream& out) {
	out<<"#Average = "<<_ave<<endl;
	out<<"#Standard Deviation = "<<_std<<endl;
}
/********************************************************************************************
computeAveAndStd
*********************************************************************************************/
void rate4siteGL::computeAveAndStd(){
	MDOUBLE sum = 0;
	MDOUBLE sumSqr=0.0;
	for (int i=0; i < _sc.seqLen(); ++i) {
		sum+=_rate[i];
		sumSqr+=(_rate[i]*_rate[i]);
	}
	_ave = sum/_sc.seqLen();
	_std= sumSqr-(sum*sum/_sc.seqLen());
	_std /= (_sc.seqLen()-1.0);
	_std = sqrt(_std);
	if (((_ave<1e-9)) && (_ave>(-(1e-9)))) _ave=0;
	if ((_std>(1-(1e-9))) && (_std< (1.0+(1e-9)))) _std=1.0;
}
/********************************************************************************************
normalizeRates
*********************************************************************************************/
void rate4siteGL::normalizeRates() {
	int i=0;
	if (_std==0) errorMsg::reportError(" std = 0 in function normalizeRates",1);
	_normalizedRates.resize(_sc.seqLen(),0.0);
	for (i=0;i<_normalizedRates.size();++i) {
		_normalizedRates[i]=(_rate[i]-_ave)/_std;
	}

	if (gainLossOptions::_rateEstimationMethod == gainLossOptions::ebExp) {
		for (int k=0; k < _sc.seqLen(); ++k) {
			_BayesianUpperBound[k] = (_BayesianUpperBound[k] - _ave)/_std;
			_BayesianLowerBound[k] = (_BayesianLowerBound[k] - _ave)/_std;
			_BayesianSTD[k] = (_BayesianSTD[k])/_std;
		}
	}
	_ave = 0.0;
	_std = 1.0;
}
