// File: /workspace/github_cpp_makefile_star2_O2/melop[P]admixem/Individual.cpp
// Function: Individual::fnDeterminePhenotypes()
void Individual::fnDeterminePhenotypes() { // Calculate the phenotypic values from genotypes

	for(std::map<string, double >::iterator it=this->_mpPhenotypes.begin(); it!=this->_mpPhenotypes.end(); ++it) {

		//Go over all phenotypes
		string sPhenoName = it->first;
		Parser *pFormula = SimulConfig.pPhenotypeConfig->GetFormula(sPhenoName);
		vector< pair<int, double> > * pvSymbols = SimulConfig.pPhenotypeConfig->GetFormulaSymbols(sPhenoName);
		vector<string> * pvSymbolStrings = SimulConfig.pPhenotypeConfig->GetFormulaSymbolStrings(sPhenoName);

		vector<string>::iterator oSymbolString = pvSymbolStrings->begin();

		for (vector< pair<int, double> >::iterator oSymbol = pvSymbols->begin(); oSymbol != pvSymbols->end(); ++oSymbol) 
		{
			
			int nChr = oSymbol->first; // Chromosome num
			double nPos = oSymbol->second; // Position of gene
			map<double, GeneProperties>  oGeneList = SimulConfig.pGeneConfig->GetMpGenes()->at(nChr-1);
			map<double, int> oGeneIndexList = SimulConfig.pGeneConfig->GetMpGeneIndex()->at(nChr-1);
			//look up information of this gene
			int nIndex2 = nChr  * 2 - 1;
			int nIndex1 = nIndex2 - 1;
			Gene oAllele1 = this->_arrGenes.at(nIndex1).at(oGeneIndexList[nPos]); 
			Gene oAllele2 = this->_arrGenes.at(nIndex2).at(oGeneIndexList[nPos]);
			GeneProperties oGeneProp = oGeneList[nPos];

			double nVal=0.0;
			/*
			if (sPhenoName == "ComplexEpi2") {
				printf("break");
			}
			*/

			if (oGeneProp.AlleleMode==GeneProperties::Hemizygous || oGeneProp.AlleleMode==GeneProperties::Dominant) { // if this gene is hemizygous or dominant
				if (oAllele1.Allele  != oAllele2.Allele) { // if one of the alleles is dominant
					nVal = (oAllele1.Allele == oGeneProp.DominantLabel )? oAllele1.Value : oAllele2.Value;//oGeneProp.DominantValue;
				}
				/*else if (oAllele1.Allele == oGeneProp.DominantLabel && oAllele2.Allele == oGeneProp.DominantLabel){ // both dominant
					nVal = ( oAllele1.Value + oAllele2.Value)/2;//oGeneProp.RecessiveValue; take the mean. 
				}*/
				else {//both recessive or dominant
					nVal = ( oAllele1.Value + oAllele2.Value)/2;
				}


			}
			else { //this gene is additive
				/*nVal  = oAllele1.Allele == oGeneProp.DominantLabel? oGeneProp.DominantValue:oGeneProp.RecessiveValue;
				  nVal += oAllele2.Allele == oGeneProp.DominantLabel? oGeneProp.DominantValue:oGeneProp.RecessiveValue;*/
				nVal = ( oAllele1.Value + oAllele2.Value);
			}
			
			
			pFormula->symbols_[*oSymbolString] = nVal; // put value to symbol;
			pFormula->symbols_[(*oSymbolString)+"_a1"] = oAllele1.Value;
			pFormula->symbols_[(*oSymbolString)+"_a2"] = oAllele2.Value;
			oSymbolString++;
		}

		//next see if need to add references to parent's phenotypes
		if (SimulConfig.pPhenotypeConfig->IsReferToParentPhe(sPhenoName)) { // fill in reference to parents' phenotypes

			for(int nParentSym=0;nParentSym<=1;nParentSym++) {
				vector<string> * pvParentSymbols = SimulConfig.pPhenotypeConfig->GetFormulaParentSymbols(sPhenoName , nParentSym);
				map< string, double > *mpParentPhes = (nParentSym ==0 )? &this->_mpDadPhenotypes : &this->_mpMomPhenotypes;
				string sSymPrefix = "Phe_";
				sSymPrefix = sSymPrefix + ((nParentSym==0)? "Mom" : "Dad") + "_";
				for (vector< string >::iterator oSymbol = pvParentSymbols->begin(); oSymbol != pvParentSymbols->end(); ++oSymbol) 
				{
					if (mpParentPhes->find(oSymbol->c_str()) != mpParentPhes->end() ) {
						if (mpParentPhes->find(*oSymbol ) != mpParentPhes->end()) {
							pFormula->symbols_[sSymPrefix + *oSymbol ] = mpParentPhes->at(*oSymbol );
						} else {
							pFormula->symbols_[sSymPrefix + *oSymbol ] = 0; //for gen 0, parent phenotypes are all 0.
						}
					}
				}
			}
		}

		this->_mpPhenotypes[sPhenoName] = pFormula->Evaluate(); // re-evaluate.
	}

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x278, %rsp            # imm = 0x278
leaq 0x50(%rdi), %rax
movq %rax, 0x48(%rsp)
movq 0x68(%rdi), %rcx
leaq 0x58(%rdi), %rax
movq %rax, 0x50(%rsp)
leaq 0x128(%rdi), %rax
movq %rax, 0x40(%rsp)
leaq 0x130(%rsp), %r12
leaq 0xe0(%rdi), %rax
movq %rax, 0x60(%rsp)
addq $0xb0, %rdi
movq %rdi, 0x68(%rsp)
leaq 0xc0(%rsp), %r14
cmpq 0x50(%rsp), %rcx
je 0x20629
movq %rcx, 0x58(%rsp)
leaq 0x20(%rcx), %rsi
leaq 0x70(%rsp), %r15
movq %r15, %rdi
callq 0x7550
leaq 0x2581b(%rip), %rax     # 0x45938
movq 0x10(%rax), %rbx
movq %r12, %rdi
movq %r15, %rsi
callq 0x7550
movq %rbx, %rdi
movq %r12, %rsi
callq 0x12646
movq %rax, 0x30(%rsp)
movq %r12, %rdi
callq 0x71a0
leaq 0x257ed(%rip), %rax     # 0x45938
movq 0x10(%rax), %rbx
leaq 0x190(%rsp), %r15
movq %r15, %rdi
leaq 0x70(%rsp), %rsi
callq 0x7550
movq %rbx, %rdi
movq %r15, %rsi
callq 0x12614
movq %rax, 0x38(%rsp)
movq %r15, %rdi
callq 0x71a0
leaq 0x257b5(%rip), %rax     # 0x45938
movq 0x10(%rax), %rbx
leaq 0x170(%rsp), %r15
movq %r15, %rdi
leaq 0x70(%rsp), %rsi
callq 0x7550
movq %rbx, %rdi
movq %r15, %rsi
callq 0x1263a
movq %rax, %rbx
movq %r15, %rdi
callq 0x71a0
movq (%rbx), %r15
movq 0x38(%rsp), %rax
movq (%rax), %r13
movq 0x30(%rsp), %rax
addq $0x68, %rax
movq %rax, 0x8(%rsp)
movq 0x38(%rsp), %rax
cmpq 0x8(%rax), %r13
je 0x203e8
movslq (%r13), %rbx
movsd 0x8(%r13), %xmm0
movsd %xmm0, 0x28(%rsp)
leaq 0x25747(%rip), %rax     # 0x45938
movq 0x18(%rax), %rdi
callq 0x15eda
leaq -0x1(%rbx), %r12
movq %rax, %rdi
movq %r12, %rsi
callq 0x22f4e
movq %r14, %rdi
movq %rax, %rsi
callq 0x1e10a
leaq 0x2571d(%rip), %rax     # 0x45938
movq 0x18(%rax), %rdi
callq 0x15eee
movq %rax, %rdi
movq %r12, %rsi
callq 0x16f9e
leaq 0x90(%rsp), %rdi
movq %rax, %rsi
callq 0x1909a
leal -0x2(,%rbx,2), %eax
movslq %eax, %rsi
movq 0x40(%rsp), %rdi
callq 0x22fb6
movq %rax, %r12
leaq 0x90(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x16f44
movslq (%rax), %rsi
movq %r12, %rdi
callq 0x22fd4
leal -0x1(,%rbx,2), %ecx
movb 0x1(%rax), %bl
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
movslq %ecx, %rsi
movq 0x40(%rsp), %rdi
callq 0x22fb6
movq %rax, %r12
leaq 0x90(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x16f44
movslq (%rax), %rsi
movq %r12, %rdi
callq 0x22fd4
movb 0x1(%rax), %bpl
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
movq %r14, %rdi
leaq 0x28(%rsp), %rsi
callq 0x17926
leaq 0x1b0(%rsp), %rdi
movq %rax, %rsi
callq 0x1e358
testl $0xfffffffd, 0x1f8(%rsp) # imm = 0xFFFFFFFD
je 0x202fc
movsd 0x18(%rsp), %xmm0
addsd 0x10(%rsp), %xmm0
jmp 0x20332
cmpb %bpl, %bl
jne 0x20317
movsd 0x18(%rsp), %xmm0
addsd 0x10(%rsp), %xmm0
mulsd 0xd0e3(%rip), %xmm0     # 0x2d3f8
jmp 0x20332
movsd 0x18(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
cmpb 0x1d0(%rsp), %bl
je 0x20338
movsd 0x10(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
movq 0x8(%rsp), %rdi
movq %r15, %rsi
callq 0x94ac
movsd 0x20(%rsp), %xmm0
movsd %xmm0, (%rax)
leaq 0x110(%rsp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
leaq 0xea50(%rip), %rdx      # 0x2edb4
callq 0x22ff5
movq 0x8(%rsp), %rdi
movq %rbx, %rsi
callq 0x18432
movsd 0x18(%rsp), %xmm0
movsd %xmm0, (%rax)
movq %rbx, %rdi
callq 0x71a0
movq %rbx, %rdi
movq %r15, %rsi
leaq 0xea23(%rip), %rdx      # 0x2edb8
callq 0x22ff5
movq 0x8(%rsp), %rdi
movq %rbx, %rsi
callq 0x18432
movsd 0x10(%rsp), %xmm0
movsd %xmm0, (%rax)
movq %rbx, %rdi
callq 0x71a0
addq $0x20, %r15
leaq 0x1b0(%rsp), %rdi
callq 0x17978
leaq 0x90(%rsp), %rdi
callq 0x17c40
movq %r14, %rdi
callq 0x18bc4
addq $0x10, %r13
jmp 0x201cb
leaq 0x25549(%rip), %rax     # 0x45938
movq 0x10(%rax), %r15
leaq 0xf0(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x7550
movq %r15, %rdi
leaq 0xf0(%rsp), %rbx
movq %rbx, %rsi
callq 0x12676
movl %eax, %ebp
movq %rbx, %rdi
callq 0x71a0
testb %bpl, %bpl
je 0x205dc
xorl %r12d, %r12d
cmpl $0x2, %r12d
je 0x205dc
leaq 0x254f9(%rip), %rax     # 0x45938
movq 0x10(%rax), %r15
leaq 0x150(%rsp), %rbx
movq %rbx, %rdi
leaq 0x70(%rsp), %rsi
callq 0x7550
movq %r15, %rdi
movq %rbx, %rsi
movl %r12d, %edx
callq 0x12620
movq %rax, %rbp
movq %rbx, %rdi
callq 0x71a0
testl %r12d, %r12d
movl %r12d, %r15d
movq 0x60(%rsp), %r12
cmoveq 0x68(%rsp), %r12
leaq 0x1b0(%rsp), %rbx
movq %rbx, %rdi
leaq 0xe928(%rip), %rsi      # 0x2edbc
movq %r14, %rdx
callq 0x9512
movl %r15d, 0x10(%rsp)
testl %r15d, %r15d
leaq 0xda6a(%rip), %rdx      # 0x2df15
leaq 0xda67(%rip), %rax      # 0x2df19
cmoveq %rax, %rdx
leaq 0x90(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x22ff5
movq %r14, %rdi
movq %r15, %rsi
leaq 0xdd00(%rip), %rdx      # 0x2e1d6
callq 0x948c
leaq 0x1b0(%rsp), %rdi
movq %r14, %rsi
callq 0x74c0
movq %r14, %rdi
callq 0x71a0
movq %r15, %rdi
callq 0x71a0
movq (%rbp), %r15
leaq 0x8(%r12), %rbx
cmpq 0x8(%rbp), %r15
je 0x205c2
movq (%r15), %rsi
movq %r14, %rdi
leaq 0x90(%rsp), %rdx
callq 0x9512
movq %r12, %rdi
movq %r14, %rsi
callq 0x1fb0c
movq %rax, %r13
movq %r14, %rdi
callq 0x71a0
cmpq %rbx, %r13
je 0x205b9
movq %r12, %rdi
movq %r15, %rsi
callq 0x1fb0c
cmpq %rbx, %rax
je 0x2058d
movq %r12, %rdi
movq %r15, %rsi
callq 0x2302e
movsd (%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
movq %r14, %rdi
leaq 0x1b0(%rsp), %rsi
movq %r15, %rdx
callq 0x23073
movq 0x8(%rsp), %rdi
movq %r14, %rsi
callq 0x18432
movsd 0x18(%rsp), %xmm0
movsd %xmm0, (%rax)
jmp 0x205b1
movq %r14, %rdi
leaq 0x1b0(%rsp), %rsi
movq %r15, %rdx
callq 0x23073
movq 0x8(%rsp), %rdi
movq %r14, %rsi
callq 0x18432
andq $0x0, (%rax)
movq %r14, %rdi
callq 0x71a0
addq $0x20, %r15
jmp 0x20504
leaq 0x1b0(%rsp), %rdi
callq 0x71a0
movl 0x10(%rsp), %r12d
incl %r12d
jmp 0x2042e
movq 0x30(%rsp), %rdi
callq 0x920c
movsd %xmm0, 0x8(%rsp)
movq 0x48(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x94ac
movsd 0x8(%rsp), %xmm0
movsd %xmm0, (%rax)
leaq 0x70(%rsp), %rdi
callq 0x71a0
movq 0x58(%rsp), %rdi
callq 0x72d0
movq %rax, %rcx
leaq 0x130(%rsp), %r12
jmp 0x200f5
addq $0x278, %rsp            # imm = 0x278
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0xf0(%rsp), %rdi
jmp 0x2072c
movq %rax, %rbx
leaq 0x190(%rsp), %rdi
jmp 0x2072c
movq %rax, %rbx
leaq 0x130(%rsp), %rdi
jmp 0x2072c
jmp 0x206f9
jmp 0x206f9
movq %rax, %rbx
leaq 0x170(%rsp), %rdi
jmp 0x2072c
jmp 0x206f9
jmp 0x206f9
jmp 0x206f9
movq %rax, %rbx
leaq 0x150(%rsp), %rdi
jmp 0x2072c
jmp 0x206f9
jmp 0x2070f
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
jmp 0x2071f
jmp 0x206c4
jmp 0x206b2
jmp 0x206c4
movq %rax, %rbx
leaq 0x110(%rsp), %rdi
callq 0x71a0
jmp 0x206c7
movq %rax, %rbx
leaq 0x1b0(%rsp), %rdi
callq 0x17978
jmp 0x206dd
jmp 0x206da
jmp 0x206da
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x17c40
leaq 0xc0(%rsp), %rdi
callq 0x18bc4
jmp 0x20731
movq %rax, %rbx
jmp 0x20731
movq %rax, %rbx
jmp 0x206ea
jmp 0x20714
jmp 0x2070f
jmp 0x20714
jmp 0x2070f
jmp 0x2070f
jmp 0x2070f
movq %rax, %rbx
jmp 0x20724
movq %rax, %rbx
leaq 0xc0(%rsp), %rdi
callq 0x71a0
leaq 0x1b0(%rsp), %rdi
callq 0x71a0
leaq 0x70(%rsp), %rdi
callq 0x71a0
movq %rbx, %rdi
callq 0x76d0
nop