<commit_before>package dr.app.bss;

import java.io.Serializable;

import dr.app.beagle.evomodel.branchmodel.BranchModel;
import dr.app.beagle.evomodel.branchmodel.HomogeneousBranchModel;
import dr.app.beagle.evomodel.sitemodel.GammaSiteRateModel;
import dr.app.beagle.evomodel.substmodel.EmpiricalAminoAcidModel;
import dr.app.beagle.evomodel.substmodel.FrequencyModel;
import dr.app.beagle.evomodel.substmodel.GTR;
import dr.app.beagle.evomodel.substmodel.GY94CodonModel;
import dr.app.beagle.evomodel.substmodel.HKY;
import dr.app.beagle.evomodel.substmodel.TN93;
import dr.evolution.coalescent.CoalescentSimulator;
import dr.evolution.coalescent.ConstantPopulation;
import dr.evolution.coalescent.DemographicFunction;
import dr.evolution.coalescent.ExponentialGrowth;
import dr.evolution.datatype.AminoAcids;
import dr.evolution.datatype.Codons;
import dr.evolution.datatype.Nucleotides;
import dr.evolution.sequence.Sequence;
import dr.evolution.util.Taxa;
import dr.evolution.util.Units;
import dr.evomodel.branchratemodel.BranchRateModel;
import dr.evomodel.branchratemodel.DiscretizedBranchRates;
import dr.evomodel.branchratemodel.StrictClockBranchRates;
import dr.evomodel.sitemodel.SiteModel;
import dr.evomodel.substmodel.Blosum62;
import dr.evomodel.substmodel.EmpiricalRateMatrix;
import dr.evomodel.tree.TreeModel;
import dr.evoxml.TaxaParser;
import dr.inference.distribution.ExponentialDistributionModel;
import dr.inference.distribution.InverseGaussianDistributionModel;
import dr.inference.distribution.LogNormalDistributionModel;
import dr.inference.distribution.ParametricDistributionModel;
import dr.inference.model.Parameter;
import dr.inferencexml.distribution.DistributionModelParser;
import dr.inferencexml.distribution.InverseGaussianDistributionModelParser;
import dr.inferencexml.distribution.LogNormalDistributionModelParser;

/**
 * @author <NAME>
 * @version $Id$
 */
@SuppressWarnings("serial")
public class PartitionData implements Serializable {

	public PartitionData() {
	}// END: Constructor

	public int from = 1;
	public int to = 1000;
	public int every = 1;

	public int createPartitionSiteCount() {
		return ((to - from) / every) + 1;
	}
	
	public void resetIdrefs() {
		resetClockModelIdref();
		resetFrequencyModelIdref();
		resetSiteRateModelIdref();
		resetSubstitutionModelIdref();
		resetTreeModelIdref();
		resetDemographicModelIdref();
		resetTaxaIdref();
	}

	// /////////////////////////
	// ---DEMOGRAPHIC MODEL---//
	// /////////////////////////

	public int demographicModelIndex = 0;
	
	public String demographicModelIdref = Utils.DEMOGRAPHIC_MODEL;

	public void resetDemographicModelIdref() {
		this.demographicModelIdref = Utils.DEMOGRAPHIC_MODEL;
	}
	
    public static String[] demographicModels = {
    	"No Model (user-specified tree)",
    	"Constant Population",
        "Exponential Growth (Growth Rate)",
        "Exponential Growth (Doubling Time)"
//        "Logistic Growth (Growth Rate)",
//        "Logistic Growth (Doubling Time)",
//        "Expansion (Growth Rate)",
//        "Expansion (Doubling Time)",
        };
	
	public static String[] demographicParameterNames = new String[] {
	        "Population Size", // Constant Population
			"Population Size", // Exponential Growth (Growth Rate)
			"Growth Rate", // Exponential Growth (Growth Rate)
			"Population Size", // Exponential Growth (Doubling Time)
			"Doubling Time" // Exponential Growth (Doubling Time)
//			"Population Size", // Logistic Growth (Growth Rate)
//			"Growth Rate", // Logistic Growth (Growth Rate)
//			"Logistic Shape (Half-life)", // Logistic Growth (Growth Rate)
//			"Population Size", // Logistic Growth (Doubling Time)
//			"Doubling Time", // Logistic Growth (Doubling Time)
//			"Logistic Shape (Half-life)", // Logistic Growth (Doubling Time)
//			"Population Size", // Expansion (Growth Rate)
//			"Ancestral Proportion", // Expansion (Growth Rate)
//			"Growth Rate", // Expansion (Growth Rate)
//			"Population Size", // Expansion (Doubling Time)
//			"Ancestral Proportion", // Expansion (Doubling Time)
//			"Doubling Time", // Expansion (Doubling Time)
	};	
	
	public static int[][] demographicParameterIndices = {
		    {  }, // No model
			{ 0 }, // Constant Population
			{ 1, 2 }, // Exponential Growth (Growth Rate)
			{ 3, 4 }// Exponential Growth (Doubling Time)
//			{ 5, 6, 7 }, // Logistic Growth (Growth Rate)
//			{ 8, 9, 10 }, // Logistic Growth (Doubling Time)
//			{ 11, 12, 13 }, // Expansion (Growth Rate)
//			{ 14, 15, 16 } // Expansion (Doubling Time)
	};
	
	
	public double[] demographicParameterValues = new double[] {
			
			/*Constant Population*/
			1000.0, // Population Size
			
			/*Exponential Growth (Growth Rate)*/
			1000.0, // Population Size
			0.5, // Growth Rate
			
			/*Exponential Growth (Doubling Time)*/
			1000.0, // Population Size
			10.0 // Doubling Time
			
//			1000.0, // Population Size
//			0.5, // Growth Rate
//			50.0, // Logistic Shape (Half-life)
//			1000.0, // Population Size
//			10.0, // Doubling Time
//			50.0, // Logistic Shape (Half-life)
//			1000.0, // Population Size
//			0.1, // Ancestral Proportion
//			0.5, // Growth Rate
//			1000.0, // Population Size
//			0.1, // Ancestral Proportion
//			10.0 // Doubling Time
	};

	public DemographicFunction createDemographicFunction() {

		DemographicFunction demographicFunction = null;

		if (this.demographicModelIndex == 0) { // No model

			// do nothing
			
		} else if (this.demographicModelIndex == 1) {// Constant Population

			demographicFunction = new ConstantPopulation(Units.Type.YEARS);
			((ConstantPopulation)demographicFunction).setN0(demographicParameterValues[0]);
			
		} else if (this.demographicModelIndex == 2) {// Exponential Growth (Growth Rate)

			demographicFunction = new ExponentialGrowth(Units.Type.YEARS);
            ((ExponentialGrowth) demographicFunction).setN0(demographicParameterValues[1]);
            ((ExponentialGrowth) demographicFunction).setGrowthRate(demographicParameterValues[2]);
			
		} else if (this.demographicModelIndex == 3) {// Exponential Growth (Doubling Time)
			
			demographicFunction = new ExponentialGrowth(Units.Type.YEARS);
            ((ExponentialGrowth) demographicFunction).setN0(demographicParameterValues[3]);
            ((ExponentialGrowth) demographicFunction).setDoublingTime(demographicParameterValues[4]);
			
//		} else if (this.demographicModelIndex == 4) {// Logistic Growth (Growth Rate)
//			
//			demographicFunction = new LogisticGrowth(Units.Type.YEARS);
//            ((LogisticGrowth) demographicFunction).setN0(demographicParameterValues[5]);
//            ((LogisticGrowth) demographicFunction).setGrowthRate(demographicParameterValues[6]);
//            ((LogisticGrowth) demographicFunction).setTime50(demographicParameterValues[7]);
//			
//		} else if (this.demographicModelIndex == 5) {// Logistic Growth (Doubling Time)
//			
//			demographicFunction = new LogisticGrowth(Units.Type.YEARS);
//            ((LogisticGrowth) demographicFunction).setN0(demographicParameterValues[8]);
//            ((LogisticGrowth) demographicFunction).setDoublingTime(demographicParameterValues[9]);
//            ((LogisticGrowth) demographicFunction).setTime50(demographicParameterValues[10]);
//			
//		} else if (this.demographicModelIndex == 6) {// Expansion (Growth Rate)
//			
//			demographicFunction = new Expansion(Units.Type.YEARS);
//            ((Expansion) demographicFunction).setN0(demographicParameterValues[11]);
//            ((Expansion) demographicFunction).setProportion(demographicParameterValues[12]);
//            ((Expansion) demographicFunction).setGrowthRate(demographicParameterValues[13]);
//			
//		} else if (this.demographicModelIndex == 7) {// Expansion (Doubling Time)
//			
//			demographicFunction = new Expansion(Units.Type.YEARS);
//            ((Expansion) demographicFunction).setN0(demographicParameterValues[14]);
//            ((Expansion) demographicFunction).setProportion(demographicParameterValues[15]);
//            ((Expansion) demographicFunction).setDoublingTime(demographicParameterValues[16]);
			
		} else {

			System.out.println("Not yet implemented");
			
		}

		return demographicFunction;
	}// END: createDemographicFunction
	
	// ////////////
	// ---TAXA---//
	// ////////////

	public TreesTableRecord record = null;
	
//	public Taxa taxa = null;
	
	public String taxaIdref = TaxaParser.TAXA;
	
	public void resetTaxaIdref() {
		this.taxaIdref = TaxaParser.TAXA;
	}
	
	// //////////////////
	// ---TREE MODEL---//
	// //////////////////

//	public Tree tree = null;
	public String treeModelIdref = TreeModel.TREE_MODEL;

	public void resetTreeModelIdref() {
	this.treeModelIdref = TreeModel.TREE_MODEL;
	}
	
	public TreeModel createTreeModel() {
		
		TreeModel treeModel = null;
		if (this.demographicModelIndex == 0 && this.record.isTreeSet()) {
			
			treeModel = new TreeModel(this.record.getTree());
			
		} else if( (this.demographicModelIndex > 0 && this.demographicModelIndex <= 3) && this.record.isTreeSet()) {
			
			Taxa taxa = new Taxa(this.record.getTree().asList()); 
			CoalescentSimulator topologySimulator = new CoalescentSimulator();
			treeModel = new TreeModel(topologySimulator.simulateTree(taxa, createDemographicFunction()));			
			
		} else if((this.demographicModelIndex > 0 && this.demographicModelIndex <= 3) && this.record.isTaxaSet()) {
			
			Taxa taxa = this.record.getTaxa();
			CoalescentSimulator topologySimulator = new CoalescentSimulator();
			treeModel = new TreeModel(topologySimulator.simulateTree(taxa, createDemographicFunction()));
		
//			} else if (this.demographicModelIndex == 0 && this.record.taxaSet) { 
//			throw new RuntimeException("Data and demographic model incompatible for partition ");	
			
		} else {
			
			throw new RuntimeException("Data and demographic model incompatible.");
			
		}// END: demo model check
		
		return treeModel;
	}//END: createTreeModel

	// /////////////////
	// ---DATA TYPE---//
	// /////////////////

//	public int dataTypeIndex = 0;
//
//	public static String[] dataTypes = { "Nucleotide", //
//			"Codon" //
//	};
//
//	public DataType createDataType() {
//
//		DataType dataType = null;
//
//		if (this.dataTypeIndex == 0) { // Nucleotide
//
//			dataType = Nucleotides.INSTANCE;
//
//		} else if (this.dataTypeIndex == 1) { // Codon
//
//			dataType = Codons.UNIVERSAL;
//
//		} else {
//
//			System.out.println("Not yet implemented");
//
//		}
//
//		return dataType;
//	}// END: createDataType

	// ///////////////////////////
	// ---SUBSTITUTION MODELS---//
	// ///////////////////////////

	//TODO: amino acid models
	
	public int substitutionModelIndex = 0;

	public String substitutionModelIdref = Utils.SUBSTITUTION_MODEL;

	public void resetSubstitutionModelIdref() {
		this.substitutionModelIdref = Utils.SUBSTITUTION_MODEL;
	}
	
	public static String[] substitutionModels = { "HKY", //
			"GTR", //
			"TN93", //
			"GY94CodonModel", //
            "Blosum62"	
	};

	public static String[] substitutionParameterNames = new String[] {
			"Kappa value", // HKY
			"AC", // GTR
			"AG", // GTR
			"AT", // GTR
			"CG", // GTR
			"CT", // GTR
			"GT", // GTR
			"Kappa 1 (A-G)", // TN93
			"Kappa 2 (C-T)", // TN93
			"Omega value", // Yang Codon Model
			"Kappa value" // Yang Codon Model
	};

	public static int[][] substitutionParameterIndices = { { 0 }, // HKY
			{ 1, 2, 3, 4, 5, 6 }, // GTR
			{ 7, 8 }, // TN93
			{ 9, 10 }, // Yang Codon Model
			{} // Blosum62

	};

	public double[] substitutionParameterValues = new double[] { 1.0, // Kappa-value
			1.0, // AC
			1.0, // AG
			1.0, // AT
			1.0, // CG
			1.0, // CT
			1.0, // GT
			1.0, // Kappa 1
			1.0, // Kappa 2
			0.1, // Omega value
			1.0 // Kappa value
	};

	public BranchModel createBranchModel() {

		BranchModel branchModel = null;

		if (this.substitutionModelIndex == 0) { // HKY

			Parameter kappa = new Parameter.Default(1, substitutionParameterValues[0]);

			FrequencyModel frequencyModel = this.createFrequencyModel();

			HKY hky = new HKY(kappa, frequencyModel);

			branchModel = new HomogeneousBranchModel(hky);

		} else if (this.substitutionModelIndex == 1) { // GTR

			Parameter ac = new Parameter.Default(1,
					substitutionParameterValues[1]);
			Parameter ag = new Parameter.Default(1,
					substitutionParameterValues[2]);
			Parameter at = new Parameter.Default(1,
					substitutionParameterValues[3]);
			Parameter cg = new Parameter.Default(1,
					substitutionParameterValues[4]);
			Parameter ct = new Parameter.Default(1,
					substitutionParameterValues[5]);
			Parameter gt = new Parameter.Default(1,
					substitutionParameterValues[6]);

			FrequencyModel frequencyModel = this.createFrequencyModel();

			GTR gtr = new GTR(ac, ag, at, cg, ct, gt, frequencyModel);

			branchModel = new HomogeneousBranchModel(gtr);

		} else if (this.substitutionModelIndex == 2) { // TN93

			Parameter kappa1 = new Parameter.Default(1,
					substitutionParameterValues[7]);
			Parameter kappa2 = new Parameter.Default(1,
					substitutionParameterValues[8]);

			FrequencyModel frequencyModel = this.createFrequencyModel();

			TN93 tn93 = new TN93(kappa1, kappa2, frequencyModel);

			branchModel = new HomogeneousBranchModel(tn93);

		} else if (this.substitutionModelIndex == 3) { // Yang Codon Model

			FrequencyModel frequencyModel = this.createFrequencyModel();

			Parameter kappa = new Parameter.Default(1,
					substitutionParameterValues[9]);
			Parameter omega = new Parameter.Default(1,
					substitutionParameterValues[10]);

			GY94CodonModel yangCodonModel = new GY94CodonModel(
					Codons.UNIVERSAL, omega, kappa, frequencyModel);

			branchModel = new HomogeneousBranchModel(yangCodonModel);

		} else if (this.substitutionModelIndex == 4) { // Blosum62
			
			FrequencyModel frequencyModel = this.createFrequencyModel();
			
			EmpiricalRateMatrix rateMatrix = Blosum62.INSTANCE;

			EmpiricalAminoAcidModel empiricalAminoAcidModel = new EmpiricalAminoAcidModel(
					rateMatrix, frequencyModel);

			branchModel = new HomogeneousBranchModel(
					empiricalAminoAcidModel);
			
		} else {

			System.out.println("Not yet implemented");

		}

		return branchModel;
	}// END: createBranchSubstitutionModel

	// ////////////////////
	// ---CLOCK MODELS---//
	// ////////////////////
	
	public int clockModelIndex = 0;

	public String clockModelIdref = BranchRateModel.BRANCH_RATES;

	public void resetClockModelIdref() {
		this.clockModelIdref = BranchRateModel.BRANCH_RATES;
	}
	
	public static String[] clockModels = { "Strict Clock", //
			"Lognormal relaxed clock (Uncorrelated)", //
			"Exponential relaxed clock (Uncorrelated)", //
			"Inverse Gaussian relaxed clock" //<commit_msg>implemented other models of a-a substitution<commit_after>package dr.app.bss;

import java.io.Serializable;

import dr.app.beagle.evomodel.branchmodel.BranchModel;
import dr.app.beagle.evomodel.branchmodel.HomogeneousBranchModel;
import dr.app.beagle.evomodel.sitemodel.GammaSiteRateModel;
import dr.app.beagle.evomodel.substmodel.EmpiricalAminoAcidModel;
import dr.app.beagle.evomodel.substmodel.FrequencyModel;
import dr.app.beagle.evomodel.substmodel.GTR;
import dr.app.beagle.evomodel.substmodel.GY94CodonModel;
import dr.app.beagle.evomodel.substmodel.HKY;
import dr.app.beagle.evomodel.substmodel.TN93;
import dr.evolution.coalescent.CoalescentSimulator;
import dr.evolution.coalescent.ConstantPopulation;
import dr.evolution.coalescent.DemographicFunction;
import dr.evolution.coalescent.ExponentialGrowth;
import dr.evolution.datatype.AminoAcids;
import dr.evolution.datatype.Codons;
import dr.evolution.datatype.Nucleotides;
import dr.evolution.sequence.Sequence;
import dr.evolution.util.Taxa;
import dr.evolution.util.Units;
import dr.evomodel.branchratemodel.BranchRateModel;
import dr.evomodel.branchratemodel.DiscretizedBranchRates;
import dr.evomodel.branchratemodel.StrictClockBranchRates;
import dr.evomodel.sitemodel.SiteModel;
import dr.evomodel.substmodel.Blosum62;
import dr.evomodel.substmodel.CPREV;
import dr.evomodel.substmodel.Dayhoff;
import dr.evomodel.substmodel.EmpiricalRateMatrix;
import dr.evomodel.substmodel.JTT;
import dr.evomodel.substmodel.LG;
import dr.evomodel.substmodel.MTREV;
import dr.evomodel.substmodel.WAG;
import dr.evomodel.tree.TreeModel;
import dr.evoxml.TaxaParser;
import dr.inference.distribution.ExponentialDistributionModel;
import dr.inference.distribution.InverseGaussianDistributionModel;
import dr.inference.distribution.LogNormalDistributionModel;
import dr.inference.distribution.ParametricDistributionModel;
import dr.inference.model.Parameter;
import dr.inferencexml.distribution.DistributionModelParser;
import dr.inferencexml.distribution.InverseGaussianDistributionModelParser;
import dr.inferencexml.distribution.LogNormalDistributionModelParser;

/**
 * @author <NAME>
 * @version $Id$
 */
@SuppressWarnings("serial")
public class PartitionData implements Serializable {

	public PartitionData() {
	}// END: Constructor

	public int from = 1;
	public int to = 1000;
	public int every = 1;

	public int createPartitionSiteCount() {
		return ((to - from) / every) + 1;
	}
	
	public void resetIdrefs() {
		resetClockModelIdref();
		resetFrequencyModelIdref();
		resetSiteRateModelIdref();
		resetSubstitutionModelIdref();
		resetTreeModelIdref();
		resetDemographicModelIdref();
		resetTaxaIdref();
	}

	// /////////////////////////
	// ---DEMOGRAPHIC MODEL---//
	// /////////////////////////

	public int demographicModelIndex = 0;
	
	public String demographicModelIdref = Utils.DEMOGRAPHIC_MODEL;

	public void resetDemographicModelIdref() {
		this.demographicModelIdref = Utils.DEMOGRAPHIC_MODEL;
	}
	
    public static String[] demographicModels = {
    	"No Model (user-specified tree)",
    	"Constant Population",
        "Exponential Growth (Growth Rate)",
        "Exponential Growth (Doubling Time)"
//        "Logistic Growth (Growth Rate)",
//        "Logistic Growth (Doubling Time)",
//        "Expansion (Growth Rate)",
//        "Expansion (Doubling Time)",
        };
	
	public static String[] demographicParameterNames = new String[] {
	        "Population Size", // Constant Population
			"Population Size", // Exponential Growth (Growth Rate)
			"Growth Rate", // Exponential Growth (Growth Rate)
			"Population Size", // Exponential Growth (Doubling Time)
			"Doubling Time" // Exponential Growth (Doubling Time)
//			"Population Size", // Logistic Growth (Growth Rate)
//			"Growth Rate", // Logistic Growth (Growth Rate)
//			"Logistic Shape (Half-life)", // Logistic Growth (Growth Rate)
//			"Population Size", // Logistic Growth (Doubling Time)
//			"Doubling Time", // Logistic Growth (Doubling Time)
//			"Logistic Shape (Half-life)", // Logistic Growth (Doubling Time)
//			"Population Size", // Expansion (Growth Rate)
//			"Ancestral Proportion", // Expansion (Growth Rate)
//			"Growth Rate", // Expansion (Growth Rate)
//			"Population Size", // Expansion (Doubling Time)
//			"Ancestral Proportion", // Expansion (Doubling Time)
//			"Doubling Time", // Expansion (Doubling Time)
	};	
	
	public static int[][] demographicParameterIndices = {
		    {  }, // No model
			{ 0 }, // Constant Population
			{ 1, 2 }, // Exponential Growth (Growth Rate)
			{ 3, 4 }// Exponential Growth (Doubling Time)
//			{ 5, 6, 7 }, // Logistic Growth (Growth Rate)
//			{ 8, 9, 10 }, // Logistic Growth (Doubling Time)
//			{ 11, 12, 13 }, // Expansion (Growth Rate)
//			{ 14, 15, 16 } // Expansion (Doubling Time)
	};
	
	
	public double[] demographicParameterValues = new double[] {
			
			/*Constant Population*/
			1000.0, // Population Size
			
			/*Exponential Growth (Growth Rate)*/
			1000.0, // Population Size
			0.5, // Growth Rate
			
			/*Exponential Growth (Doubling Time)*/
			1000.0, // Population Size
			10.0 // Doubling Time
			
//			1000.0, // Population Size
//			0.5, // Growth Rate
//			50.0, // Logistic Shape (Half-life)
//			1000.0, // Population Size
//			10.0, // Doubling Time
//			50.0, // Logistic Shape (Half-life)
//			1000.0, // Population Size
//			0.1, // Ancestral Proportion
//			0.5, // Growth Rate
//			1000.0, // Population Size
//			0.1, // Ancestral Proportion
//			10.0 // Doubling Time
	};

	public DemographicFunction createDemographicFunction() {

		DemographicFunction demographicFunction = null;

		if (this.demographicModelIndex == 0) { // No model

			// do nothing
			
		} else if (this.demographicModelIndex == 1) {// Constant Population

			demographicFunction = new ConstantPopulation(Units.Type.YEARS);
			((ConstantPopulation)demographicFunction).setN0(demographicParameterValues[0]);
			
		} else if (this.demographicModelIndex == 2) {// Exponential Growth (Growth Rate)

			demographicFunction = new ExponentialGrowth(Units.Type.YEARS);
            ((ExponentialGrowth) demographicFunction).setN0(demographicParameterValues[1]);
            ((ExponentialGrowth) demographicFunction).setGrowthRate(demographicParameterValues[2]);
			
		} else if (this.demographicModelIndex == 3) {// Exponential Growth (Doubling Time)
			
			demographicFunction = new ExponentialGrowth(Units.Type.YEARS);
            ((ExponentialGrowth) demographicFunction).setN0(demographicParameterValues[3]);
            ((ExponentialGrowth) demographicFunction).setDoublingTime(demographicParameterValues[4]);
			
//		} else if (this.demographicModelIndex == 4) {// Logistic Growth (Growth Rate)
//			
//			demographicFunction = new LogisticGrowth(Units.Type.YEARS);
//            ((LogisticGrowth) demographicFunction).setN0(demographicParameterValues[5]);
//            ((LogisticGrowth) demographicFunction).setGrowthRate(demographicParameterValues[6]);
//            ((LogisticGrowth) demographicFunction).setTime50(demographicParameterValues[7]);
//			
//		} else if (this.demographicModelIndex == 5) {// Logistic Growth (Doubling Time)
//			
//			demographicFunction = new LogisticGrowth(Units.Type.YEARS);
//            ((LogisticGrowth) demographicFunction).setN0(demographicParameterValues[8]);
//            ((LogisticGrowth) demographicFunction).setDoublingTime(demographicParameterValues[9]);
//            ((LogisticGrowth) demographicFunction).setTime50(demographicParameterValues[10]);
//			
//		} else if (this.demographicModelIndex == 6) {// Expansion (Growth Rate)
//			
//			demographicFunction = new Expansion(Units.Type.YEARS);
//            ((Expansion) demographicFunction).setN0(demographicParameterValues[11]);
//            ((Expansion) demographicFunction).setProportion(demographicParameterValues[12]);
//            ((Expansion) demographicFunction).setGrowthRate(demographicParameterValues[13]);
//			
//		} else if (this.demographicModelIndex == 7) {// Expansion (Doubling Time)
//			
//			demographicFunction = new Expansion(Units.Type.YEARS);
//            ((Expansion) demographicFunction).setN0(demographicParameterValues[14]);
//            ((Expansion) demographicFunction).setProportion(demographicParameterValues[15]);
//            ((Expansion) demographicFunction).setDoublingTime(demographicParameterValues[16]);
			
		} else {

			System.out.println("Not yet implemented");
			
		}

		return demographicFunction;
	}// END: createDemographicFunction
	
	// ////////////
	// ---TAXA---//
	// ////////////

	public TreesTableRecord record = null;
	
//	public Taxa taxa = null;
	
	public String taxaIdref = TaxaParser.TAXA;
	
	public void resetTaxaIdref() {
		this.taxaIdref = TaxaParser.TAXA;
	}
	
	// //////////////////
	// ---TREE MODEL---//
	// //////////////////

//	public Tree tree = null;
	public String treeModelIdref = TreeModel.TREE_MODEL;

	public void resetTreeModelIdref() {
	this.treeModelIdref = TreeModel.TREE_MODEL;
	}
	
	public TreeModel createTreeModel() {
		
		TreeModel treeModel = null;
		if (this.demographicModelIndex == 0 && this.record.isTreeSet()) {
			
			treeModel = new TreeModel(this.record.getTree());
			
		} else if( (this.demographicModelIndex > 0 && this.demographicModelIndex <= 3) && this.record.isTreeSet()) {
			
			Taxa taxa = new Taxa(this.record.getTree().asList()); 
			CoalescentSimulator topologySimulator = new CoalescentSimulator();
			treeModel = new TreeModel(topologySimulator.simulateTree(taxa, createDemographicFunction()));			
			
		} else if((this.demographicModelIndex > 0 && this.demographicModelIndex <= 3) && this.record.isTaxaSet()) {
			
			Taxa taxa = this.record.getTaxa();
			CoalescentSimulator topologySimulator = new CoalescentSimulator();
			treeModel = new TreeModel(topologySimulator.simulateTree(taxa, createDemographicFunction()));
		
//			} else if (this.demographicModelIndex == 0 && this.record.taxaSet) { 
//			throw new RuntimeException("Data and demographic model incompatible for partition ");	
			
		} else {
			
			throw new RuntimeException("Data and demographic model incompatible.");
			
		}// END: demo model check
		
		return treeModel;
	}//END: createTreeModel

	// /////////////////
	// ---DATA TYPE---//
	// /////////////////

//	public int dataTypeIndex = 0;
//
//	public static String[] dataTypes = { "Nucleotide", //
//			"Codon" //
//	};
//
//	public DataType createDataType() {
//
//		DataType dataType = null;
//
//		if (this.dataTypeIndex == 0) { // Nucleotide
//
//			dataType = Nucleotides.INSTANCE;
//
//		} else if (this.dataTypeIndex == 1) { // Codon
//
//			dataType = Codons.UNIVERSAL;
//
//		} else {
//
//			System.out.println("Not yet implemented");
//
//		}
//
//		return dataType;
//	}// END: createDataType

	// ///////////////////////////
	// ---SUBSTITUTION MODELS---//
	// ///////////////////////////

	//TODO: amino acid models
	
	public int substitutionModelIndex = 0;

	public String substitutionModelIdref = Utils.SUBSTITUTION_MODEL;

	public void resetSubstitutionModelIdref() {
		this.substitutionModelIdref = Utils.SUBSTITUTION_MODEL;
	}
	
	public static String[] substitutionModels = { "HKY", //
			"GTR", //
			"TN93", //
			"GY94CodonModel", //
            "Blosum62", //	
			"CPREV", //
			"Dayhoff", //
			"FLU", //
			"JTT", //
			"LG", //
			"MTREV", //
			"WAG" //
	};

	public static String[] substitutionParameterNames = new String[] {
			"Kappa value", // HKY
			"AC", // GTR
			"AG", // GTR
			"AT", // GTR
			"CG", // GTR
			"CT", // GTR
			"GT", // GTR
			"Kappa 1 (A-G)", // TN93
			"Kappa 2 (C-T)", // TN93
			"Omega value", // Yang Codon Model
			"Kappa value" // Yang Codon Model
	};

	public static int[][] substitutionParameterIndices = { { 0 }, // HKY
			{ 1, 2, 3, 4, 5, 6 }, // GTR
			{ 7, 8 }, // TN93
			{ 9, 10 }, // Yang Codon Model
			{}, // Blosum62
			{}, // CPREV
			{}, // Dayhoff
			{}, // FLU
			{}, // JTT
			{}, // LG
			{}, // MTREV
			{} // WAG
	};

	public double[] substitutionParameterValues = new double[] { 1.0, // Kappa-value
			1.0, // AC
			1.0, // AG
			1.0, // AT
			1.0, // CG
			1.0, // CT
			1.0, // GT
			1.0, // Kappa 1
			1.0, // Kappa 2
			0.1, // Omega value
			1.0 // Kappa value
	};

	public BranchModel createBranchModel() {

		BranchModel branchModel = null;

		if (this.substitutionModelIndex == 0) { // HKY

			Parameter kappa = new Parameter.Default(1, substitutionParameterValues[0]);

			FrequencyModel frequencyModel = this.createFrequencyModel();

			HKY hky = new HKY(kappa, frequencyModel);

			branchModel = new HomogeneousBranchModel(hky);

		} else if (this.substitutionModelIndex == 1) { // GTR

			Parameter ac = new Parameter.Default(1,
					substitutionParameterValues[1]);
			Parameter ag = new Parameter.Default(1,
					substitutionParameterValues[2]);
			Parameter at = new Parameter.Default(1,
					substitutionParameterValues[3]);
			Parameter cg = new Parameter.Default(1,
					substitutionParameterValues[4]);
			Parameter ct = new Parameter.Default(1,
					substitutionParameterValues[5]);
			Parameter gt = new Parameter.Default(1,
					substitutionParameterValues[6]);

			FrequencyModel frequencyModel = this.createFrequencyModel();

			GTR gtr = new GTR(ac, ag, at, cg, ct, gt, frequencyModel);

			branchModel = new HomogeneousBranchModel(gtr);

		} else if (this.substitutionModelIndex == 2) { // TN93

			Parameter kappa1 = new Parameter.Default(1,
					substitutionParameterValues[7]);
			Parameter kappa2 = new Parameter.Default(1,
					substitutionParameterValues[8]);

			FrequencyModel frequencyModel = this.createFrequencyModel();

			TN93 tn93 = new TN93(kappa1, kappa2, frequencyModel);

			branchModel = new HomogeneousBranchModel(tn93);

		} else if (this.substitutionModelIndex == 3) { // Yang Codon Model

			FrequencyModel frequencyModel = this.createFrequencyModel();

			Parameter kappa = new Parameter.Default(1,
					substitutionParameterValues[9]);
			Parameter omega = new Parameter.Default(1,
					substitutionParameterValues[10]);

			GY94CodonModel yangCodonModel = new GY94CodonModel(
					Codons.UNIVERSAL, omega, kappa, frequencyModel);

			branchModel = new HomogeneousBranchModel(yangCodonModel);

		} else if (this.substitutionModelIndex == 4) { // Blosum62
			
			FrequencyModel frequencyModel = this.createFrequencyModel();
			
			EmpiricalRateMatrix rateMatrix = Blosum62.INSTANCE;

			EmpiricalAminoAcidModel empiricalAminoAcidModel = new EmpiricalAminoAcidModel(
					rateMatrix, frequencyModel);

			branchModel = new HomogeneousBranchModel(
					empiricalAminoAcidModel);
			
        } else if (this.substitutionModelIndex == 5) { // CPREV
			
			FrequencyModel frequencyModel = this.createFrequencyModel();
			
			EmpiricalRateMatrix rateMatrix = CPREV.INSTANCE;

			EmpiricalAminoAcidModel empiricalAminoAcidModel = new EmpiricalAminoAcidModel(
					rateMatrix, frequencyModel);

			branchModel = new HomogeneousBranchModel(
					empiricalAminoAcidModel);
			
        } else if (this.substitutionModelIndex == 6) { // Dayhoff
			
			FrequencyModel frequencyModel = this.createFrequencyModel();
			
			EmpiricalRateMatrix rateMatrix = Dayhoff.INSTANCE;

			EmpiricalAminoAcidModel empiricalAminoAcidModel = new EmpiricalAminoAcidModel(
					rateMatrix, frequencyModel);

			branchModel = new HomogeneousBranchModel(
					empiricalAminoAcidModel);
		
        } else if (this.substitutionModelIndex == 7) { // JTT
			
			FrequencyModel frequencyModel = this.createFrequencyModel();
			
			EmpiricalRateMatrix rateMatrix = JTT.INSTANCE;

			EmpiricalAminoAcidModel empiricalAminoAcidModel = new EmpiricalAminoAcidModel(
					rateMatrix, frequencyModel);

			branchModel = new HomogeneousBranchModel(
					empiricalAminoAcidModel);
		
        } else if (this.substitutionModelIndex == 8) { // LG
			
			FrequencyModel frequencyModel = this.createFrequencyModel();
			
			EmpiricalRateMatrix rateMatrix = LG.INSTANCE;

			EmpiricalAminoAcidModel empiricalAminoAcidModel = new EmpiricalAminoAcidModel(
					rateMatrix, frequencyModel);

			branchModel = new HomogeneousBranchModel(
					empiricalAminoAcidModel);
			
        } else if (this.substitutionModelIndex == 9) { // MTREV
			
			FrequencyModel frequencyModel = this.createFrequencyModel();
			
			EmpiricalRateMatrix rateMatrix = MTREV.INSTANCE;

			EmpiricalAminoAcidModel empiricalAminoAcidModel = new EmpiricalAminoAcidModel(
					rateMatrix, frequencyModel);

			branchModel = new HomogeneousBranchModel(
					empiricalAminoAcidModel);	
			
        } else if (this.substitutionModelIndex == 10) { // WAG
			
			FrequencyModel frequencyModel = this.createFrequencyModel();
			
			EmpiricalRateMatrix rateMatrix = WAG.INSTANCE;

			EmpiricalAminoAcidModel empiricalAminoAcidModel = new EmpiricalAminoAcidModel(
					rateMatrix, frequencyModel);

			branchModel = new HomogeneousBranchModel(
					empiricalAminoAcidModel);	
			
		} else {

			System.out.println("Not yet implemented");

		}

		return branchModel;
	}// END: createBranchSubstitutionModel

	// ////////////////////
	// ---CLOCK MODELS---//
	// ////////////////////
	
	public int clockModelIndex = 0;

	public String clockModelIdref = BranchRateModel.BRANCH_RATES;

	public void resetClockModelIdref() {
		this.clockModelIdref = BranchRateModel.BRANCH_RATES;
	}
	
	public static String[] clockModels = { "Strict Clock", //
			"Lognormal relaxed clock (Uncorrelated)", //
			"Exponential relaxed clock (Uncorrelated)", //
			"Inverse Gaussian relaxed clock" //
{'fraction_non_alphanumeric': 0.13888543737574552, 'fraction_numerical': 0.015997763419483103, 'mean_word_length': 3.2866844207723034, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3608631', 'n_tokens_mistral': 11825, 'n_tokens_neox': 9839, 'n_words': 2111}