package jet.tools;
import java.util.*;

/** Classe gérant l'initialisation des parametres et le lancement du clustering 3D des residus traces:
 * Calcul des graines, extension des graines, calcul des seuils pour la taille des clusters via
 * la génération alétoire de clusters*/

public class MapClusters 
{
   
	/** Initialisation et lancement de la clusterisation des acides aminés accessibles (surface) 
	 * de la séquence ref, en fonction de leur score de trace et/ou de pc (dépend de analysisType).  
	 * Deux résidus clusterisent si leur distance est inférieur à radius.
	 * Les clusters couvre une proportion de la surface dépendante de percentInterface.
	 * Ce parametre est soit donné en entrée soit évalué par une relation entre la taille des interfaces 
	 * et des surfaces (percentInterface=26.54/surfSize+0.03)*/
	
	public static Vector map(jet.data.datatype.Sequence3D ref, Vector trace, Vector pc, Vector surface, float radius, String analysisType, double percentInterface)
    {
		/* Initialisation de la clusterisation */
		jet.cluster.Clustering clustering=new jet.cluster.Clustering(ref,radius);
		
		Vector index=new Vector(1,1),clusterTable=new Vector(),clusterData=fillVector(ref.size());
		
		int i,j;
		double coverage=0.0;
		int clustersSize;
		boolean minScore=true;
		int surfSize=0;
		
		/* taille de la surface */
		for(i=0;i<surface.size();i++) if ((Double)surface.get(i)==1.0) surfSize=surfSize+1;
		
		/* Si percentInterface=-1 (pas de valeurs d'entrée) alors il est évalué */
		
		if (percentInterface==-1) percentInterface=(26.54/(double)surfSize)+0.03;
    	
    	System.out.println("surface size:"+surfSize);
    	System.out.println("percent interface used:"+percentInterface);
		
		double minScoreResiduGraine,minScoreClusterGraine,minScoreResidu,minScoreCluster;
		
		Vector statistique=new Vector();
		
		Vector scoreSeeds=new Vector();
		Vector scoreExtension=new Vector();
		Vector pcModifiedMoy=new Vector();
		Vector sortedScore;
		
		Vector traceMoy=clustering.calculScoreMoy(trace,surface);
		
		double max=0.0;
		/* calcul des valeurs utilisées pour l'analyse en propriétés phisico-chimiques.
		 * trace*pc² avec utilisation des valeur de pc originelle (0 à 2.21 et pas entre 0 et 1).*/
		for (i=0;i<20;i++) if (jet.data.datatype.Residue.getResiduePC(i)>max) max=jet.data.datatype.Residue.getResiduePC(i);
		for (i=0;i<trace.size();i++) pcModifiedMoy.add((Double)trace.get(i)*(Math.pow(((Double)pc.get(i))*max,2)));
		pcModifiedMoy=clustering.calculScoreMoy(pcModifiedMoy,surface);
		
		Vector analyse=new Vector();
		Vector seuilConf=new Vector();
		Vector seuilMoyCluster=new Vector();
		Vector seuilResidu=new Vector();
		Vector forcedResults=new Vector();
		
		/* Initialisation des scores à clustériser pour le calcul des graines 
		 * en fonction de l'analyse voulu en entrée  */
		if (analysisType.equals("1"))
		{
			/* Clusterisation basée sur la trace (conservation) */
			analyse.add(traceMoy);
			/* Extension basée sur la trace (conservation) */
			scoreExtension=traceMoy;
			/* seuil de confiance (sur la distribution des tailles des 
			 * clusters générés aléatoirement) pour la taille des clusters sélectionnés */
			seuilConf.add(0.1);
			/* La valeur seuil moyenne pour le calcul de la graine est celle du résidu dont le score 
			 * est à la position (percentInterface/4.0) de la distribution triée des scores*/
			seuilMoyCluster.add(percentInterface/4.0);
			/* Valeur seuil pour considérer un résidu */
			seuilResidu.add((percentInterface*2.0>1.0)?1.0:(percentInterface*2.0));
			/* si true alors on permet de baisser les seuil de confiance afin de récupérer au moins un cluster.
			 * Donc si false on peut obtenir aucun cluster. */
			forcedResults.add(true);
		}
		else
		{
			/* Clusterisation basée sur la trace (conservation) et les proprietes physico-chimiques*/
			analyse.add(traceMoy);
			analyse.add(pcModifiedMoy);
			
			/* Initialisation des scores à clustériser pour la phase d'extension des graines  */
			for (i=0;i<trace.size();i++) scoreExtension.add(((Double)trace.get(i)+(Double)pc.get(i))/2.0);
			scoreExtension=clustering.calculScoreMoy(scoreExtension,surface);
			
			seuilConf.add(0.1);
			seuilConf.add(0.1);
			
			seuilMoyCluster.add(percentInterface/4.0);
			seuilMoyCluster.add(percentInterface/4.0);
			
			seuilResidu.add((percentInterface*2.0>1.0)?1.0:(percentInterface*2.0));
			seuilResidu.add((percentInterface*2.0>1.0)?1.0:(percentInterface*2.0));
			
			forcedResults.add(true);
			/* on ne force pas l'obtention d'un cluster pour l'analyse via pc */
			forcedResults.add(false);
		}
		
		/*
		
		score = (Vector)jprotein.tools.OrderValue.invertProperty(score);
		for (int y=0;y<score.size();y++)
			if (((Double)surface.get(y))==0.0) score.set(y, 0.0);

		*/
		
		jet.cluster.data.Cluster clust;
		
		/* lancement des calculs des graines (pc et trace ou seulement trace) */
		for (int nbAnalyse=0; nbAnalyse<analyse.size();nbAnalyse++)
		{
			scoreSeeds=(Vector)analyse.get(nbAnalyse);
			
			index.clear();
			clustersSize=0;
			
			clustering.setClusterList(new Vector());
			
			/* tri des scores */
			sortedScore = (Vector)jet.tools.OrderValue.orderProperty(scoreSeeds).get(1);
			/* récupération des seuils initialisés précédemment */
			minScoreResiduGraine=jet.tools.OrderValue.percent(sortedScore, (Double)seuilResidu.get(nbAnalyse), false);
			minScoreClusterGraine=jet.tools.OrderValue.percent(sortedScore, (Double)seuilMoyCluster.get(nbAnalyse), false);
			
			System.out.println("******* scoreResGraine:"+minScoreResiduGraine+"******* scoreClusGraine:"+minScoreClusterGraine+"********");
			
			for (int y=0;y<scoreSeeds.size();y++) index.add(y);
			
			index=filtrerScore (scoreSeeds,index,minScoreResiduGraine);
			index=trierScore(scoreSeeds,index);
			
			clustering.cluster(index,scoreSeeds,pc,traceMoy,minScoreClusterGraine,surfSize,minScore);
			
			for(i=0;i<((Vector)clustering.getClusterList()).size();i++)
				clustersSize=clustersSize+((jet.cluster.data.Cluster)((Vector)clustering.getClusterList()).get(i)).getCoreIndex().size();
			if (surfSize>0) coverage=((double)clustersSize)/((double)surfSize);
			System.out.println("coverage:"+coverage);
	
			/* Génération aléatoire de cluster en respectant la meme procedur de clusterisation */
			statistique=randomTraceMap(ref,scoreSeeds,pc,traceMoy,surface,radius,6000, minScoreResiduGraine,minScoreClusterGraine,minScore);
			
			if (((Vector)clustering.getClusterList()).size()>0) clustering.setClusterList(selectSeeds(((Vector)clustering.getClusterList()),statistique,(Double)seuilConf.get(nbAnalyse),(Boolean)forcedResults.get(nbAnalyse)));
			
			int l;
			
			for(int k=0;k<clustering.getClusterList().size();k++)
			{
				clust=(jet.cluster.data.Cluster)clustering.getClusterList().get(k);
				l=0;
				while (l<clusterTable.size())
				{
					if (
							clust.isEmbedded((jet.cluster.data.Cluster)clusterTable.get(l))
							||clust.isNeighbour((jet.cluster.data.Cluster)clusterTable.get(l))
						)
					{
						clust.merge((jet.cluster.data.Cluster)clusterTable.get(l));
						clusterTable.remove(l);
					}
					else l++;
				}
				clusterTable.add(clust);
			}			
    	}
		
		System.out.print(" selected cluster graine size:");
    	for(i=0;i<clusterTable.size();i++)
    	{
    		clust=(jet.cluster.data.Cluster)clusterTable.get(i);
    		System.out.print(" "+clust.getCoreIndex().size());
    	}
    	System.out.println("");
		
		clustering.setClusterList(clusterTable);
		
		/* réinitialisation des seuils pour le score moyen des clusters et le score des résidus 
		 * en vue de la phase d'extension des graines.*/
		sortedScore = (Vector)jet.tools.OrderValue.orderProperty(scoreExtension).get(1);
		minScoreResidu=jet.tools.OrderValue.percent(sortedScore, (percentInterface*2.0>1.0)?1.0:(percentInterface*2.0), false);
		minScoreCluster=jet.tools.OrderValue.percent(sortedScore, percentInterface/2.0, false);
		
		System.out.println("******* scoreResExt:"+minScoreResidu+"******* scoreClusExt:"+minScoreCluster+"********");
		/* Calcul des extensions si on a obtenu des graines */
		if (((Vector)clustering.getClusterList()).size()>0) spreadSeeds(clustering,scoreExtension,pc,traceMoy,minScoreResidu,minScoreCluster,surfSize);
		
		System.out.print("predicted cluster size after spread:");
			
		/* Récupération des scores des résidus clusterisés */
		int position;
		Double val1;
		for(i=0;i<clusterTable.size();i++)
		{
			position=0;
			clust=(jet.cluster.data.Cluster)clusterTable.get(i);
			for(j=0;j<clust.getCoreIndex().size();j++)
			{
				position=((Integer)clust.getCoreIndex().get(j)).intValue();
				val1=(Double)scoreExtension.get(position);
				clusterData.setElementAt(val1,position);
				//clusterData.setElementAt(i+1,position);
			}
			System.out.print(" "+clust.getCoreIndex().size());
		}
		/* Affichage des Pvaleur pour la taille des clusters et le nombre de clusters */
		System.out.println("");
		
		double seuilConfiance=0.1;
		System.out.println("");
		System.out.println("Seuil de confiance de 0.1 à 1.0:");
		System.out.print("==>seuil pour la taille des clusters:");
		while (seuilConfiance<=1.0)
		{
			System.out.print(" "+atConfidence(seuilConfiance,(int[])statistique.get(1),true));
			seuilConfiance=seuilConfiance+0.1;
		}
		System.out.println("");
		System.out.print("==>seuil pour le nombre de clusters:");
		seuilConfiance=0.1;
		while (seuilConfiance<=1.0)
		{
			System.out.print(" "+atConfidence(seuilConfiance,(int[])statistique.get(0),false));
			seuilConfiance=seuilConfiance+0.1;
		}
		System.out.println("");

		if (clusterTable.size()<=0) System.out.println("no valid cluster");
	
		return clusterData;
	}
    
	/** Sélection des clusters du vecteur clusterTable vérifiant la statistique pour le seuil de 
	 * confiance (Pvaleur) seuilConfiance. Si forcedResults=true la sélection est relachée 
	 * jusqqu'à l'obtention d'un cluster. */
	
    public static Vector selectSeeds(Vector clusterTable, Vector statistique,double seuilConfiance, boolean forcedResults)
    {
    	
    	jet.cluster.data.Cluster clust;
    	boolean validCluster=false;
    	int minClusterSize=0;
    	
    	Vector clusterTableGraine=new Vector();
    	Vector taillesCluster=new Vector();
    		
    	taillesCluster.clear();
    		
    	System.out.print("predicted cluster graine size:");
    	for(int i=0;i<clusterTable.size();i++)
    	{
    		clust=(jet.cluster.data.Cluster)clusterTable.get(i);
    		taillesCluster.add(clust.getCoreIndex().size());
    		System.out.print(" "+((Integer)taillesCluster.get(i)).intValue());
    	}
    	System.out.println("");
    	
    	int nbClus=clusterTable.size();
    	double confNbClus=whichConfidence(nbClus, (int[])statistique.get(0), false);
    	System.out.println("Confidence threshold for the number of clusters predicted:"+confNbClus);
    	int clusSizeMax=0;
    	for(int i=0;i<clusterTable.size();i++)
    	{
    		if (((Integer)taillesCluster.get(i)).intValue()>clusSizeMax)
    		{
    			clusSizeMax=((jet.cluster.data.Cluster)clusterTable.get(i)).getCoreIndex().size();
    		}
    	}
    	double confTailleClus;
    	double scoreTraceMoyClus;
    	double scoreFinal;
    	double scoreTraceMoyAll=0.0;
    	double scorePcMoyClus;
    	int nbResidus=0;
    	System.out.println("Confidence threshold for the size of the largest cluster:"+whichConfidence(clusSizeMax, (int[])statistique.get(1), true));
    		
    	for(int i=0;i<clusterTable.size();i++)
    	{
    		scoreTraceMoyAll=scoreTraceMoyAll+((jet.cluster.data.Cluster)clusterTable.get(i)).getTraceMoy()*((Integer)taillesCluster.get(i)).intValue();
    		nbResidus=nbResidus+((Integer)taillesCluster.get(i)).intValue();
    	}
    	scoreTraceMoyAll=scoreTraceMoyAll/(double)nbResidus;
    	
    	System.out.print("fixing cluster size to:");
    	while ((!validCluster)&&(seuilConfiance<=1.0))
    	{
    		minClusterSize=atConfidence(seuilConfiance,(int[])statistique.get(1),true);
    		
    		System.out.println("..."+minClusterSize);
    			
    		for(int i=0;i<clusterTable.size();i++)
    		{
    			confTailleClus=whichConfidence(((Integer)taillesCluster.get(i)).intValue(), (int[])statistique.get(1), true);
    			scoreTraceMoyClus=scoreTraceMoyAll/((jet.cluster.data.Cluster)clusterTable.get(i)).getTraceMoy();
    			scorePcMoyClus=((jet.cluster.data.Cluster)clusterTable.get(i)).getpcMoy()*jet.data.datatype.Residue.getResiduePC("PHE");
    			
    			scoreFinal=confTailleClus;
    				
    			System.out.print(" cluster "+i+" score:"+scoreFinal);
    			System.out.print(" scoreTaille:"+confTailleClus);
    			System.out.print(" scClus:"+scoreTraceMoyClus);
    			System.out.print(" scPcClus:"+scorePcMoyClus);
    			
    			if (scoreFinal<=seuilConfiance)
    	    		
    			{
    				validCluster=true;
    				clusterTableGraine.add(clusterTable.get(i));
    				System.out.println(" ... ok:");
    			}
    			else System.out.println(" ... not ok:");
    				
    		}
    		if (forcedResults)  seuilConfiance=seuilConfiance+0.1;
    		else seuilConfiance=1.1;
    	}

    	if ((forcedResults)&&(!validCluster))
    	{
    		for(int i=0;i<clusterTable.size();i++)
    		{
    			if (((Integer)taillesCluster.get(i)).intValue()==clusSizeMax)
    			{
    				validCluster=true;
    				clusterTableGraine.add(clusterTable.get(i));
    			}
    		}
    	}
    		
    	return clusterTableGraine;
    }
    
    /** Extension des clusters de clustering */
    
    public static void spreadSeeds(jet.cluster.Clustering clustering, Vector score,Vector pc, Vector trace, double minTraceResidu, double minTraceCluster, int surfSize)
    {
    	Vector neighbour=new Vector();
    	Vector index=new Vector();
    	Vector clusterTableGraine=clustering.getClusterList();
		int nb=0;
		boolean arret=false;
		while(!arret)
		{
			nb++;			
			index.clear();
			for (int i=0;i<clusterTableGraine.size();i++)
			{
				neighbour.clear();
				neighbour.addAll(((jet.cluster.data.Cluster)clusterTableGraine.get(i)).getNeighbourIndex());
				neighbour.retainAll(index);
				index.removeAll(neighbour);
				index.addAll(((jet.cluster.data.Cluster)clusterTableGraine.get(i)).getNeighbourIndex());
			}
			
			index=filtrerScore (score,index,minTraceResidu);
			index=trierScore(score,index);
			arret=!clustering.cluster(index,score,pc, trace, minTraceCluster,surfSize,true);
			clusterTableGraine=clustering.getClusterList();
		}
    }
    
    /** Génération aléatoire de clusters sur la proteine ref en utilisant la distribution de scores trace
     *  mélangée aléatoirement ainsi que les scores seuil de clusterisation minScoreResidu et minScoreCluster.
     *   La génération est faite nbIteration fois. 
     *  La distribution des tailles de clusters et du nombre de cluster est retournée. */
    
    public static Vector randomTraceMap(jet.data.datatype.Sequence3D ref,Vector score,Vector pc, Vector trace, Vector surface, float radius, int nbIteration, double minScoreResidu,double minScoreCluster,boolean minScore)
    {
    	jet.cluster.Clustering clustering=new jet.cluster.Clustering(ref,radius);

    	int surfSize=0;
    	for(int i=0;i<surface.size();i++) if ((Double)surface.get(i)==1.0) surfSize=surfSize+1;
    	
    	Vector index=new Vector(1,1),clusterTable;
    	
    	int i,j;
    	
    	int[] tailleClusterMax=new int[ref.size()+1];
    	int[] nbClusters=new int[ref.size()+1];
    	
    	for (i=0;i<ref.size()+1;i++)
    	{
    		tailleClusterMax[i]=0;
    		nbClusters[i]=0;
    	}
    	Vector scoreTriee=new Vector();
    	Vector traceTriee=new Vector();
    	Vector pcTriee=new Vector();
    	Vector traceRandom=new Vector();
    	Vector scoreRandom=new Vector();
    	Vector pcRandom=new Vector();
    	int rand;
    	
    	Double val1,val2;
    	Double valpc1;
    	Double valtrace1;
    	
    	for(i=0;i<score.size();i++)
	    {		
		val1=(Double)score.get(i);
		valpc1=(Double)pc.get(i);
		valtrace1=(Double)trace.get(i);		   
			for(j=0;j<scoreTriee.size();j++)
			    {
				val2=(Double)scoreTriee.get(j);
				if(val1.doubleValue()>=val2.doubleValue())
				    {
					scoreTriee.add(j,val1);
					traceTriee.add(j,valtrace1);
					pcTriee.add(j,valpc1);
					break;
				    }
				
			    }
			if(j==scoreTriee.size())
			{
				scoreTriee.add(val1);
				traceTriee.add(valtrace1);
				pcTriee.add(valpc1);
			}
	    }
    	
    	while(nbIteration>0)
    	{
    		scoreRandom.clear();
    		traceRandom.clear();
    		pcRandom.clear();
    		index.clear();
    		for (i=0;i<scoreTriee.size();i++)
    		{
    			scoreRandom.add(0.0);
    			traceRandom.add(0.0);
    			pcRandom.add(0.0);
    		}
    		
    		i=0;
    		while (((Double)scoreTriee.get(i))>minScoreResidu)
    		{
    			rand=(int)(Math.random()*(double)scoreTriee.size());
    			scoreRandom.set(rand, scoreTriee.get(i));
    			traceRandom.set(rand, traceTriee.get(i));
    			pcRandom.set(rand, pcTriee.get(i));
    			index.add(new Integer(rand));
    			i++;
    		}

    		clustering.clearClusterList();
    		clustering.cluster(index,scoreRandom,pcRandom,traceRandom,minScoreCluster,surfSize,minScore);
    		clusterTable=clustering.getClusterList();
    		
    		nbClusters[clusterTable.size()]++;
    		int tailleMax=-1;
    		for(i=0;i<clusterTable.size();i++)
    	    {
    			if (((jet.cluster.data.Cluster)clusterTable.get(i)).getCoreIndex().size()>tailleMax)
    				tailleMax=((jet.cluster.data.Cluster)clusterTable.get(i)).getCoreIndex().size();
    	    }
    		if (tailleMax!=-1) tailleClusterMax[tailleMax]++;
    		nbIteration--;
        }
    	Vector statistique=new Vector(2);
    	statistique.add(nbClusters);
    	statistique.add(tailleClusterMax);
    	return statistique;
    }
    
    /** Génération aléatoire de clusters sur la proteine ref. La génération est faite nbIteration fois.
     * Les clusters sont étendus tant que la somme de leur taille couvre moins de coverage de la surface. 
     *  La distribution des tailles de clusters et du nombre de cluster est retournée. */
    
    public static Vector randomMap(jet.data.datatype.Sequence3D ref, Vector surface, float radius,double coverage,int nbIteration)
    {

	jet.cluster.Clustering clustering=new jet.cluster.Clustering(ref,radius);

	Vector index=new Vector(1,1), indexTemp=new Vector(1,1),indexSurf=new Vector(1,1),clusterTable;
	int i;
	
	int[] tailleClusterMax=new int[ref.size()+1];
	int[] nbClusters=new int[ref.size()+1];
	
	for (i=0;i<ref.size()+1;i++)
	{
		tailleClusterMax[i]=0;
		nbClusters[i]=0;
	}
	
	for (i=0;i<surface.size();i++) if (((Double)surface.get(i)).doubleValue()==1.0) indexSurf.add(i);
	
	while(nbIteration>0)
	{
		indexTemp.clear();
		index.clear();
		for (i=0;i<indexSurf.size();i++)
		{
			indexTemp.add(indexSurf.get(i));
		}
		int rand;
		while(indexTemp.size()>indexSurf.size()*(1.0-coverage))
		{
			rand=(int)(Math.random()*(double)indexTemp.size());
			index.add(indexTemp.remove(rand));
		}
		clustering.cluster(index);
		clusterTable=clustering.getClusterList();
		
		nbClusters[clusterTable.size()]++;
		int tailleMax=-1;
		for(i=0;i<clusterTable.size();i++)
	    {
			if (((jet.cluster.data.Cluster)clusterTable.get(i)).getCoreIndex().size()>tailleMax)
				tailleMax=((jet.cluster.data.Cluster)clusterTable.get(i)).getCoreIndex().size();
	    }
		if (tailleMax!=-1) tailleClusterMax[tailleMax]++;
		nbIteration--;
    }
	Vector statistique=new Vector(2);
	statistique.add(nbClusters);
	statistique.add(tailleClusterMax);
	return statistique;
    }
  
    /** Calcul de la valeur ayant pour Pvaleur seuil (ou 1-Pvaleur seuil en fonction le booleen max) 
     * sur la distribution statistique. */
    
    public static int atConfidence(double seuil, int[] statistique, boolean max)
    {
    	if ((seuil>=0.0)&&(seuil<=1.0))
    	{
	    	int somme=0, sommeSeuil=0;
	    	int i,sens;
	    	String signe;
	    	for (i=0;i<statistique.length;i++) somme=somme+statistique[i];
	    	
	    	if (max) 
	    	{
	    		i=statistique.length-1;
	    		sens=-1;
	    		signe=">";
	    	}
	    	else
	    	{
	    		i=0;
	    		sens=1;
	    		signe="<";
	    	}	
	    	sommeSeuil=sommeSeuil+statistique[i];
	    	while ((double)sommeSeuil<((double)somme*(double)seuil))
	    	{	
	    		i=i+sens;
	    		sommeSeuil=sommeSeuil+statistique[i];
	    	}
	    	return i-sens;
    	}
    	else
    	{
    		System.err.println("Le seuil de confiance doit etre entre 0 et 1");
    		return -1;
    	
    	}
    }
    
    /** Calcul de la Pvaleur (ou de 1-Pvaleur en fonction le booleen max) 
     * de valeur sur la distribution statistique. */
    
    public static double whichConfidence(int valeur, int[] statistique, boolean max)
    {
	    int somme=0, sommeSeuil=0;
	    int i,sens;
	    String signe;
	    for (i=0;i<statistique.length;i++) somme=somme+statistique[i];
	    	
	    if (max) 
	    {
	    	i=statistique.length-1;
	    	sens=-1;
	    	signe=">";
	    }
	    else
	    {
	    	i=0;
	    	sens=1;
	    	signe="<";
	    }	
	    sommeSeuil=sommeSeuil+statistique[i];
	    while (i!=valeur)
	    {	
	    	i=i+sens;
	    	sommeSeuil=sommeSeuil+statistique[i];
	    }
	    return ((double)sommeSeuil/(double)somme);
    	
    }
    
    /** Calcul de la moyenne des scores de la distribution statistique */
    
    public static double mean(int[] statistique)
    {
    	double mean=0;
    	int nb=0;
	    for(int i=0;i<statistique.length;i++)
	    {
	    	nb=nb+statistique[i];
	    	mean=mean+(double)statistique[i]*(double)i;
	    }
    	return mean/(double)nb;
    	
    }
    
    /** Elimination des résidus (index) dont le score (traceMoy) est inférieur minTraceResidu  */
    
    public static Vector filtrerScore (Vector traceMoy, Vector index, double minTraceResidu)
    {
    	Vector indexFiltrer=new Vector(1,1);
    	int i;
    	for(i=0;i<index.size();i++)
    	{		

    		if(((Double)traceMoy.get(((Integer)index.get(i)))).doubleValue()>minTraceResidu)
    		{
    			indexFiltrer.add(index.get(i));
    		}
    	}
    	return indexFiltrer;
    }
    
    /** Tri des résidus (index) en fonction de leur score (traceMoy) */
    
    public static Vector trierScore (Vector traceMoy, Vector index)
    {
    	Vector indexTri=new Vector();
    	int i,j;
    	Double val1,val2;
    	for(i=0;i<index.size();i++)
    	    {
    		val1=(Double)traceMoy.get(((Integer)index.get(i)).intValue());

    			for(j=0;j<indexTri.size();j++)
    			    {
    				val2=(Double)traceMoy.get(((Integer)indexTri.get(j)).intValue());
    				if(val1.doubleValue()>val2.doubleValue())
    				    {
    					indexTri.add(j,((Integer)index.get(i)).intValue());
    					break;
    				    }
    				
    			    }
    			if(j==indexTri.size()) indexTri.add(((Integer)index.get(i)).intValue());
    		    
    	    }
    	return indexTri;
    }
    
    /** initialisation à 0.0 d'un vecteur de taille size */
    
    public static Vector fillVector(int size)
    {
	int i;
	Vector v=new Vector(size);
	for(i=0;i<size;i++) v.add(new Double(0.0)); 
	return v;
    }
    
}
