/***************************************************************************
                          jeupop.cpp  -  Librairie d'objets permettant de manipuler des donn�es
                          						sp�cifiques aux populations
                             -------------------
    begin                : ven sep 06 10:25:55 CEST 2000
    copyright            : (C) 2000 by Olivier Langella CNRS UPR9034
    email                : Olivier.Langella@pge.cnrs-gif.fr
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/



#include "jeupop.h"
#include "distgnt.h"

//constructeur
Jeupop::Jeupop () {

//cerr << "Jeupop::Jeupop ()  debut" << endl;


	_nbpop = 0;
	_nbloc = 0;
	_nploidie = 0;

	_tabPpop.resize(0);
	_tabPloc.resize(0);

	_Pracinepops = new MetaPop(this);
//cerr << "Jeupop::Jeupop ()  fin" << endl;
}

/*Jeupop::Jeupop (long nbpop, long nbloc) {
	long i;


	_nbpop = nbpop;
	_nbloc = nbloc;
	_nploidie = 0;

	_tabPpop.resize(0);
	_tabPloc.resize(0);
//	_tabPpop = new (Population*[nbpop]);
//	_tabPloc = new (Locus*[nbloc]);

	for (i=0;i < nbpop;i++) _tabPpop.push_back(new Population (this));
	for (i=0;i < nbloc;i++) _tabPloc.push_back(new Locus (this,0));

	_Pracinepops = new MetaPop(this);

}
*/
Jeupop::Jeupop(const Jeupop& original) {
	//constructeur de copies
	unsigned long i;

//cerr << "Jeupop::Jeupop construct copie debut " << endl;
	_nploidie = original.get_nploidie();
	_commentaires = original._commentaires;

//cerr << "Jeupop::Jeupop construct delete _Pracine " << endl;
//	delete _Pracinepops;
//cerr << "Jeupop::Jeupop construct delete _Pracine " << endl;
	_tabPpop.resize(0);
//cerr << "Jeupop::Jeupop construct delete _Pracine " << endl;
//	for (i=0;i < _tabPloc.size();i++) delete (_tabPloc[i]);
	_tabPloc.resize(0);


 	_nbloc = original.get_nbloc();
	for (i=0;i < _nbloc;i++) {
//cerr << "Jeupop::Jeupop construct copie locus " << endl;
		_tabPloc.push_back(new Locus (*original._tabPloc[i], this));
	}

//cerr << "Jeupop::Jeupop construct copie metapop " << endl;
	_Pracinepops = new MetaPop(*original._Pracinepops,0, this);
//cerr << "Jeupop::Jeupop construct copie fin " << endl;
}

//destructeur
Jeupop::~Jeupop () {
	unsigned long i;

	//for (i=0;i < _tabPpop.size();i++) delete (_tabPpop[i]);
	for (i=0;i < _tabPloc.size();i++) delete (_tabPloc[i]);

	delete _Pracinepops;
}


void Jeupop::reset() {

	unsigned long i;

//cerr << "Jeupop::reset(long nbpop, long nbloc) debut"<< endl;
	_nbloc = _tabPloc.size();
	delete _Pracinepops;
	_tabPpop.resize(0);
	_nbpop = 0;

	for (i=0;i < _nbloc;i++) delete (_tabPloc[i]);
	_nbloc = 0;
	_tabPloc.resize(0);
	_VcalcStrucPop.resize(0);
	_VcalcLocus.resize(0);

	
	_Pracinepops = new MetaPop(this);	

//cerr << "Jeupop::reset(long nbpop, long nbloc) fin" << endl;

}


void Jeupop::oGenepopCano(ostream& sortie) const{
	//�criture de fichiers au format genepop
	//    type canonique (avec Pop nomdepop)
// pas adapt�e � un traitement sur fichiers haploides
	unsigned long i,j;
	char car(0);
	unsigned long nbpop(get_nbpop());
	unsigned long nbloc(get_nbloc());
	unsigned long nbind;
	int format(1);

	if (_nploidie != 2) {
		//le format Genepop ne permet que le stockage de pop diplo�des
		throw Anomalie(1);
	}

	if (!(f_verifnum(1))) {
		//il faut renum�roter les all�les pour le format genepop
		throw Anomalie(2);
	}


	//commentaires
	car = '"';
	if (_commentaires.size() == 0) sortie << car << endl;
	else {
		sortie << _commentaires.get_titre(0) << endl;
		for (i=1; i < _commentaires.size(); i++) {
			sortie << car << _commentaires.get_titre(i) << endl;
		}
	}

	//nom des locus
	for (i=0; i < nbloc;i++) {
		sortie << _tabPloc[i]->get_nom() << endl ;
	}

	// populations
	for (i=0; i < nbpop;i++) {
		sortie << "POP " << _tabPpop[i]->get_nom_chemin() << endl ;
		// individus
		if (_tabPpop[i]->_tabAllIntrogressant.size() > 0) format = 2;
		else format = 1;


		nbind = _tabPpop[i]->get_nbind();
		for (j=0; j < nbind;j++) {
			_tabPpop[i]->_tabPind[j]->affiche(sortie,format);
			sortie << endl;
		}
	}
	
}

void Jeupop::oGenepop(ostream& sortie) const{
	//�criture de fichiers au format genepop
// pas adapt�e � un traitement sur fichiers haploides
	long i,j;
	char car;
	long nbpop(get_nbpop());
	long nbloc(get_nbloc());
	long nbind;
	int format(1);

	if (_nploidie != 2) {
		//le format Genepop ne permet que le stockage de pop diplo�des
		throw Anomalie(1);
	}

	if (!(f_verifnum(1))) {
		//il faut renum�roter les all�les pour le format genepop
		throw Anomalie(2);
	}


	//nom des populations
	car = '"';
	sortie << car;

	i = 0;
	for (i=0; i < (nbpop-1);i++) {
		sortie << _tabPpop[i]->get_nom() << ";" ;
	}
	sortie << _tabPpop[i]->get_nom() << car << endl;


	//nom des locus
	for (i=0; i < nbloc;i++) {
		sortie << _tabPloc[i]->get_nom() << endl ;
	}

	// populations
	for (i=0; i < nbpop;i++) {
		sortie << "POP" << endl ;
		// individus
		if (_tabPpop[i]->_tabAllIntrogressant.size() > 0) format = 2;
		else format = 1;

		nbind = _tabPpop[i]->get_nbind();
		for (j=0; j < nbind;j++) {
			_tabPpop[i]->_tabPind[j]->affiche(sortie,format);
			sortie << endl;
		}
	}
	
}

void Jeupop::oPopulations(ostream& sortie) const{
	//�criture de fichiers au format populations
// adapt� � toutes les ploidies
	unsigned long i,j;
	char car;
	unsigned long nbpop(get_nbpop());
	unsigned long nbloc(get_nbloc());
	unsigned long nbind;
	int format(3);

	//commentaires
//cerr << "Jeupop::oPopulations(ostream& sortie)" << _commentaires.size()  << "comm size" << endl;
	car = '"';
	if (_commentaires.size() == 0) sortie << car << endl;
	else {
		for (i=0; i < _commentaires.size(); i++) {
			sortie << car << _commentaires.get_titre(i) << endl;
		}
	}

//	sortie << _tabPpop[i]->get_nom() << car << endl;


	//nom des locus
	for (i=0; i < nbloc;i++) {
		sortie << _tabPloc[i]->get_nom() << endl ;
	}
//cerr << "Jeupop::oPopulations(ostream& sortie) 2" << endl;

	// populations
	for (i=0; i < nbpop;i++) {
		sortie << "POP " << _tabPpop[i]->get_nom_chemin() << endl ;
//cerr << "Jeupop::oPopulations(ostream& sortie) pop " << _tabPpop[i]->get_nom_chemin() << endl;
		// individus
		nbind = _tabPpop[i]->get_nbind();
//cerr << "Jeupop::oPopulations(ostream& sortie) nbind " << nbind << endl;
		for (j=0; j < nbind;j++) {
			_tabPpop[i]->_tabPind[j]->affiche(sortie,format);
			sortie << endl;
		}
	}
//cerr << "Jeupop::oPopulations(ostream& sortie) 3" << endl;
	
}

void Jeupop::oImmanc(ostream& sortie) const{
	//format d'entr�e pour :
	//Immanc - detects individual that are immigrants or have recent immigrant ancestry
    //by using multilocus genotypes. 
    //Version 5.0, released October 8, 1998    
    //Reference: Rannala, B., and J.L., Mountain. 1997. Detecting immigration by using
    //multilocus genotypes. Proceedings of the National Academy of Sciences USA 94:
    //9197-9201. 

// pas adapt�e � un traitement sur fichiers haploides
	if (_nploidie != 2) {
		//le format Immanc ne permet que le stockage de pop diplo�des
		throw Anomalie(1);
	}

	if (!(f_verifnum(1))) {
		//il faut renum�roter les all�les pour le format Immanc
		throw Anomalie(2);
	}

	long i,j,k, nbind, nbloc(get_nbloc()), nbpop(get_nbpop());
	string nomloc; 
	string nompop; 
	for (i=0; i< nbloc-1;i++) {//scan de chaque locus
		nomloc = _tabPloc[i]->_nom;
		for (j=0; j< nbpop;j++) {//scan des pops
			nompop = _tabPpop[j]->get_nom();
			nbind = _tabPpop[j]->get_nbind();
			for (k=0; k < nbind;k++) {// scan des individus
				//nom de l'ind, nom de la pop, nom du locus, les 2 all�les
				sortie << " " << _tabPpop[j]->_tabPind[k]->_nom;
				sortie << " " << nompop;
				sortie << " " << nomloc;
				sortie << " " << _tabPpop[j]->_tabPind[k]->_tabPall[i * 2]->_nom;
				sortie << " " << _tabPpop[j]->_tabPind[k]->_tabPall[(i * 2) + 1]->_nom;
				sortie << " " << endl;
			}
		}
	}	
}

void Jeupop::oMsat(ostream& sortie) const{
	//format d'entr�e pour :
	//distances microsat de D. Goldstein

	if (!(f_verifnum(2))) {
		//les noms d'alleles ne correspondent pas a des tailles de microsat
		throw Anomalie(2);
	}

	// 1 ligne = 1 allele, d'un locus d'un individu

	long i,j,k,l , nbind, nbloc(get_nbloc()), nbpop(get_nbpop());
	long nploidie(get_nploidie());
	string nomind;
	string nomloc; 
	string nomall;

	Individu * Pind;

	for (i=0; i< nbpop;i++) {//scan des pops
		nbind = _tabPpop[i]->get_nbind();
		for (j=0; j< nbind;j++) {// scan des individus
		//	nomind = _tabPpop[i]->_tabPind[j]->get_nom();
			Pind = _tabPpop[i]->_tabPind[j];
			nomind = Pind->get_nom();

			for (k=0; k < nbloc;k++) {// scan des locus
				nomloc = _tabPloc[k]->_nom;

				for (l=0; l < nploidie;l++) {// scan des alleles
					nomall = Pind->get_nom_all(k,l);
					//nom de l'ind, nom de la pop, nom du locus, les 2 all�les
					sortie << nomind << " " << nomloc << " " << nomall << endl;
				}
			}
		}
	}	
}

void Jeupop::oMsatFreq(ostream& sortie) const{
	//format d'entr�e pour :
	//distances microsat de D. Goldstein

	if (!(f_verifnum(2))) {
		//les noms d'alleles ne correspondent pas a des tailles de microsat
		throw Anomalie(2);
	}

	// 1 ligne = 1 allele, d'un locus d'un individu

	long i,k,l , nball, nbloc(get_nbloc()), nbpop(get_nbpop());
//	long nploidie(get_nploidie());
	string nompop;
	string nomloc; 
	string nomall;

//	Individu * Pind;

	for (i=0; i< nbpop;i++) {//scan des pops
		nompop = _tabPpop[i]->get_nom();


		for (k=0; k < nbloc;k++) {// scan des locus
			nomloc = _tabPloc[k]->_nom;
			nball = _tabPloc[k]->get_nball();

			for (l=0; l < nball;l++) {// scan des alleles
				nomall = _tabPloc[k]->_tabPall[l]->get_Nom();
				//nom de l'ind, nom de la pop, nom du locus, les 2 all�les
				sortie << nompop << " " << nomloc << " " << nomall << endl;
				sortie << " " << _tabPpop[i]->r_nbcopall(_tabPloc[k]->_tabPall[l]) << endl;
			}
		}
	}	
}

/*int Jeupop::r_allcommun(Individu * pind1, Individu * pind2, unsigned int numlocus) const{
	//renvoi du nombre d'all�les en commun
	// fonctionne pour N ploides
	Vecteur<Allele*> tabPall1;
	unsigned int i,j;
	long pos;

	j = numlocus * _nploidie;

	for (i = 0; i < _nploidie; i++) {
		tabPall1.push_back(pind1->_tabPall[i+j]);
	}

	for (i = 0; i < _nploidie; i++) {
		pos = tabPall1.Position(pind2->_tabPall[i+j]);
		if (pos != -1) tabPall1.Suppr(pos);
	}

	return (_nploidie - tabPall1.size());
}
*/
/*
int Jeupop::r_allcommunnul(Individu * pind1, Individu * pind2, int numlocus) const{
	//renvoi du nombre d'all�les en commun
	// saute les all�les nuls
	// fonctionne pour N ploides
	Vecteur<Allele*> tabPall1;
	unsigned int i,j;
	int pos;

	j = numlocus * _nploidie;

	for (i = 0; i < _nploidie; i++) {
		tabPall1.push_back(pind1->_tabPall[i+j]);
	}

	for (i = 0; i < _nploidie; i++) {
		if (pind2->_tabPall[i+j]->_nul) {}
		else {
			pos = tabPall1.Position(pind2->_tabPall[i+j]);
			if (pos != -1) tabPall1.Suppr(pos);
		}
	}

	return (_nploidie - tabPall1.size());
}
*/
/*
long Jeupop::r_allcommunnul(Individu * pind1, Individu * pind2) const{
	//renvoi du nombre d'all�les en commun
	// saute les all�les nuls
	// fonctionne pour N ploides
	Vecteur<Allele*> tabPall1;
	int i,pos;
	long taille;

	taille = pind2->_tabPall.size();

	tabPall1 = pind1->_tabPall;

	for (i = 0; i < taille; i++) {
		if (pind2->_tabPall[i]->_nul) {}
		else {
			pos = tabPall1.Position(pind2->_tabPall[i]);
			if (pos != -1) tabPall1.Suppr(pos);
		}
	}

	return (taille - tabPall1.size());
}
*/

void Jeupop::f_rarefaction(MatriceLD& resultat, int effectif) const {

	//calcul de la nouvelle diversit� all�lique, pour un �chantillon
	// r�duit: r�sultats stock�s dans Matrice, int => effectif r�duit
	long i,j;
//	char temp[10];
	int nbloc(get_nbloc());
	int nbpop(get_nbpop());

	resultat.resize(nbpop,nbloc);

	resultat._titre.push_back("Nouvelle diversit� all�lique pour un effectif r�duit de : ");
	
//	resultat._titre[resultat._titre.size()-1] += itoa(effectif,temp,10);
	resultat._titre[resultat._titre.size()-1].AjEntier(effectif);
	resultat.SetType(1);
	resultat.SetFlag(3);

	for (i=0;i<nbloc;i++) {
		resultat._tcol[i] = _tabPloc[i]->_nom;
	}

	for (j=0;j<nbpop;j++) {
		resultat._tlig[j] = _tabPpop[j]->_nom;

		for (i=0;i<nbloc;i++) {
			resultat.GetCase(j,i) = _tabPpop[j]->r_rare(effectif,i);
//	cerr << "coucou";
		}
	}
}



const string & Jeupop::get_nomlocus(long nblocus) const {
	// donne le nom du locus nblocus
	return (_tabPloc[nblocus]->get_nom());
}

const string & Jeupop::get_nompop(long nbpop) const{
	// donne le nom de la populations nbpop
	return (_tabPpop[nbpop]->get_nom());

}

Locus* Jeupop::get_Plocus(const string & nom) const{
	// donne un pointeur sur le locus du nom 'nom'
	Locus* res;
	unsigned long i;

	res = 0;
	for (i=0; i < _tabPloc.size(); i++) {
		if(_tabPloc[i]->_nom == nom) {
			res = _tabPloc[i];
			break;
		}
	}
	if (res == 0) throw Anomalie(8);

	return (res);
}

Locus* Jeupop::get_Plocus(unsigned long i) const {
	// donne le pointeur sur le locus i
	if (i >= _tabPloc.size()) throw Anomalie(8);

	return (_tabPloc[i]);
}

Population* Jeupop::get_Ppop(string & nom) const{
	// donne un pointeur sur le locus du nom 'nom'
	Population* res;
	unsigned long i;

	res = 0;
	for (i=0; i < _tabPpop.size(); i++) {
		if(_tabPpop[i]->_nom == nom) {
			res = _tabPpop[i];
			break;
		}
	}
	if (res == 0) throw Anomalie(9);

	return (res);
}

Population* Jeupop::get_Ppop(unsigned long p) const{
	// donne un pointeur sur la population p
	if (p >= _tabPpop.size()) throw Anomalie(9);

	return (_tabPpop[p]);
}

/*
long double Jeupop::r_dist2pop(long double ** tabFreq1, long double ** tabFreq2, long * tabNbAll, Population * ppop1, Population * ppop2, int methode) const {
	//renvoi de la distance entre 2 Populations
	long double resultat(0);
	long double somme;
	long nbpop1(ppop1->get_nbind()), nbpop2(ppop2->get_nbind());
	long calcsomme(ppop1->get_nbind() * ppop2->get_nbind());
	long i,j;

	if (methode < 100) {
		//distance entre populations bas�e sur distances entre individus
		somme = 0;
		for (i=0; i < nbpop1; i++) {	//scan des individus de la pop1	
			for (j=0; j < nbpop2; j++) {	//scan des individus de la pop2
				try {
					somme += r_dist2ind(ppop1->get_Pind(i), ppop2->get_Pind(j), methode);
				}
				catch (Anomalie erreur) {
					if (erreur.le_pb == 6) calcsomme--;
				}
			}
		}
	
		if (calcsomme < 1) return (0);
		resultat = somme / calcsomme;
	}
	else {
		switch (methode) {
		case 101:
			// Nei's minimum genetic distance (1972)	
			resultat = r_dpopNei(tabFreq1, tabFreq2, tabNbAll, false);
			break;
		case 102:
			// Nei's standard genetic distance (1972)			
			resultat = r_dpopNei(tabFreq1, tabFreq2, tabNbAll, true);
			break;
		case 103:
			// Cavalli-Sforza and Edwards' (1967)			
			resultat = r_dpopCavalli(tabFreq1, tabFreq2, tabNbAll);
			break;

		case 104:
			// Nei et al's, Da (1983)
			resultat = r_dpopNeiDa(tabFreq1, tabFreq2, tabNbAll);
			break;
		case 106:
			// Goldstein et al. (1995a)
			resultat = r_dpopGoldsteinMu(tabFreq1, tabFreq2, tabNbAll);
			break;
		case 107:
			// Latter's Fst (1972)
			resultat = r_dpopFst(tabFreq1, tabFreq2, tabNbAll);
			break;
		case 108:
			// Prevosti et al.'s, Cp (1975)
			resultat = r_dpopPrevosti(tabFreq1, tabFreq2, tabNbAll);
			break;
		case 109:
			// Rogers', Dr (1972)
			resultat = r_dpopRoger(tabFreq1, tabFreq2, tabNbAll);
			break;
		case 110:
			// Goldstein et al. (1995b) Slatkin 1995
			resultat = r_dpopGoldsteinASD(tabFreq1, tabFreq2, tabNbAll);
			break;
		case 111:
			// Shriver et al's, Dsw (1995)
			resultat = r_dpopShriver(tabFreq1, tabFreq2, tabNbAll);
			break;

		}
	}

	return resultat;
}
*/


istream& operator>>(istream& ientree,Jeupop& LesPops) {
	int nbformat(5),i(1);
	char car;
	bool autre(true);

	ientree.get(car);
	if (ientree.fail()) {
		cerr << _("The file is not readable... ") << endl;
		throw Jeupop::Anomalie(5);
	}
	while ((autre) && (i < nbformat)) {
		try {
			ientree.clear();
			ientree.seekg(0);
			LesPops.iFichier(ientree,i);

			autre = false;
		}
		catch (Jeupop::Anomalie erreur) {
			if (erreur.le_pb > 0) {
				autre = true;
				if (i == (nbformat-1)) {
					cerr << _("unknown file format") << endl;
					autre = false;
					throw Jeupop::Anomalie(5);
				}
				erreur.le_pb = 0;
			}
		}
		i++;
	}

	return (ientree);
}

void Jeupop::iFichier(istream & entree, int i) {
//cerr << "Jeupop::iFichier debut " << i << endl;
	switch (i) {
		case 1:
			iPopulationsXML(entree);
//			set_nploidie(_nploidie);
			return;
		case 2:
			iGenepop(entree);
//			set_nploidie(_nploidie);
			return;
		case 3:
			iPopulations(entree);
//			set_nploidie(_nploidie);
			return;
		case 4:
			iGenetix(entree);
//			set_nploidie(_nploidie);
			return;
		default:
			return;
	}
}


void Jeupop::iGenepop(istream &fichier){
	//lecture de fichiers au format genepop
// pas adapt�e � un traitement sur fichiers haploides

//cerr << "Jeupop::iGenepop debut" << endl;
	ChaineFicPop lecturePop(fichier);
	biolib::vecteurs::ChaineCar mot;
	biolib::vecteurs::ChaineCar nomall1;
	biolib::vecteurs::ChaineCar nomall2;

	Titre titres;
	
	Population * Ppop;	
	Individu * Pind;

	unsigned int nbloc,i,j;
	unsigned int nbdigits(0);

//cerr << "Jeupop::iGenepop debut2" << endl;
	// lecture des commentaires
	try {
		lecturePop.get_titre(_commentaires);
	}
	catch (ChaineFicPop::Anomalie pb) {
		throw Anomalie(4);
	}
//cerr << "Jeupop::iGenepop get_titre " << _commentaires[0] << endl;

	reset();

	// lecture des locus
	try {
		lecturePop.get_locus(titres);
	}
	catch (ChaineFicPop::Anomalie pb) {
		throw Anomalie(4);
	}
	nbloc = titres.size();

	for (i=0; i < nbloc; i++) {
		_tabPloc.push_back(new Locus(this, 0));
		_tabPloc.back()->set_nom(titres[i]);
	}
//cerr << "Jeupop::iGenepop locus " << titres[0] << " " << nbloc << " " << _tabPloc.size() << endl;


	//lecture des populations
//	_nploidie = 2;
	set_nploidie(2);

	while (lecturePop.estunepop()) {
		//creation d'une nouvelle population
//cerr << "Jeupop::iGenepop get_nompop(mot) " << mot << endl;
		lecturePop.get_nompop(mot);
//cerr << "Jeupop::iGenepop get_nompop(mot) " << mot << endl;

		Ppop = NewPop(mot);
//cerr << "Jeupop::iGenepop get_nompop(mot) " << mot << endl;
		
		try {
			if (lecturePop.get_lignepop()==1) break;
		}
		catch (ChaineFicPop::Anomalie pb) {
			throw Anomalie(4);
		}
		while (lecturePop.estunindividu()) {
			//creation d'un nouvel individu
			lecturePop.get_nomind(mot);
			Pind = new Individu(_tabPpop.back(), mot);
			Ppop->AjouterIndividu(Pind);

			lecturePop.get_alleles(titres);

			if (titres.size() != nbloc) {//erreur
				cout << endl;
				cout << _("error in data file.") << endl;
				cout << _("wrong number of locus at line : ") << lecturePop.get_numeroligne() << endl;

				throw Anomalie(4);
			}
				
			//enregistrement de chaque locus
			for (i=0; i < nbloc; i++) {
				mot = titres[i];
				if (nbdigits == 0) nbdigits = (mot.size() / 2);
				if (nbdigits == 1) {
					throw Anomalie(4);
				}
				if (mot.size() != (nbdigits * 2)) {
					throw Anomalie(4);
				}
				if (mot.EstUnChiffre() == false) {
					throw Anomalie(4);
				}

				nomall1.assigner(mot, 0, nbdigits - 1);
				nomall2.assigner(mot, nbdigits, (nbdigits * 2) - 1);

				Pind->_tabPall[i*2] = _tabPloc[i]->getPall(nomall1);
				if (Pind->_tabPall[i*2] == 0) {
					Pind->_tabPall[i*2] = new Allele(_tabPloc[i], nomall1);
					_tabPloc[i]->_tabPall.push_back(Pind->_tabPall[i*2]);
				}

				Pind->_tabPall[i*2 + 1] = _tabPloc[i]->getPall(nomall2);
				if (Pind->_tabPall[i*2 + 1] == 0) {
					Pind->_tabPall[i*2 + 1] = new Allele(_tabPloc[i], nomall2);
					_tabPloc[i]->_tabPall.push_back(Pind->_tabPall[i*2 + 1]);
				}
			}

			try {
				if (lecturePop.get_lignepop()==1) break;
//				lecturePop.get_lignepop();
			}
			catch (ChaineFicPop::Anomalie pb) {
				throw Anomalie(4);
			}
		}//lecture est un individu
	}

	// traitement sp�cifique au cas des fichiers JM Cornuet
	if (lecturePop.get_boolnompop() == false) { //il n'y avait pas de noms de pop
		// derriere le mot cle pop => tentative d'extraction style JMC
//cerr << "coucou";

		// lecture des noms de populations dans les commentaires
		for (i=0,j=0; i < _commentaires.size(); i++) {
//cerr << "coucou " << _commentaires[i].GetNbMots(",") << " " << _tabPpop.size();
			if (_commentaires[i].GetNbMots(",") == _tabPpop.size()) {
				//extraction des noms;
				for (j=0; j < _tabPpop.size(); j++) {
					_commentaires[i].GetMot(j+1,_tabPpop[j]->_nom,",");
				}
				break;
			}
		}

		if (j ==  0) {
			//il n'y a vraiment pas de noms... on num�rote
			for (i=0; i < _tabPpop.size(); i++) {
				if (_tabPpop[i]->_nom == "") {
          ostringstream tampon;
					tampon << "POP_";
					tampon << (i+1);
          _tabPpop[i]->_nom = tampon.str();
				}
			}
		}
	}
}


void Jeupop::iPopulations(istream &fichier){
	//lecture de fichiers au format Populations
// adapt�s � un traitement sur fichiers haploides
// 
// modification du 31/07/2000:
// rajout du mot cl� "DIFF" (nom d'all�le) qui permet de compter comme diff�rents 2 all�les
// utile pour le traitement de donn�es RFLP
// 
// refait le 07/9/2000

	ChaineFicPop lecturePop(fichier);
	biolib::vecteurs::ChaineCar mot;
	biolib::vecteurs::ChaineCar nomall;

	Titre titres;
	
	Population * Ppop;	
	Individu * Pind;
	Allele * Palldiff;
	Allele * Pall;

	bool allestintrogressant(false);

	unsigned int nbloc,i, j;

	// lecture des commentaires
	try {
		lecturePop.get_titre(_commentaires);
	}
	catch (ChaineFicPop::Anomalie pb) {
		throw Anomalie(4);
	}
//cerr << "Jeupop::iGenepop get_titre " << _commentaires[0] << endl;

	reset();

	// lecture des locus
	try {
		lecturePop.get_locus(titres);
	}
	catch (ChaineFicPop::Anomalie pb) {
		throw Anomalie(4);
	}
	_nbloc = nbloc = titres.size();

	for (i=0; i < nbloc; i++) {
		_tabPloc.push_back(new Locus(this, 0));
		_tabPloc.back()->set_nom(titres[i]);
	}
//cerr << "Jeupop::iGenepop locus " << titres[0] << " " << nbloc << " " << _tabPloc.size() << endl;


	//lecture des populations
	_nploidie = 0; //pas encore d�termin�

	while (lecturePop.estunepop()) {
		//creation d'une nouvelle population
		lecturePop.get_nompop(mot);
		Ppop = NewPop(mot);
		
		try {
			if (lecturePop.get_lignepop()==1) break;
//			lecturePop.get_lignepop();
		}
		catch (ChaineFicPop::Anomalie pb) {
			throw Anomalie(4);
		}
		while (lecturePop.estunindividu()) {
			//creation d'un nouvel individu
			//
			lecturePop.get_nomind(mot);
			
			Pind = new Individu(Ppop, mot);
			Ppop->AjouterIndividu(Pind);
		
//cerr << "Jeupop::iGenepop lecture: " <<lecturePop << endl;
//			lecturePop.get_nomind(Pind->_nom);
//cerr << "Jeupop::iGenepop individu: " << Pind->_nom << endl;


			lecturePop.get_alleles(titres);
//cerr << "Jeupop::iGenepop alleles : " << titres.size() << endl;
//for (j =0 ; j < titres.size(); j++) cerr << titres[j] << " ";
			if (titres.size() != nbloc) {//erreur
				cout << endl;
				cout << _("error in data file.") << endl;
				cout << _("wrong number of locus at line : ") << lecturePop.get_numeroligne() << endl;

				throw Anomalie(4);
			}
//cerr << "Jeupop::iPopulations nbloc " <<nbloc << endl;				
			//enregistrement de chaque locus
			for (i=0; i < nbloc; i++) {
				mot = titres[i];
//cerr << "Jeupop::iPopulations mot " << mot << endl;				
				if (_nploidie == 0) {
					set_nploidie(mot.GetNbMots(":"));
					//Ppop->set_nploidie();
				}
				
//cerr << "Jeupop::iPopulations set_nploidie : " << mot.GetNbMots(":") << " "<< _nploidie << endl;
				if (mot.GetNbMots(":") != _nploidie) {//erreur
					cout << endl;
					cout << _("error in data file.") << endl;
					cout << _("wrong number of alleles at line : ") << lecturePop.get_numeroligne() << endl;

					throw Anomalie(4);
				}

				Palldiff = 0;
				for (j = 0; j < _nploidie; j++) { //boucle pour chaque allele d'un locus
					Pall = 0;
					allestintrogressant = false;
					
					mot.GetMot(j+1 ,nomall, ":");
					//cas des alleles introgressants:
					// marqu�s par une *
					if (nomall[0] == '*') {
//cerr << "Jeupop::iPopulations all introgressant" << endl;
						allestintrogressant = true;
						nomall.erase(0,1);
					}
//cerr << "Jeupop::iPopulations nomall" <<  nomall << endl;
				
					if ((Palldiff == 0) && (nomall == "DIFF")) {
						// creation d'un allele diff�rent pour ce locus pour cet individu
						Pall = Palldiff = new Allele(_tabPloc[i], "DIFF");
						Pind->_tabPall[i*_nploidie + j] = Palldiff;
						_tabPloc[i]->_tabPall.push_back(Palldiff);
					}
					else {
						if (nomall == "DIFF") {
							// assignation de l'all�le diff�rent
							Pind->_tabPall[i*_nploidie + j] = Pall = Palldiff;
						}
						else {
							// recherche de l'allele
							Pall = Pind->_tabPall[i*_nploidie + j] = _tabPloc[i]->getPall(nomall);
							
							if (Pall == 0) {
								// si la recherche n'a rien donner: creation de l'all�le
								Pall = Pind->_tabPall[i*_nploidie + j] = new Allele(_tabPloc[i], nomall);
								_tabPloc[i]->_tabPall.push_back(Pall);

							}
						}
					}

					if (allestintrogressant) {
						// si il n'est pas deja not� dans le tableau de la pop, l'indiquer
//cerr << "Jeupop::iPopulations all introgressant" << endl;
						Ppop->AjouterAllIntrogressant(Pall);
					//	allestintrogressant = false;
					}					
				}

			}

//Pind->affiche(cout,1);
			
			try {
				if (lecturePop.get_lignepop()==1) break;
//				lecturePop.get_lignepop();
			}
			catch (ChaineFicPop::Anomalie pb) {
				throw Anomalie(4);
			}
		} // boucle while (lecturePop.estunepop())
	} // boucle while (lecturePop.estunepop())
	
	// lecture des noms de populations dans les commentaires

/*	for (i=0; i < _tabPpop.size(); i++) {
		if (_tabPpop[i]->_nom == "_") {
			_tabPpop[i]->_nom = "POP_";
			_tabPpop[i]->_nom.AjEntier(i+1);
		}
	}*/
}

bool Jeupop::f_verifnum(int typedenum) const {
	// V�rification du type de num�rotation des all�les
//	1 => type Genepop stricte (2digits)
//	2 => nom d'alleles = num�ros
//	3 => nom d'alleles = num�ros < 999
		//Anomalie 2-> les num�ros d'all�les format genepop ne sont pas pr�sents

	long nbloc(get_nbloc());
	long i;

	for (i=0; i < nbloc; i++) {
		if (!(_tabPloc[i]->f_verifnum(typedenum))) return(false);
	}

	return(true);
}

void Jeupop::f_rempliVcalcStrucPop(unsigned int niveau) {
	// remplir le tableau _VcalcStrucPop,
	// en vue de calcul sur des m�tapopulations (ex: DistGnt)
	unsigned long i;

	f_resetVcalcStrucPop();
//cerr << "Jeupop::f_rempliVcalcStrucPop(unsigned int niveau) debut" << endl;
//	if (_VcalcStrucPop.size() != 0) return;

	if (niveau == 100) {
		//Populations normales
		_VcalcStrucPop.resize(_tabPpop.size());

		for (i = 0; i < _VcalcStrucPop.size(); i++) _VcalcStrucPop[i] = _tabPpop[i];
		return;
		
	}
	//cerr << "Jeupop::f_rempliVcalcStrucPop(unsigned int niveau) " << niveau << endl;
	_Pracinepops->f_rempliTabStrucPop(_VcalcStrucPop, niveau);

//cerr << "Jeupop::f_rempliVcalcStrucPop(unsigned int niveau)" << endl;
//for (i = 0; i < _VcalcStrucPop.size(); i++) cerr << _VcalcStrucPop[i]->get_nom();

}

void Jeupop::f_trad2Gpop(ostream& tableCorrespondances) {

	long nbloc(get_nbloc());
	long i;

// 1-> op�ration possible seulement sur les diploides
	if (get_nploidie() != 2) throw Anomalie(1);

	//verification sur le nombre d'alleles maximum (99)
	//pas fait
	tableCorrespondances << "correspondances Anciens_Noms <---> Noms_Genepop" << endl;
	for (i=0; i < nbloc; i++) {
		_tabPloc[i]->f_trad2Gpop(tableCorrespondances);
	}
}

void Jeupop::ifAjouterLocus(const Locus * Ploc) {
	//ajout d'un locus dans une pop, avec les alleles correspondants
	// => recherche un locus preexistant
	long i, taille(_tabPloc.size()), nbloc(-1);
	string nomloc;
	nomloc = Ploc->get_nom();

	for (i = 0 ; i < taille; i++) {
		if (nomloc == get_nomlocus(i)) {
			nbloc = i;
			break;
		}
	}
	if (nbloc >= 0) { //le locus existe deja
		//il faut ajouter les alleles que l'original n'a pas
		taille = Ploc->get_nball();
		for (i = 0; i < taille; i++ ){
			get_Plocus(nbloc)->ifAjouterAllele(Ploc->getPall(i));
		}
	}
	else { //il faut le creer, avec les alleles du nouveau locus
		_tabPloc.push_back(new Locus(*Ploc, this));
	}

	_nbloc = _tabPloc.size(); //precaution
}

/*void Jeupop::ifAjouterPop(const Population * Ppop) {
	//ajout d'un population dans un jeupop, avec les individus correspondants
	// => recherche d'une population preexistante
	long i, taille(get_nbpop()), nbpop(-1);
	const string nompop(Ppop->get_nom());

	for (i = 0 ; i < taille; i++) {
		if (nompop == get_nompop(i)) {
			nbpop = i;
			break;
		}
	}
	if (nbpop >= 0) { //la population existe deja
		//il faut ajouter les individus que l'original n'a pas
		// et completer les alleles des individus preexistants
		// pb � r�soudre: incoh�rence entre alleles d'un meme locus,
		//   d'un meme individu...
		get_pop(nbpop)->_nploidie = get_nploidie();
		get_pop(nbpop)->_nbloc = 0;// _Pjeu->get_nbloc();

		get_pop(nbpop)->resize_loc();

		taille = Ppop->get_nbind();
		for (i = 0; i < taille; i++ ){

//cerr << "if	ajouterpop" << endl;
			get_pop(nbpop)->ifAjouterIndividu(Ppop->get_Pind(i));
		}
	}
	else { //il faut creer une nouvelle population
		_tabPpop.push_back(new Population(this, *Ppop));
	}
}

*/
/*
Jeupop Jeupop::operator+ (const Jeupop &rval) const {
	long i , taille;

	if (get_nploidie() != rval.get_nploidie()) throw Anomalie(7);
	//	if (_nc != rval._nc) throw Anomalie(4);
//	for (i=0; i < rval._commentaires.size(); i++) {
//cerr << rval.GetTitre(i);
//		_commentaires.push_back(rval._commentaires.GetTitre(i));
//	}

//cerr << _commentaires[0] << " " << _commentaires[1];

	Jeupop Resultat;
	//on peut fixer la ploidie, et commencer � remplir Resultat
	// avec le 1er jeu de populations:
//cerr << "operator + debut " << endl;
	Resultat = *this;

	Resultat._commentaires = _commentaires + rval._commentaires;
	// Il faut savoir combien de locus differents comportera le r�sultat
	// => parcours du tableau de locus du 2eme JeuPop
	taille = rval.get_nbloc();
	for (i = 0; i < taille; i++) {
//cerr << "ajout locus " << i << endl;
		Resultat.ifAjouterLocus(rval.get_Plocus(i));
	}

	// A ce stade, Resultat contient tout le 1er jeupop 
	//    et tous les locus et alleles du 2eme
	//   Il faut maintenant remplir les populations de resultat
	taille = rval.get_nbpop();
	for (i = 0; i < taille; i++) {
//cerr << "ajout pop " << i << endl;
		Resultat.ifAjouterPop(rval.get_pop(i));
	}

	taille = Resultat.get_nbpop();
	for (i = 0; i < taille; i++) {
//cerr << "resize " << i << endl;
		Resultat.get_pop(i)->resize_loc();
	}

//cerr << "operator + fin " << endl;
	return Resultat;

}*/


void Jeupop::f_BootstrapLocus(Arbre &arbreRef, int methodeArbre, int methodeDist, bool square_distance, int nbrepet,bool sur_ind, Vecteur<unsigned int> * PVcalcLocus) {
	// Boostrap sur les locus => arbre d'individus si sur_ind est vrai
	// Boostrap sur les locus => arbre de populations si sur_ind est faux
	// ********creer des exceptions pour v�rifier l'arbreRef *********

	DistancesGnt distgnt(methodeDist, square_distance, this);
	unsigned long i;

// pr�paration de _VcalcLoc:
	if (PVcalcLocus == NULL) {
		PVcalcLocus = new Vecteur<unsigned int>;
		_VcalcLocus.resize(get_nbloc());
		PVcalcLocus->resize(get_nbloc());
		for (i = 0; i < _VcalcLocus.size(); i ++) {
			_VcalcLocus[i] = i;
			PVcalcLocus->operator[](i) = i;
		}
	}

	try {
		distgnt.f_bootstrapLocus(arbreRef, methodeArbre, nbrepet, PVcalcLocus, sur_ind);
	}
	catch (DistancesGnt::Anomalie lepb) {
		cerr << endl << lepb.fmessage() << endl;
		throw Anomalie(101);
	}
}

void Jeupop::f_BootstrapIndividus(Arbre &arbreRef, int methodeArbre, int methodeDist, bool square_distance, int nbrepet, Vecteur<unsigned int> * PVcalcLocus) {
	// Boostrap sur les locus => arbre d'individus si sur_ind est vrai
	// Boostrap sur les locus => arbre de populations si sur_ind est faux
	// ********creer des exceptions pour v�rifier l'arbreRef *********

	DistancesGnt distgnt(methodeDist, square_distance, this);
	unsigned long i;

// pr�paration de _VcalcLoc:
	if (PVcalcLocus == NULL) {
		PVcalcLocus = new Vecteur<unsigned int>;
		_VcalcLocus.resize(get_nbloc());
		PVcalcLocus->resize(get_nbloc());
		for (i = 0; i < _VcalcLocus.size(); i ++) {
			_VcalcLocus[i] = i;
			PVcalcLocus->operator[](i) = i;
		}
	}

	try {
		distgnt.f_bootstrapIndividus(arbreRef, methodeArbre, nbrepet, PVcalcLocus);
	}
	catch (DistancesGnt::Anomalie lepb) {
		cerr << endl << lepb.fmessage() << endl;
		throw Anomalie(101);
	}
}

void Jeupop::f_distgntpop (MatriceLD &resultat,int methode, bool square_distance, unsigned int niveau, Vecteur<unsigned int> *PVcalcLocus) {
//cerr << "Jeupop::f_distgntpop debut" << endl;
	//distances G�n�tiques entre Populations 
	DistancesGnt distgntpop(methode, square_distance, this, niveau);
	unsigned long i;

// pr�paration de _VcalcLoc:
	if (PVcalcLocus == NULL) {
		_VcalcLocus.resize(get_nbloc());
		for (i = 0; i < _VcalcLocus.size(); i ++) {
			_VcalcLocus[i] = i;
		}
	}
	else {
		_VcalcLocus = *PVcalcLocus;
	}
//cerr << "Jeupop::f_distgntpop 1" << endl;

	try {
		distgntpop.f_distgntpop(resultat, &_VcalcLocus);
	}
	catch (DistancesGnt::Anomalie lepb) {
		cerr << endl << lepb.fmessage() << endl;
		throw Anomalie(101);
	}

//cerr << "Jeupop::f_distgntpop fin" << endl;

}

void Jeupop::f_distgnt (MatriceLD &resultat,int methode, bool square_distance,  Vecteur<unsigned int> *PVcalcLocus) {
	//distances G�n�tiques entre individus 
	DistancesGnt distgntind(methode, square_distance, this);
	unsigned long i;
// pr�paration de _VcalcLoc:
//cerr << "f_distgnt (jeupop) deb" << endl;
	if (PVcalcLocus == NULL) {
		_VcalcLocus.resize(get_nbloc());
		for (i = 0; i < _VcalcLocus.size(); i ++) {
			_VcalcLocus[i] = i;
		}
	}
	else {
		_VcalcLocus = *PVcalcLocus;
	}

//	f_distgntVcalc (resultat, methode);
	
	try {
		distgntind.f_distgntInd(resultat, &_VcalcLocus);
	}
	catch (DistancesGnt::Anomalie lepb) {
		cerr << endl << lepb.fmessage() << endl;
		throw Anomalie(101);
	}
//cerr << "f_distgnt (jeupop) fin" << endl;

}


/*long Jeupop::get_numloc(Locus * Ploc) const {
	long i;
	
	for (i= 0; i < _nbloc; i++) {
//		cerr << "getnumloc" << endl;
		if (_tabPloc[i] == Ploc) return (i);
	}
	return (-1);
}*/



Population* Jeupop::get_pop(unsigned long numpop) const{
	if (numpop < get_nbpop()) { //ok
		return(_tabPpop[numpop]);
	}
	else {
		return (0);
	}
}

unsigned int Jeupop::get_nploidie() const {
	return(_nploidie);
}

unsigned long Jeupop::get_nbloc() const {
	return(_tabPloc.size());
}

unsigned long Jeupop::get_nbpop() const {
	return(_tabPpop.size());
}

unsigned long Jeupop::get_nbind() const {
	return(_Pracinepops->get_nbind());
}

/*Allele* Jeupop::get_Pall(int loc, int all) const {
	return(_tabPloc[loc]->_tabPall[all]);
}
*/

Allele* Jeupop::get_Pall(unsigned long loc, unsigned long all) const {
	return(_tabPloc[loc]->_tabPall[all]);
}

void Jeupop::get_nomniveauxstruc(Titre & nom_niveaux) const {

	_Pracinepops->get_nomniveauxstruc(nom_niveaux);
	
}


void Jeupop::set_nploidie(unsigned int nploidie) {
	_nploidie = nploidie;
	_nbloc = get_nbloc();

//cerr << "Jeupop::set_nploidie " << _nploidie << " " << _nbloc << endl;
	_Pracinepops->set_nploidie();
//cerr << "Jeupop::set_nploidie fin" << _nploidie << " " << _nbloc << endl;
}


void Jeupop::AjouterPopulation(Population * Ppop) {
//	_tabPpop.push_back(Ppop);
  //AjouterTabPop(Ppop);
	_Pracinepops->AjouterPopulation(Ppop);
}

void Jeupop::AjouterTabPop(Population * Ppop) {
	_tabPpop.push_back(Ppop);
	_nbpop++;
//	_Pracinepops->AjouterPopulation(Ppop);
}

Locus * Jeupop::new_locus(const string & name) {
  Locus * Plocus (new Locus(this, 0));
  Plocus->set_nom(name);
  _tabPloc.push_back(Plocus);
  return (Plocus);
}

Population * Jeupop::NewPop(const biolib::vecteurs::ChaineCar & chemin) {
// cr�ation de Population et de MetaPop en fonction du chemin
	Titre tabchemin;
	biolib::vecteurs::ChaineCar mot;
	unsigned long i;
	MetaPop * Pmetapop(_Pracinepops);
	Population * Ppop;

//cerr << "Jeupop::NewPop(ChaineCar & chemin) d�but " << endl;

	mot.assign("");

	for (i = 0; i < chemin.GetNbMots("/"); i ++) {
		chemin.GetMot(i+1,mot, "/");
		if (mot == "") continue;
		tabchemin.push_back(mot);
	}

	if (tabchemin.size() > 0) {
		for (i = 0; i < tabchemin.size()-1; i ++) {
			//cr�er une m�tapopulation
			Pmetapop = Pmetapop->NewMetaPop(tabchemin[i]);
			mot = tabchemin[tabchemin.size()-1];
		}
	}

	Ppop = new Population(Pmetapop);
//cerr << "Jeupop::NewPop(ChaineCar & chemin) set_nom " << endl;
	Ppop->set_nom(mot);
	
	Pmetapop->AjouterPopulation(Ppop);

//cerr << "Jeupop::NewPop(ChaineCar & chemin) fin " << endl;

	return (Ppop);
}


void Jeupop::affind (int numpop, int numind) const {
	_tabPpop[numpop]->_tabPind[numind]->affiche(cout,1);
}

/** Suppression de la population p du Jeupop */
void Jeupop::SupprPop(StrucPop * Ppop){
//cerr << "Jeupop::SupprPop debut" << endl;
	unsigned long i;
	
	_Pracinepops->SupprPop(Ppop);
	for (i = 0; i < _tabPpop.size(); i++) {
		if (_tabPpop[i] == Ppop) _tabPpop.Suppr(i);
	}
	_nbpop--;
//cerr << "Jeupop::SupprPop fin" << endl;
}
/** D�place la pop Ppop a � la position b */
void Jeupop::f_deplacePop(Population * Ppop, unsigned long b){
	signed long a;
	a = _tabPpop.Position(Ppop);
	if (a < 0) return;
	if (b > _tabPpop.size()) return;
	if ((unsigned long)a == b) return;
	
	_tabPpop[a] = _tabPpop[b];
	_tabPpop[b] = Ppop;
}
/** enl�ve les all�les qui ne sont pas repr�sent�s dans les populations
 */
void Jeupop::f_nettoieAlleles(){
	unsigned long l;

	for (l = 0; l < _tabPloc.size(); l++) _tabPloc[l]->f_nettoieAlleles();
}

/** Retourne vrai, si l'allele n'est pas pr�sent dans jeupop */
bool Jeupop::r_allelenonpresent(Allele * Pall) const{

	return(_Pracinepops->r_allelenonpresent(Pall));
}
/** construit le vecteur Vlocus avec les numeros de tous les locus */
void Jeupop::f_selectlocustous(vector<unsigned int> & Vlocus) const{
	unsigned int nblocus(get_nbloc());
	unsigned int i;

	Vlocus.resize(0);
		
	for (i = 0; i < nblocus; i ++) Vlocus.push_back(i);	
}
/** Suppression des locus qui ne sont pas pr�sents dans Vnumloc */
void Jeupop::GarderVlocus(Vecteur<unsigned int> & Vnumloc){

	unsigned int i;
	_nbloc = _tabPloc.size();

//cerr << "Jeupop::GarderVlocus " << _nbloc << endl ;
	for (i = _nbloc; i > 0 ; i--) {
//cerr << "Jeupop::GarderVlocus " << i-1 << endl ;
		// si i-1 n'est pas pr�sent dans  Vnumloc: on supprime le locus
		if (!Vnumloc.Existe(i-1)) supprLocus(i-1);
	}
}
/** Suppression d'un locus */
void Jeupop::supprLocus(unsigned int numlocus){
	unsigned long i;

	if (numlocus >= _tabPloc.size()) throw Anomalie(8);
	//suppression du locus chez tous les individus
	for (i = 0; i < _Pracinepops->_tabPind.size(); i++) _Pracinepops->_tabPind[i]->supprLocus(numlocus);
	
	delete _tabPloc[numlocus];
	_tabPloc.Suppr(numlocus);

	set_nbloc();
}
/** R�affectation du nombre de locus */
void Jeupop::set_nbloc(){

	_nbloc = _tabPloc.size();
	_Pracinepops->set_nbloc();

}
/** obtenir le num�ro d'un locus avec son nom */
signed int Jeupop::get_numloc(const string & nomlocus) const{
	signed int numloc(-1);
	unsigned int nbloc(get_nbloc()), i;

	for (i=0; i < nbloc; i++) {
//cerr << "Jeupop::get_numloc " << nomlocus << " " << _tabPloc[i]->get_nom()<<endl;
		if (nomlocus == _tabPloc[i]->get_nom()) {
			numloc = i;
			break;
		}
	}	

	return (numloc);	
}


void Jeupop::iGenetix(istream &fichier){
	//lecture de fichiers au format Genetix
// pas adapt�e � un traitement sur fichiers haploides ou nploides

//cerr << "Jeupop::iGenetix debut" << endl;
	ChaineFicPop objetGenetix(fichier);
	Titre titres;
	biolib::vecteurs::ChaineCar mot, nomall1, nomall2;
	
	Population * Ppop;	
	Individu * Pind;

	unsigned int nbpop, nbloc, nball(0), nbind, i,j, k;
	unsigned int nbdigits(3);

	reset();

	set_nploidie(2);

	objetGenetix.get_lignepop();
	objetGenetix.GetMot(1, mot);
	nbloc = (int) mot;
	if ((nbloc < 1) || (nbloc > 100)) throw Anomalie(5);
	_commentaires.push_back(objetGenetix);


//cerr << "Jeupop::iGenetix nbloc " << nbloc << endl;
	objetGenetix.get_lignepop();
	objetGenetix.GetMot(1, mot);
	nbpop = (int) mot;
//	fichier >> nbpop;
	if ((nbpop < 1) || (nbpop > 1000)) throw Anomalie(5);
	_commentaires.push_back(objetGenetix);

//cerr << "Jeupop::iGenetix nbpop " << nbpop << endl;

	//lecture et cr�ation des locus et des all�les
	for (i=0; i < nbloc; i++) {
		_tabPloc.push_back(new Locus(this, 0));
		objetGenetix.get_lignepop();
		_tabPloc.back()->set_nom(objetGenetix);	
//cerr << "Jeupop::iGenetix locus " << objetGenetix << endl;
		fichier >> nball;
		objetGenetix.get_lignepop();
		if (objetGenetix.GetNbMots() != (int) nball) throw Anomalie(5);
		for (j=0; j < nball; j++) {
			objetGenetix.GetMot(j+1, nomall1);
			_tabPloc[i]->_tabPall.push_back(new Allele(_tabPloc[i], nomall1));
		}
	}
	set_nbloc();

	for (i=0; i < nbpop; i++) {
		objetGenetix.get_lignepop();
		
		Ppop = NewPop(objetGenetix);

//cerr << "Jeupop::iGenetix pop " << objetGenetix << endl;
		objetGenetix.get_lignepop();
		if (objetGenetix.EstUnChiffre() == false) {
				cout << endl;
				cout << _("error in Genetix data file.") << endl;
				cout << _("wrong number of individuals at line : ") << objetGenetix.get_numeroligne() << endl;

				throw Anomalie(201);
		}
		else nbind = (unsigned int) objetGenetix;

//cerr << "Jeupop::iGenetix nbind " << nbind << endl;
		for (j=0; j < nbind; j++) {
			//creation d'un nouvel individu
			fichier >> mot;
			Pind = new Individu(_tabPpop.back(), mot);
			Ppop->AjouterIndividu(Pind);

//cerr << "Jeupop::iGenetix ind " << mot << endl;

			objetGenetix.get_lignepop();
			if (objetGenetix.GetNbMots() != (int) nbloc){
				cout << endl;
				cout << _("error in Genetix data file.") << endl;
				cout << _("wrong number of locus at line : ") << objetGenetix.get_numeroligne() << endl;

				throw Anomalie(201);
			}

			for (k=0; k < nbloc; k++) {
//cerr << "Jeupop::iGenetix nbloc nbmots " << nbloc << " " << objetGenetix.GetNbMots() << endl;
				objetGenetix.GetMot(k+1, mot);
				if (mot.EstUnChiffre() == false) {
					throw Anomalie(5);
				}
//cerr << "Jeupop::iGenetix mot " << mot << endl;
				nomall1.assigner(mot, 0, nbdigits - 1);
				nomall2.assigner(mot, nbdigits, (nbdigits * 2) - 1);

//cerr << "Jeupop::iGenetix all  " << nomall1 << " " << nomall2 << endl;
				if (nomall1 == "000") Pind->_tabPall[k*2] = _tabPloc[k]->getPallNul();
				else Pind->_tabPall[k*2] = _tabPloc[k]->getPall(nomall1);

				if (nomall2 == "000") Pind->_tabPall[k*2 + 1] = _tabPloc[k]->getPallNul();
				else Pind->_tabPall[k*2 + 1] = _tabPloc[k]->getPall(nomall2);
//cerr << "Jeupop::iGenetix Pall  " << Pind->_tabPall[k*2] << " " << Pind->_tabPall[k*2 + 1] << endl;
			}	
		}
	}
//cerr << "Jeupop::iGenetix fin "<< endl;
}

void Jeupop::iPopulationsXML(istream &fichier){
  #ifdef XMLREADPOPULATIONS_H
//cerr << "Jeupop::iPopulationsXML debut "<< endl;
  //  string mot;

  //  fichier >> mot;
//cerr << "Jeupop::iPopulationsXML mot " << mot << endl;
 //   if (mot != "<?xml") {
  //    fichier.seekg(0);
  //    throw Jeupop::Anomalie(5);
 //     return;
 //   }
  //  fichier.seekg(0);

    try {
      
      XMLreadPopulations * Plecture;
      Plecture = new XMLreadPopulations(*this);
      Plecture->iParseFlux(fichier);
cerr << "Jeupop::iPopulationsXML(istream &fichier)"        << endl;
    }
    catch (XMLreadPopulations::Anomalie pb) {
      cout << endl << pb.message << endl << endl;
      throw Jeupop::Anomalie(5);
    }
    
  #else
    throw Anomalie(5);
  #endif
}

void Jeupop::set_commentaires(const string & commentaires){
  _commentaires.push_back(commentaires);
}

