/***********************************************************************
* Filename: LOX.h
* Abstract: Level Of eXpression

* Version: 1.8
* Author: Zhang Zhang  (zhangzhang@big.ac.cn)
* Date: February 4, 2012
* Note: (1) Remove the bug for calculating p-values.
        (2) Change the first column name to be outputted, "ID" into "Gene".
        (3) Output p-values files for methodologies.  

* Version: 1.7
* Author: Zhang Zhang  (zhangzhang.cn@gmail.com)
* Date: July 26, 2011
* Note: Add an option to output posterior distribution for each gene.

* Version: 1.6
* Author: Zhang Zhang  (zhang.zhang@kaust.edu.sa)
* Date: Jun. 3, 2011
* Note: Remove the bug for calculating p-values.

* Version: 1.5
* Author: Zhang Zhang  (zhang.zhang@kaust.edu.sa)
* Date: Mar. 8, 2011
* Note: (1) Remove the bug when first column count=0, resulting from locating
        the lowest value and normarlization (getPQResults).
		(2) Provide more specifica error message for the input file (setHeader
		and Run). 

* Version: 1.4
* Author: Zhang Zhang  (zhang.zhang@kaust.edu.sa)
* Date: Nov. 9, 2010
* Note: Remove the bug for normalizing of p.

* Version: 1.3
* Author: Zhang Zhang  (zhang.zhang@kaust.edu.sa)
* Date: Nov. 1, 2010
* Note: Set q=1 for any input file with only one methodology.

* Version: 1.2
* Author: Zhang Zhang  (zhang.zhang@kaust.edu.sa)
* Date: July, 2010
* Note: (1) Accommodate input file with only one methodology;
        (2) Update the LOX reference published in Bioinformatics.

* Version: 1.1
* Author: Zhang Zhang  (zhang.zhang@kaust.edu.sa)
* Date: April, 2010
* Note: Output pvalue files for treatments

* Version: 1.0
* Author: Zhang Zhang  (zhang.zhang@yale.edu)
* Date: August 27, 2009

* Note: 
LOX is distributed as open-source software and licensed under the GNU 
General Public License (Version 3; http://www.gnu.org/licenses/gpl.txt), 
in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
See the GNU General Public License for more details. Commercial use of LOX 
requires a special contract.
************************************************************************/

#pragma warning(disable:4786)		//Disable warning when using vector

#if !defined(LOX_H)
#define  LOX_H

#define ABBRNAME   "LOX"	//Program short name
#define FULLNAME   "Level Of eXpression"	//Program full name
#define FUNCTION   "Inferring level of expression from diverse methods of census sequencing"
#define VERSION    "1.8"
#define LASTUPDATE "February 4, 2012"
#define REFERENCE  "Zhang, Z., Lopez-Giraldez, F. and Townsend, J.P. (2010) LOX: inferring level of expression from diverse methods of census sequencing, Bioinformatics, 26(15):1918-1919."

#define UNEXPECTED_ERROR "Unexpected error. Please contact Zhang Zhang at zhangzhang.cn@gmail.com."

#include "base.h"

using namespace std;

typedef vector<double> DoubleVector;

//LOX header, including methodologies and treatments
class LOXHeader {
public:
	//Method name
	string method;
	//Method's ID
	int methodNum;
	//Treatment name
	string treatment;
	//Treatment's ID
	int treatmentNum;
	
	LOXHeader() {}

	//Construction function
	LOXHeader(string m, int mn, string t, int tn) {
		method = m;
		methodNum = mn;
		treatment = t;
		treatmentNum = tn;
	}
};

class LOXNode {
public:
	string ID;	
	string CommonName;
	vector<double> Nodes;   //double: in case of nodes with exetreme large values
	vector<double> NodesOrderByTreatment;
	vector<double> NodesOrderByMethod;
	string ErrorMsg;

	double BestLogLikelihood;

	//Results: 0=Treatments, 1=Methods
	vector<DoubleVector> Ratios;
	// -97.5 Confidence Interval
	vector<DoubleVector> RatiosLowCI;
	// +97.5 Confidence Interval
	vector<DoubleVector> RatiosHighCI;
	//Acceptance Ratio
	vector<double> AcceptanceRatio; 
	vector<bool> Tuned;		
	vector<DoubleVector> MLERatios;

	//PValues
	vector<double> PValuesTreatment;
	vector<double> PValuesMethodology;
	
	LOXNode() {}

	LOXNode(string id, string common_name, vector<double> nodes, string msg = "") {
		this->ID = id;
		this->CommonName = common_name;
		this->Nodes = nodes;
		this->ErrorMsg = msg;
	}

	~LOXNode() {
		Nodes.clear();
	}
};

class LOX : public Base {
	public:
		LOX();
		~LOX();

		int Run(int argc, const char* argv[]);

		//Set experimental methods and states
		int setHeader();
		int setExpressionNodes();
		int showParameterSettings();

		int MCMC(unsigned long tally);
		int getPQResults(LOXNode& lox, vector<double> CountByTreatmentOrMethod, vector<DoubleVector> tally, vector<double> best, double AcceptanceRatio, bool Tuned);

		int readDatFile(string filename);
		int outputResult();
		int outputPValues();

		double calculateLikelihood(LOXNode lox, vector<double>& p, vector<double>& q);
		int randomPQ(vector<double>& pORq, vector<double> step);
		int randomStepPQ(int MaxTuningDepth, double acceptance_ratio, vector<double>& step, bool& tuned);

	protected:
		//Parse input parameters
		bool parseParameter(int argc, const char* argv[]);
		void showHelpInfo();

		//Three-row Headers 
		vector<LOXHeader> HeadersVector;
		//Names of methods
		vector<string> MethodsVector;
		//Names of treatments
		vector<string> TreatmentsVector;
		
		//Genes' Nodes
		vector<LOXNode> NodesVector;
		//Sum for each column
		vector<double> ColumnSumsVector;
		//Sum for each treatment
		vector<double> TreatmentSumsVector;
		//Sum for each method
		vector<double> MethodSumsVector;

	private:
		string InputFileName;
		string LOXOutputFileName;
		string MetOutputFileName;
		int NumOfColumn;
		vector<string> DatLines;
		bool isOutputMethodsResults;
		bool isShowMLERatios;
		bool isOutputPosterior;

		long ChainSampleSize;
		long BurnIn;
		long SamplingPeriod;
		long MaxTuningDepth;
		double LowerAcceptance;
		double UpperAcceptance;

};

#endif

