void Host :: MutateGenes(int mutationType, KIRGene& kir_hap2, Map& kirMap, GenePool& mhcPool, int gene_type)
{
	if(mutationType == 1)//pick another molecules as mutation
	{
		KIRGene newGene(RandomNumber(2,16));
		/*if(!kirMap.IsGeneInMap(newGene))
		{
			kirMap.FillMap(mhcPool, newGene);
			if(gene_type !=2)////force to have only one type of receptors, if the user wants it!
				newGene.SetGeneType(gene_type);
			kir_hap2.Copy(newGene);
		}//*/
		int M_id = 0;
		int mhcPoolSize = mhcPool.GetPoolSize();
		
		//calculate the value of M_id to determine whether the gene is pseudogene or not
		for(unsigned int i = 0; i < mhcPoolSize; i++)
		{
			Gene mhcGene;
			mhcGene.SetGeneID(mhcPool.GetGenes().at(i));
			int L = newGene.BindMolecule(mhcGene);
			if(L >= newGene.GetGeneSpecificity())
				M_id += (1<<i);
		}
		newGene.SetPseudogene(M_id);
		if(gene_type !=2)////force to have only one type of receptors, if the user wants it!
			newGene.SetGeneType(gene_type);
		kir_hap2.Copy(newGene);
		return;
	}

	if(mutationType == 2)//point mutation + L
	{

		if(RandomNumberDouble()<0.8) //pointmutation
		{
			kir_hap2.PointMutation();
			//kirMap.FillMap(mhcPool, kir_hap2);
			int M_id = 0;
			int mhcPoolSize = mhcPool.GetPoolSize();
			
			//calculate the value of M_id to determine whether the gene is pseudogene or not
			for(unsigned int i = 0; i < mhcPoolSize; i++)
			{
				Gene mhcGene;
				mhcGene.SetGeneID(mhcPool.GetGenes().at(i));
				int L = kir_hap2.BindMolecule(mhcGene);
				if(L >= kir_hap2.GetGeneSpecificity())
					M_id += (1<<i);
			}
			kir_hap2.SetPseudogene(M_id);
		}

		if(RandomNumberDouble()<0.8) //mutate L
		{
			kir_hap2.MutateSpecificity();
			//kirMap.FillMap(mhcPool, kir_hap2);
			int M_id = 0;
			int mhcPoolSize = mhcPool.GetPoolSize();
			
			//calculate the value of M_id to determine whether the gene is pseudogene or not
			for(unsigned int i = 0; i < mhcPoolSize; i++)
			{
				Gene mhcGene;
				mhcGene.SetGeneID(mhcPool.GetGenes().at(i));
				int L = kir_hap2.BindMolecule(mhcGene);
				if(L >= kir_hap2.GetGeneSpecificity())
					M_id += (1<<i);
			}
			kir_hap2.SetPseudogene(M_id);
		}
		if(RandomNumberDouble()<0.8)//mutate type
		{
			kir_hap2.MutateReceptorType();
		}
		return;
	}
}
void Host::MutateGenesForMutualInvasion(int mutationType, KIRGene& kir_hap2, Map& kirMap, GenePool& mhcPool, double simulationTime, double time_invasion, int gene_type)
{

	if(mutationType == 1)//pick another molecule as mutation
	{
		KIRGene newGene(RandomNumber(2,16));
		/*if(!kirMap.IsGeneInMap(newGene))
		{
			kirMap.FillMap(mhcPool, newGene);
			//cout <<simulationTime << "|" <<time_invasion <<endl;
			if(simulationTime < time_invasion)//only after the invasion time, the receptor type should be allowed to mutate
				newGene.SetGeneType(gene_type);
			kir_hap2.Copy(newGene);
		}//*/
		int M_id = 0;
		int mhcPoolSize = mhcPool.GetPoolSize();
		
		//calculate the value of M_id to determine whether the gene is pseudogene or not
		for(unsigned int i = 0; i < mhcPoolSize; i++)
		{
			Gene mhcGene;
			mhcGene.SetGeneID(mhcPool.GetGenes().at(i));
			int L = newGene.BindMolecule(mhcGene);
			if(L >= newGene.GetGeneSpecificity())
				M_id += (1<<i);
		}
		//set the Gene pseudo
		newGene.SetPseudogene(M_id);
		if(gene_type !=2)////force to have only one type of receptors, if the user wants it!
			newGene.SetGeneType(gene_type);
		kir_hap2.Copy(newGene);
		return;
	}

	if(mutationType == 2)//point mutation + L
	{
		if(RandomNumberDouble()<0.8)
		{
			kir_hap2.PointMutation();
			//kirMap.FillMap(mhcPool, kir_hap2);
			int M_id = 0;
			int mhcPoolSize = mhcPool.GetPoolSize();
			
			//calculate the value of M_id to determine whether the gene is pseudogene or not
			for(unsigned int i = 0; i < mhcPoolSize; i++)
			{
				Gene mhcGene;
				mhcGene.SetGeneID(mhcPool.GetGenes().at(i));
				int L = kir_hap2.BindMolecule(mhcGene);
				if(L >= kir_hap2.GetGeneSpecificity())
					M_id+= (1<<i);
			}
			//set the Gene pseudo
			kir_hap2.SetPseudogene(M_id);
		}

		if(RandomNumberDouble()<0.2)
		{
			kir_hap2.MutateSpecificity();
			//kirMap.FillMap(mhcPool, kir_hap2);
			int M_id = 0;
			int mhcPoolSize = mhcPool.GetPoolSize();
			
			//calculate the value of M_id to determine whether the gene is pseudogene or not
			for(unsigned int i = 0; i < mhcPoolSize; i++)
			{
				Gene mhcGene;
				mhcGene.SetGeneID(mhcPool.GetGenes().at(i));
				int L = kir_hap2.BindMolecule(mhcGene);
				if(L >= kir_hap2.GetGeneSpecificity())
					M_id+= (1<<i);
			}
			//set the Gene pseudo
			kir_hap2.SetPseudogene(M_id);
		}
		if(RandomNumberDouble()<0.2)
		{
			if(simulationTime >= time_invasion) //only after the invasion time, the receptor type should be allowed to mutate
				kir_hap2.MutateReceptorType();
		}
		return;
	}
}
/*FUNCTIONS OF CLASS HOST
 *Constructs a host for the initialization of the population: it fills the MHC genes with a randomly picked allele from the population
 * and creates KIRs that match their own MHC according to the specificity*/
Host::Host(int loci_kir, int loci_mhc, double _mutationRate, bool _tuning, int numberOfExtraKirs,Map& kirMap, MHCGenePool& mhcPool, bool hla) {

	InitializeHostParameters(_mutationRate,_tuning, loci_kir, loci_mhc);
	//fill the mhc Genes
	for(int i = 0; i <lociMHC*TWO; i++)
	{
		Gene firstGene;
		int mhc1 = mhcPool.RandomlyPickGene(hla);
		firstGene.SetGeneID(mhc1);
		mhcGenes.push_back(firstGene);
	}

/*
	Gene secondGene;
	secondGene.SetGeneID(mhc2);
	mhcGenes.push_back(secondGene);*/

	//create random KIRs with random specificity for ONE haplotype
	// (at the beginning of the simulation, the size of the map should equal the LOCI_NUMBER)
	map< pair<int,int>, pair <int, int> > ::iterator it;
	for(it = kirMap.GetMap().begin(); it != kirMap.GetMap().end(); it ++)
	{
		int id = it->first.first;
		int geneType = it->first.second;
		int L = it->second.first;
		int pseudo = it->second.second;
		KIRGene kir;
		kir.SetGeneSpecificity(L);
		kir.SetGeneID(id);
		kir.SetPseudogene(pseudo);
		kir.SetGeneType(geneType);
		kir.SetGeneFunctionality(false);
		kir.SetGeneExpression(false);
		kirGenes.push_back(kir);
		//cout << "printing genes in host first constructor" <<endl;
		//kir.PrintGenes();
	}

	int size = kirGenes.size();
	//make sure that the first haplotype has number lociKIR (regardless of the Map size!)
	while(size < lociKIR)
	{
		KIRGene bla = kirGenes.at(size-1);
		kirGenes.push_back(bla);
		size ++;
	}

	//copy the first kirs into the other haplotype (all individuals are homozygous!)
	for(int i=0; i<lociKIR; i++)
	{
		KIRGene kir = kirGenes.at(i);
		kirGenes.push_back(kir);

	}

	if(tuning == true)
		EducateKIRs();
	ExpressKIRs(numberOfExtraKirs);
	//CountFunctionalKIRs();
	age = RandomNumber(1,70); //population initialized with a random age between 1 and 70
	//cout <<inhibitoryKIRs << "|" <<activatingKIRs <<"|"<<CountExpressedKIRs() <<endl;
}