/*  
 *  src/org/metaqtl/MetaQtlAnalysis.java
 * 
 *  $Author: veyrieras $, $Date: 2006-10-17 15:41:54 $, $Version$
 *
 *  MetaQTL : a Java package for QTL Meta-Analysis
 * 
 *  Copyright (C) 2003-2006  Jean-Baptiste Veyrieras, INRA, France.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed 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.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * 
 */
package org.metaqtl;


/**
 * A QTL meta analysis consists in a clustering of QTL positions over
 * chromosomes for different group of traits. The a
 * <code>MetaQtlAnalysis</code> object is just a bundle of chromosomes
 * in each of which the result of the meta analysis is stored.
 */
public class MetaQtlAnalysis {
	/**
	 * The number of chromosomes on which the meta-analysis
	 * has been performed.
	 */
	public int nchr;
	/**
	 * The names of the chromosomes.
	 */
	public String[] chromNames;
	/**
	 * The matrix of qtl by chromosome
	 */
	public Qtl[][] qtlByChrom;
	/**
	 * The matrix of results where the rows are the chromosomes.
	 */
	public MetaQtlResult[][] resultByChrom;
	
	/**
	 * Creates a new instance of a <code>MetaQtlAnalysis</code>
	 * 
	 * @param nchr the number of chromosomes on which the meta-analysis has been
	 * performed.
	 */
	public MetaQtlAnalysis(int nchr) {
		this.nchr = nchr;
		this.chromNames = new String[nchr];
		this.qtlByChrom = new Qtl[nchr][];
		this.resultByChrom = new MetaQtlResult[nchr][];
	}
	/**
	 * Returns the result for the given trait name or null
	 * if not found.  
	 * @param trait the name of the trait for which the result is asked.  
	 * @return the result or null if not found.
	 */
	public MetaQtlResult getResult(String chrom, String trait) {
		int i;
		
		i = getChromIdx(chrom);
		
		if (i<chromNames.length) {
			// Look for the trait
			int j;
			for(j=0;j<resultByChrom[i].length;j++)
				if (resultByChrom[i][j].trait.equals(trait))
					return resultByChrom[i][j];
		}
		
		return null;
	}
	/**
	 * Returns the first result for the given chromosome.  
	 * @return the result or null if not found.
	 */
	public MetaQtlResult getResult(String chrom) {
		int i;
		
		i = getChromIdx(chrom);
		
		if (i<chromNames.length)
			return resultByChrom[i][0];
		
		return null;
	}
	/**
	 * Returns the result for the given trait name or null
	 * if not found.  
	 * @param trait the name of the trait for which the result is asked.  
	 * @return the result or null if not found.
	 */
	public MetaQtlResult getResult(int chromIdx, String trait) {
		if (chromIdx<chromNames.length) {
			// Look for the trait
			int j;
			for(j=0;j<resultByChrom[chromIdx].length;j++)
				if (resultByChrom[chromIdx][j].trait.equals(trait))
					return resultByChrom[chromIdx][j];
		}
		return null;
	}
	/**
	 * 
	 * @return
	 */
	public int getChromIdx(String chrom) {
		for(int i=0;i<chromNames.length;i++) {
			if (chromNames[i].equals(chrom))
				return i;
		}
		return -1;
	}
	/**
	 * 
	 * @return
	 */
	public int getTraitIdx(int chromIdx, String trait) {
		if (chromIdx >= 0 && chromIdx < nchr) 
			for(int j=0;j<resultByChrom[chromIdx].length;j++)
				if (resultByChrom[chromIdx][j].trait.equals(trait))
					return j;
		return -1;
	}
	/**
	 * Returns the meta Qtl for the given chromosome indice
	 * <code>cidx</code>, the given trait name <code>trait</code>
	 * and the given number of clusters <code>k</code>. 
	 * @param cidx
	 * @param trait
	 * @param k
	 */
	public Qtl[] getMetaQtl(String chrom, String trait, int k) {
		int cidx = getChromIdx(chrom);
		int tidx = getTraitIdx(cidx, trait);
		
		if (tidx!=-1)
			return resultByChrom[cidx][tidx].getMetaQtl(k);
		
		return null;
	}
	/**
	 * This methods returns the best models for each criterion
	 * defined to select the optimal number of clusters per
	 * chromosome per trait.
	 * 
	 * @return
	 */
	public MetaQtlModel getBestModel(int criterion) {
		MetaQtlModel model = null;
		
		model = new MetaQtlModel(this.nchr);
		
		for(int i=0;i<nchr;i++) {
			
			String[] traits = new String[resultByChrom[i].length];
			int[] models    = new int[resultByChrom[i].length];
			
			for(int j=0;j<resultByChrom[i].length;j++) {
				
				traits[j] = resultByChrom[i][j].getTraitName();
				
				System.out.println(chromNames[i]+" "+traits[j]);
				
				models[j] = resultByChrom[i][j].getBestClustering(criterion).k;
				
			}
			
			model.setChromName(i, chromNames[i]);
			model.setTraitNames(i, traits);
			model.setModel(i, models);
			
		}
		
		return model;
	}
	
	public MetaQtlResult[] getResults(String chromName) {
		int cidx = getChromIdx(chromName);
		if (cidx>=0) return resultByChrom[cidx]; 
		return null;
	}
	
}
