// File: /workspace/github_cpp_makefile_star2_O2/melop[P]admixem/config.cpp
// Function: PhenotypeConfigurations::LoadFromFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
void PhenotypeConfigurations::LoadFromFile(string szConfigFile) 
{
	FILE *pConfigFile;
	char szBuffer[2048];
	char szPhenotypeName[100];
	char szFormula[2048];
	
	#ifdef _OPENMP
		int nTotalCPUCore =  omp_get_max_threads();//omp_get_num_threads();
		//printf("OpenMP enabled\n");
	#else
		int nTotalCPUCore = 1;
		//printf("OpenMP disabled \n");
	#endif
	
	printf("Start loading phenotype file %s ...\n", szConfigFile.c_str());

	_szConfigFilename = szConfigFile; // save name of config file

	pConfigFile = fopen(szConfigFile.c_str(), "r");

	if (!pConfigFile) {
		printf("%s\n", "Cannot open phenotype file ...");
		throw "Cannot open phenotype file!";
	}

	if (fgets(szBuffer, 2048, pConfigFile) == NULL) { // skip the header line
		throw "Cannot read phenotype file!";
	}

	while(fgets(szBuffer, 2048, pConfigFile) != NULL) 
	{
		string sPhenotypeName, sFormula;

		sscanf(szBuffer, "%[^\t\n]	%[^\t\n]", szPhenotypeName, szFormula);
		sPhenotypeName = szPhenotypeName;
		sFormula = szFormula;
		if (sPhenotypeName.length() != 0 && sFormula.length() !=0) {
			this->_mpPhenotypes[sPhenotypeName] = sFormula;
			
			Parser * pF = new Parser("");
			try {
				pF->Evaluate(sFormula);
			}
			catch(std::runtime_error e) {
				if ( string(e.what()) == "Divide by zero" ) {
					
					printf("Warning in formula: %s \nErrMsg:%s\nThis could simply be caused by uninitialized values", sFormula.c_str(), e.what());
					
					
				}
				else {
					printf("Error occured when trying to parse formula: %s \nErrMsg:%s\nPlease check formulae grammar!", sFormula.c_str(), e.what());
					exit(100);
				}
			}

			vector< pair<int, double> > vSymbols;
			vector< string > vDadPheSymbols;
			vector< string > vMomPheSymbols;
			vector<string> vSymbolStrings;
			//list all the symbols used in this formula
			for(map<string,double>::iterator it = pF->symbols_.begin(); it != pF->symbols_.end(); ++it) 
			{	
				//Parse chromosome number and position from the symbol
				//cout << (it->first) << "\n"; //list all keys

				int nSymbolChr;
				double nSymbolPos;
				
				if (strlen(it->first.c_str()) < 6) { // no need to add symbol
					continue;
				}

				string sSymbolLabel = it->first;
				size_t nFirstUS = sSymbolLabel.find_first_of("_");
				size_t nLastUS = sSymbolLabel.find_last_of("_");

				if (sSymbolLabel.find_first_of("Phe") == 0) { //if referring to the phenotype of dad or mum
					string sWhichParent = sSymbolLabel.substr(  nFirstUS+1, 3);
					string sPhenotype = sSymbolLabel.substr(  nLastUS+1 );

					if (sWhichParent == "Dad" ) {
						vDadPheSymbols.push_back(sPhenotype);
						//vSymbolStrings.push_back(sSymbolLabel); //don't add this
						this->_mpIsReferToParentPhe[sPhenotypeName] = true;
					}

					if (sWhichParent == "Mom" ) {
						vMomPheSymbols.push_back(sPhenotype);
						//vSymbolStrings.push_back(sSymbolLabel); //don't add this.
						this->_mpIsReferToParentPhe[sPhenotypeName] = true;

					}

					continue;
				}

				string sTemp = it->first.substr(3);	
				nFirstUS = sTemp.find_first_of("_");
				nLastUS = sTemp.find_last_of("_");

				if (nFirstUS != nLastUS) { // there is _a1 _a2 suffixes, delete the suffix
					sTemp = sTemp.substr(0,nLastUS);
					sSymbolLabel = "chr" + sTemp;				
				}

				sTemp = sTemp.replace(sTemp.find_first_of("_"), 1, " ");
				if (sscanf(sTemp.c_str(), "%d %lf", &nSymbolChr, &nSymbolPos)!=2) 
				{ // see if it's another format with _a1, a2 suffixes
					continue;
				};
				pair<int,double> oSymbolPair( nSymbolChr, nSymbolPos);
				vSymbols.push_back(oSymbolPair);
				vSymbolStrings.push_back(sSymbolLabel); // save label too
			}

			for (int nCPU=0;nCPU<nTotalCPUCore;nCPU++) {
				//map<string , Parser *> _mpPhenotypeFormulae;
				this->_mpmpPhenotypeFormulae[nCPU][sPhenotypeName] = new Parser(sFormula);//pF;
			}
			this->_mpPhenotypeFormulaSymbols[sPhenotypeName] = vSymbols;
			this->_mpPhenotypeFormulaDadSymbols[sPhenotypeName] = vDadPheSymbols;
			this->_mpPhenotypeFormulaMomSymbols[sPhenotypeName] = vMomPheSymbols;
			this->_mpPhenotypeFormulaSymbolStrings[sPhenotypeName] = vSymbolStrings;
		}
	}

	for (std::map<string,string>::iterator it = _mpPhenotypes.begin(); it != _mpPhenotypes.end(); ++it) {
		printf("%s %s\n", it->first.c_str(), it->second.c_str());
	}

	printf("%d phenotype(s) loaded. \n", _mpPhenotypes.size());

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x11f8, %rsp           # imm = 0x11F8
movq %rsi, %rbx
movq %rdi, %r14
movq (%rsi), %rsi
leaq 0x1c0a9(%rip), %rdi     # 0x2ddd8
xorl %eax, %eax
callq 0x7050
movq %r14, 0x8(%rsp)
movq %r14, %rdi
movq %rbx, %rsi
callq 0x7220
movq (%rbx), %rdi
leaq 0x1df4a(%rip), %rsi     # 0x2fc9a
callq 0x74a0
testq %rax, %rax
je 0x12437
leaq 0x1f0(%rsp), %rdi
movl $0x800, %esi            # imm = 0x800
movq %rax, 0x168(%rsp)
movq %rax, %rdx
callq 0x75e0
testq %rax, %rax
je 0x12454
movq 0x8(%rsp), %rax
leaq 0x58(%rax), %rcx
movq %rcx, 0x160(%rsp)
leaq 0x20(%rax), %rcx
movq %rcx, 0x18(%rsp)
leaq 0x88(%rax), %r12
leaq 0xb8(%rax), %rcx
movq %rcx, 0x150(%rsp)
leaq 0xe8(%rax), %rcx
movq %rcx, 0x148(%rsp)
leaq 0x118(%rax), %rcx
movq %rcx, 0x140(%rsp)
addq $0x148, %rax            # imm = 0x148
movq %rax, 0x138(%rsp)
leaq 0x1f0(%rsp), %r15
leaq 0xa0(%rsp), %r14
leaq 0x60(%rsp), %r13
movq %r12, 0x158(%rsp)
movq %r15, %rdi
movl $0x800, %esi            # imm = 0x800
movq 0x168(%rsp), %rdx
callq 0x75e0
testq %rax, %rax
je 0x123d3
leaq 0xb0(%rsp), %rax
movq %rax, 0xa0(%rsp)
andq $0x0, 0xa8(%rsp)
xorl %ecx, %ecx
movb %cl, 0xb0(%rsp)
leaq 0x50(%rsp), %rax
movq %rax, 0x40(%rsp)
andq $0x0, 0x48(%rsp)
movb %cl, 0x50(%rsp)
movq %r15, %rdi
leaq 0x1bff9(%rip), %rsi     # 0x2de54
leaq 0x180(%rsp), %r15
movq %r15, %rdx
leaq 0x9f0(%rsp), %rcx
xorl %eax, %eax
callq 0x73c0
movq %r14, %rdi
movq %r15, %rsi
callq 0x7730
leaq 0x40(%rsp), %rdi
leaq 0x9f0(%rsp), %rsi
callq 0x7730
cmpq $0x0, 0xa8(%rsp)
je 0x12302
cmpq $0x0, 0x48(%rsp)
je 0x12302
movq 0x160(%rsp), %rdi
movq %r14, %rsi
callq 0x170e6
movq %rax, %rdi
leaq 0x40(%rsp), %rsi
callq 0x7220
movl $0x98, %edi
callq 0x73f0
movq %rax, %r15
leaq 0x20(%rsp), %rbx
movq %rbx, %rdi
leaq 0x1c103(%rip), %rsi     # 0x2dfe9
movq %r13, %rdx
callq 0x9512
movq %r15, %rdi
movq %rbx, %rsi
callq 0x1714c
movq %rbx, %rdi
callq 0x71a0
movq %r15, %rdi
leaq 0x40(%rsp), %rsi
callq 0x92d0
andq $0x0, 0x130(%rsp)
andq $0x0, 0x110(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x120(%rsp)
andq $0x0, 0xf0(%rsp)
movaps %xmm0, 0x100(%rsp)
andq $0x0, 0xd0(%rsp)
movaps %xmm0, 0xe0(%rsp)
movaps %xmm0, 0xc0(%rsp)
movq 0x80(%r15), %rbp
addq $0x70, %r15
movq %r15, 0x170(%rsp)
cmpq 0x170(%rsp), %rbp
je 0x121ff
movq 0x20(%rbp), %rdi
callq 0x7180
cmpq $0x6, %rax
jb 0x121ef
leaq 0x20(%rbp), %r13
leaq 0x20(%rsp), %rbx
movq %rbx, %rdi
movq %r13, %rsi
callq 0x7550
movq %rbx, %rdi
leaq 0x1c22f(%rip), %r12     # 0x2e1d6
movq %r12, %rsi
xorl %edx, %edx
callq 0x71e0
movq %rax, %r14
movq %rbx, %rdi
movq %r12, %rsi
pushq $-0x1
popq %r15
movq %r15, %rdx
callq 0x73a0
movq %rax, %r12
movq %rbx, %rdi
leaq 0x1bf3e(%rip), %rsi     # 0x2df11
xorl %edx, %edx
callq 0x71e0
testq %rax, %rax
je 0x12126
leaq 0x60(%rsp), %rbx
movq %rbx, %rdi
movq %r13, %rsi
pushq $0x3
popq %rdx
movq %r15, %rcx
callq 0x7430
movq %rbx, %rdi
leaq 0x1c1d3(%rip), %r12     # 0x2e1d6
movq %r12, %rsi
xorl %edx, %edx
callq 0x71e0
movq %rax, %r14
movq %rbx, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x73a0
cmpq %rax, %r14
leaq 0xa0(%rsp), %r14
movq %rbx, %r13
je 0x12087
leaq 0x80(%rsp), %rbx
movq %rbx, %rdi
movq %r13, %rsi
xorl %edx, %edx
movq %rax, %rcx
callq 0x7430
movq %r13, %rdi
movq %rbx, %rsi
callq 0x74c0
movq %rbx, %rdi
callq 0x71a0
movq %rbx, %rdi
leaq 0x1beba(%rip), %rsi     # 0x2df1d
movq %r13, %rdx
callq 0x9325
leaq 0x20(%rsp), %rdi
movq %rbx, %rsi
callq 0x74c0
movq %rbx, %rdi
callq 0x71a0
leaq 0x1c14f(%rip), %r12     # 0x2e1d6
movq %r13, %rdi
movq %r12, %rsi
xorl %edx, %edx
callq 0x71e0
movq %r13, %rdi
movq %rax, %rsi
pushq $0x1
popq %rdx
leaq 0x1de8a(%rip), %rcx     # 0x2ff2e
callq 0x7240
movq %r13, %rdi
movq %rax, %rsi
callq 0x7220
movq 0x60(%rsp), %rdi
leaq 0x1be61(%rip), %rsi     # 0x2df21
leaq 0x14(%rsp), %rdx
leaq 0x178(%rsp), %rcx
xorl %eax, %eax
callq 0x73c0
cmpl $0x2, %eax
jne 0x121dd
movl 0x14(%rsp), %eax
movl %eax, 0x80(%rsp)
movsd 0x178(%rsp), %xmm0
movsd %xmm0, 0x88(%rsp)
leaq 0x120(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x1730a
leaq 0xc0(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x17278
jmp 0x121dd
incq %r14
leaq 0x60(%rsp), %r13
movq %r13, %rdi
movq %rbx, %rsi
movq %r14, %rdx
pushq $0x3
popq %rcx
callq 0x7430
incq %r12
leaq 0x80(%rsp), %rdi
movq %rbx, %rsi
movq %r12, %rdx
pushq $-0x1
popq %rcx
callq 0x7430
movq %r13, %rdi
leaq 0x1bdb3(%rip), %rsi     # 0x2df15
callq 0x954d
testb %al, %al
leaq 0xa0(%rsp), %r14
je 0x12198
leaq 0x100(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x17278
movq 0x18(%rsp), %rdi
movq %r14, %rsi
callq 0x172a4
movb $0x1, (%rax)
movq %r13, %rdi
leaq 0x1bd77(%rip), %rsi     # 0x2df19
callq 0x954d
testb %al, %al
je 0x121d0
leaq 0xe0(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x17278
movq 0x18(%rsp), %rdi
movq %r14, %rsi
callq 0x172a4
movb $0x1, (%rax)
leaq 0x80(%rsp), %rdi
callq 0x71a0
movq %r13, %rdi
callq 0x71a0
leaq 0x20(%rsp), %rdi
callq 0x71a0
movq %rbp, %rdi
callq 0x72d0
movq %rax, %rbp
jmp 0x11f68
xorl %eax, %eax
movq 0x158(%rsp), %r12
movl %eax, 0x20(%rsp)
testl %eax, %eax
jg 0x1224e
movl $0x98, %edi
callq 0x73f0
movq %rax, %r15
movq %rax, %rdi
leaq 0x40(%rsp), %rsi
callq 0x1714c
movq %r12, %rdi
leaq 0x20(%rsp), %rsi
callq 0x17328
movq %rax, %rdi
movq %r14, %rsi
callq 0x17376
movq %r15, (%rax)
movl 0x20(%rsp), %eax
incl %eax
jmp 0x12209
movq 0x150(%rsp), %rdi
movq %r14, %rsi
callq 0x173dc
movq %rax, %rdi
leaq 0x120(%rsp), %rsi
callq 0x17442
movq 0x148(%rsp), %rdi
movq %r14, %rsi
callq 0x17502
movq %rax, %rdi
leaq 0x100(%rsp), %rsi
callq 0x17568
movq 0x140(%rsp), %rdi
movq %r14, %rsi
callq 0x17502
movq %rax, %rdi
leaq 0xe0(%rsp), %rsi
callq 0x17568
movq 0x138(%rsp), %rdi
movq %r14, %rsi
callq 0x17502
movq %rax, %rdi
leaq 0xc0(%rsp), %rsi
callq 0x17568
leaq 0xc0(%rsp), %rdi
callq 0x17632
leaq 0xe0(%rsp), %rdi
callq 0x17632
leaq 0x100(%rsp), %rdi
callq 0x17632
leaq 0x120(%rsp), %rdi
callq 0x1af48
leaq 0x40(%rsp), %rdi
callq 0x71a0
movq %r14, %rdi
callq 0x71a0
leaq 0x1f0(%rsp), %r15
jmp 0x11dfd
movq %rax, %rbp
cmpl $0x1, %edx
jne 0x12566
movq %r14, %r12
movq %rbp, %rdi
callq 0x74d0
leaq 0x60(%rsp), %rbx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x7170
movq %rbp, %rdi
callq 0x7160
movq %rbx, %rdi
callq 0x7540
leaq 0x20(%rsp), %rdi
movq %rax, %rsi
leaq 0x80(%rsp), %rdx
callq 0x9512
leaq 0x20(%rsp), %rbx
movq %rbx, %rdi
leaq 0x1add6(%rip), %rsi     # 0x2d152
callq 0x954d
movl %eax, %ebp
movq %rbx, %rdi
callq 0x71a0
movq 0x40(%rsp), %r14
leaq 0x60(%rsp), %rdi
callq 0x7540
testb %bpl, %bpl
je 0x12477
leaq 0x1bab8(%rip), %rdi     # 0x2de62
movq %r14, %rsi
movq %rax, %rdx
xorl %eax, %eax
callq 0x7050
leaq 0x60(%rsp), %rdi
callq 0x7788
callq 0x7660
movq %r12, %r14
leaq 0x60(%rsp), %r13
jmp 0x11f0e
movq 0x8(%rsp), %rax
movq 0x70(%rax), %r14
leaq 0x60(%rax), %r15
leaq 0x1bb41(%rip), %rbx     # 0x2df28
cmpq %r15, %r14
je 0x1240b
movq 0x20(%r14), %rsi
movq 0x40(%r14), %rdx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x7050
movq %r14, %rdi
callq 0x72d0
movq %rax, %r14
jmp 0x123e7
movq 0x8(%rsp), %rax
movq 0x80(%rax), %rsi
leaq 0x1bb11(%rip), %rdi     # 0x2df2f
xorl %eax, %eax
callq 0x7050
addq $0x11f8, %rsp           # imm = 0x11F8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1b9bf(%rip), %rdi     # 0x2ddfd
callq 0x75c0
pushq $0x8
popq %rdi
callq 0x71d0
leaq 0x1b9ca(%rip), %rcx     # 0x2de1c
jmp 0x12463
pushq $0x8
popq %rdi
callq 0x71d0
leaq 0x1b9d5(%rip), %rcx     # 0x2de38
movq %rcx, (%rax)
movq 0x32ae3(%rip), %rsi     # 0x44f50
movq %rax, %rdi
xorl %edx, %edx
callq 0x76a0
leaq 0x1ba3a(%rip), %rdi     # 0x2deb8
movq %r14, %rsi
movq %rax, %rdx
xorl %eax, %eax
callq 0x7050
pushq $0x64
popq %rdi
callq 0x74b0
jmp 0x124e2
movq %rax, %rbp
leaq 0x60(%rsp), %rdi
callq 0x7788
callq 0x7660
jmp 0x12566
movq %rax, %rdi
callq 0x955a
jmp 0x124e2
movq %rax, %rbp
leaq 0x20(%rsp), %rdi
callq 0x71a0
jmp 0x124c8
movq %rax, %rbp
movl $0x98, %esi
movq %r15, %rdi
callq 0x7400
jmp 0x12566
jmp 0x12504
jmp 0x12504
jmp 0x12504
jmp 0x124eb
movq %rax, %rbp
jmp 0x12566
jmp 0x1252f
jmp 0x12504
movq %rax, %rbp
jmp 0x12511
movq %rax, %rbp
leaq 0x80(%rsp), %rdi
callq 0x71a0
jmp 0x12507
jmp 0x1252f
movq %rax, %rbp
leaq 0x60(%rsp), %rdi
callq 0x71a0
leaq 0x20(%rsp), %rdi
callq 0x71a0
jmp 0x12532
movq %rax, %rbp
movl $0x98, %esi
movq %r15, %rdi
callq 0x7400
jmp 0x12532
movq %rax, %rbp
leaq 0xc0(%rsp), %rdi
callq 0x17632
leaq 0xe0(%rsp), %rdi
callq 0x17632
leaq 0x100(%rsp), %rdi
callq 0x17632
leaq 0x120(%rsp), %rdi
callq 0x1af48
leaq 0x40(%rsp), %rdi
callq 0x71a0
leaq 0xa0(%rsp), %rdi
callq 0x71a0
movq %rbp, %rdi
callq 0x76d0
nop