// File: /workspace/github_cpp_makefile_star2_O2/gcollet[P]MstatX/src/scoring_matrix.cpp
// Function: ScoringMatrix::ScoringMatrix(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
ScoringMatrix :: ScoringMatrix(string fname)
{
  /* Open file */
	if(fname.empty()){
		cerr << "Error, score matrix file name is empty\n";
		exit(0);
	}
	if (Options::Get().verbose){
		cout << "Read Scoring Matrix in " << fname << "\n";
	}
	ifstream file(fname.c_str());
	if (!file.good()){
	  cerr << "Cannot open file " << fname << "\n";
		exit(0);
	}
	
	/* Read file */
	string s;
	getline(file,s);
	while (file.good() && s[0] != 'M'){
	  getline(file,s);
	}
	
	/* Read Alphabet */
	int alphabet_begin = (int) s.find('=') + 2;
	int alphabet_size = (int) s.find(',') - alphabet_begin;
	alphabet = s.substr(alphabet_begin,	alphabet_size);
	
	/* Allocate the matrix */
	matrix = (float **) calloc (alphabet_size, sizeof(float *));
	if (matrix == NULL){
	  cerr << "Cannot allocate scoring matrix\n";
		exit(0);
	}
	for (int i(0); i < alphabet_size; ++i) {
		matrix[i] = (float *) calloc(i + 1, sizeof(float));
		if (matrix[i] == NULL){
			cerr << "Cannot allocate scoring matrix[" << i << "]\n";
			exit(0);
		}
	}
	
	
	/* Read the matrix */
  min = 1000; max = -1000;
	for (int i(0); i < alphabet_size; ++i) {
		getline(file,s);
		for (int j(0); j <=i ; j++){
			matrix[i][j] = atof(s.substr(j*8, 8).c_str());
      if (matrix[i][j] < min)
        min = matrix[i][j];
      if (matrix[i][j] > max)
        max = matrix[i][j];
		}
	}
	
	
	/* Allocate the norm_matrix */
	norm_matrix = (float **) calloc (alphabet_size, sizeof(float *));
	if (norm_matrix == NULL){
	  cerr << "Cannot allocate the normalized amino acid vector\n";
		exit(0);
	}
	for (int i(0); i < alphabet_size; ++i) {
		norm_matrix[i] = (float *) calloc(i+1, sizeof(float));
		if (norm_matrix[i] == NULL){
			cerr << "Cannot allocate norm_matrix[" << i << "]\n";
			exit(0);
		}
	}
	
	/* Calculate normalized vector */
	
	for (int i(0); i < alphabet_size; ++i) {
		for (int j(0); j <= i; ++j){
			norm_matrix[i][j] = (score(alphabet[i], alphabet[j]) - min) / (max - min);
		}
	}
	
	if (Options::Get().verbose){
		cout << "Normalized :\n";
		for (int i(0); i < alphabet_size; ++i) {
			cout.width(9);
			cout << alphabet[i];
			for (int j(0); j <= i; j++){
				cout.width(9);
				cout << norm_matrix[i][j];
			}
			cout << "\n";
		}
		cout << "\n";
		cout.width(9);
		cout << ' ';
		for (int j(0); j <= alphabet_size ; j++){
			cout.width(9);
			cout << alphabet[j];
		} 
		cout << "\n\n";
	}
	
	is_set = true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x268, %rsp            # imm = 0x268
leaq 0x7f10(%rip), %rax      # 0x12ce8
movq %rax, (%rdi)
leaq 0x18(%rdi), %rax
movq %rax, 0x8(%rdi)
andq $0x0, 0x10(%rdi)
leaq 0x8(%rdi), %rax
movq %rax, (%rsp)
movb $0x0, 0x18(%rdi)
cmpq $0x0, 0x8(%rsi)
je 0xb29f
movq %rsi, %r15
movq %rdi, %r14
callq 0x4a00
cmpb $0x1, 0xec(%rax)
jne 0xae40
movq 0x81a6(%rip), %rdi      # 0x12fc0
leaq 0x2977(%rip), %rsi      # 0xd798
callq 0x4250
movq %rax, %rdi
movq %r15, %rsi
callq 0x4240
leaq 0x26be(%rip), %rsi      # 0xd4f6
movq %rax, %rdi
callq 0x4250
movq (%r15), %rsi
leaq 0x60(%rsp), %rdi
pushq $0x8
popq %rdx
callq 0x4470
movq 0x60(%rsp), %rax
movq -0x18(%rax), %rax
cmpl $0x0, 0x80(%rsp,%rax)
jne 0xb2b7
leaq 0x30(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0x60(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x4060
leaq 0x60(%rsp), %rbx
leaq 0x20(%rsp), %r15
movq 0x60(%rsp), %rax
movq -0x18(%rax), %rax
cmpl $0x0, 0x80(%rsp,%rax)
jne 0xaebb
movq 0x20(%rsp), %rax
cmpb $0x4d, (%rax)
je 0xaebb
movq %rbx, %rdi
movq %r15, %rsi
callq 0x4060
jmp 0xae91
leaq 0x20(%rsp), %r15
pushq $0x3d
popq %rsi
movq %r15, %rdi
xorl %edx, %edx
callq 0x4340
movq %rax, %r12
addl $0x2, %r12d
pushq $0x2c
popq %rsi
movq %r15, %rdi
xorl %edx, %edx
callq 0x4340
movq %rax, %rbx
subl %r12d, %ebx
movslq %r12d, %rdx
movslq %ebx, %r12
leaq 0x40(%rsp), %rdi
movq %r15, %rsi
movq %r12, %rcx
callq 0x4280
leaq 0x40(%rsp), %r15
movq (%rsp), %rdi
movq %r15, %rsi
callq 0x42f0
movq %r15, %rdi
callq 0x4110
pushq $0x8
popq %rsi
movq %r12, 0x10(%rsp)
movq %r12, %rdi
callq 0x4190
movq %rax, 0x28(%r14)
testq %rax, %rax
je 0xb2e9
movq %rax, %r15
xorl %eax, %eax
testl %ebx, %ebx
cmovgl %ebx, %eax
movq %rax, 0x8(%rsp)
negq %rax
movq %rax, 0x18(%rsp)
pushq $-0x1
popq %rbx
pushq $0x1
popq %r13
pushq $0x4
popq %rbp
movq 0x18(%rsp), %rax
addq %r13, %rax
cmpq $0x1, %rax
je 0xafb5
movq %r13, %rdi
movq %rbp, %rsi
callq 0x4190
movq %rax, -0x8(%r15,%r13,8)
movq 0x28(%r14), %r15
incl %ebx
cmpq $0x0, -0x8(%r15,%r13,8)
leaq 0x1(%r13), %r13
jne 0xaf54
movq 0x805d(%rip), %rdi      # 0x12fe8
leaq 0x283e(%rip), %rsi      # 0xd7d0
callq 0x4250
movq %rax, %rdi
movl %ebx, %esi
callq 0x4420
leaq 0x2848(%rip), %rsi      # 0xd7f0
movq %rax, %rdi
callq 0x4250
jmp 0xb0f3
movsd 0x27a3(%rip), %xmm0     # 0xd760
movsd %xmm0, 0x40(%r14)
pushq $0x1
popq %r12
xorl %ebx, %ebx
leaq 0x40(%rsp), %rbp
cmpq 0x8(%rsp), %rbx
je 0xb070
leaq 0x60(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x4060
xorl %r15d, %r15d
xorl %r13d, %r13d
cmpq %r13, %r12
je 0xb065
movq %rbp, %rdi
leaq 0x20(%rsp), %rsi
movq %r15, %rdx
pushq $0x8
popq %rcx
callq 0x4280
movq 0x40(%rsp), %rdi
callq 0x4310
cvtsd2ss %xmm0, %xmm0
movq 0x28(%r14), %rax
movq (%rax,%rbx,8), %rax
movss %xmm0, (%rax,%r13,4)
movq %rbp, %rdi
callq 0x4110
movq 0x28(%r14), %rax
movq (%rax,%rbx,8), %rax
movss (%rax,%r13,4), %xmm0
movss 0x44(%r14), %xmm1
ucomiss %xmm0, %xmm1
jbe 0xb04f
movss %xmm0, 0x44(%r14)
movss (%rax,%r13,4), %xmm0
ucomiss 0x40(%r14), %xmm0
jbe 0xb05c
movss %xmm0, 0x40(%r14)
incq %r13
addq $0x8, %r15
jmp 0xafee
incq %rbx
incq %r12
jmp 0xafce
pushq $0x8
popq %rsi
movq 0x10(%rsp), %rdi
callq 0x4190
movq %rax, 0x38(%r14)
testq %rax, %rax
je 0xb301
movq %rax, %r15
pushq $-0x1
popq %rbx
pushq $0x1
popq %r13
pushq $0x4
popq %rbp
movq 0x18(%rsp), %rax
addq %r13, %rax
cmpq $0x1, %rax
je 0xb0fa
movq %r13, %rdi
movq %rbp, %rsi
callq 0x4190
movq %rax, -0x8(%r15,%r13,8)
movq 0x38(%r14), %r15
incl %ebx
cmpq $0x0, -0x8(%r15,%r13,8)
leaq 0x1(%r13), %r13
jne 0xb097
movq 0x7f1a(%rip), %rdi      # 0x12fe8
leaq 0x2750(%rip), %rsi      # 0xd825
callq 0x4250
movq %rax, %rdi
movl %ebx, %esi
callq 0x4420
leaq 0x2705(%rip), %rsi      # 0xd7f0
movq %rax, %rdi
callq 0x4250
xorl %edi, %edi
callq 0x42d0
pushq $0x1
popq %rbx
xorl %r15d, %r15d
cmpq 0x8(%rsp), %r15
je 0xb158
xorl %r12d, %r12d
cmpq %r12, %rbx
je 0xb150
movq 0x8(%r14), %rax
movsbl (%rax,%r15), %esi
movsbl (%rax,%r12), %edx
movq %r14, %rdi
callq 0xb364
movss 0x44(%r14), %xmm1
subss %xmm1, %xmm0
movss 0x40(%r14), %xmm2
subss %xmm1, %xmm2
divss %xmm2, %xmm0
movq 0x38(%r14), %rax
movq (%rax,%r15,8), %rax
movss %xmm0, (%rax,%r12,4)
incq %r12
jmp 0xb10a
incq %r15
incq %rbx
jmp 0xb100
callq 0x4a00
cmpb $0x1, 0xec(%rax)
jne 0xb274
movq 0x7e4f(%rip), %rbx      # 0x12fc0
leaq 0x26ca(%rip), %rsi      # 0xd842
movq %rbx, %rdi
callq 0x4250
pushq $0x1
popq %r15
xorl %r13d, %r13d
leaq 0x2368(%rip), %r12      # 0xd4f6
cmpq 0x8(%rsp), %r13
je 0xb1fd
movq (%rbx), %rax
movq -0x18(%rax), %rax
movq $0x9, 0x10(%rbx,%rax)
movq (%rsp), %rax
movq (%rax), %rax
movsbl (%rax,%r13), %esi
movq %rbx, %rdi
callq 0x42b0
xorl %ebp, %ebp
cmpq %rbp, %r15
je 0xb1ea
movq (%rbx), %rax
movq -0x18(%rax), %rax
movq $0x9, 0x10(%rbx,%rax)
movq 0x38(%r14), %rax
movq (%rax,%r13,8), %rax
movss (%rax,%rbp,4), %xmm0
movq %rbx, %rdi
callq 0x41e0
incq %rbp
jmp 0xb1bb
movq %rbx, %rdi
movq %r12, %rsi
callq 0x4250
incq %r13
incq %r15
jmp 0xb18e
movq 0x7dbc(%rip), %rbx      # 0x12fc0
leaq 0x22eb(%rip), %rsi      # 0xd4f6
movq %rbx, %rdi
callq 0x4250
movq (%rbx), %rax
movq -0x18(%rax), %rax
movq $0x9, 0x10(%rbx,%rax)
pushq $0x20
popq %rsi
movq %rbx, %rdi
callq 0x42b0
xorl %r15d, %r15d
cmpq 0x10(%rsp), %r15
jg 0xb261
movq (%rbx), %rax
movq -0x18(%rax), %rax
movq $0x9, 0x10(%rbx,%rax)
movq (%rsp), %rax
movq (%rax), %rax
movsbl (%rax,%r15), %esi
movq %rbx, %rdi
callq 0x42b0
incq %r15
jmp 0xb231
movq 0x7d58(%rip), %rdi      # 0x12fc0
leaq 0x2286(%rip), %rsi      # 0xd4f5
callq 0x4250
movb $0x1, 0x30(%r14)
leaq 0x20(%rsp), %rdi
callq 0x4110
leaq 0x60(%rsp), %rdi
callq 0x4090
addq $0x268, %rsp            # imm = 0x268
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x7d42(%rip), %rdi      # 0x12fe8
leaq 0x24c3(%rip), %rsi      # 0xd770
callq 0x4250
jmp 0xb0f3
movq 0x7d2a(%rip), %rdi      # 0x12fe8
leaq 0x1d5b(%rip), %rsi      # 0xd020
callq 0x4250
movq %rax, %rdi
movq %r15, %rsi
callq 0x4240
leaq 0x221a(%rip), %rsi      # 0xd4f6
movq %rax, %rdi
callq 0x4250
jmp 0xb0f3
movq 0x7cf8(%rip), %rdi      # 0x12fe8
leaq 0x24b9(%rip), %rsi      # 0xd7b0
callq 0x4250
jmp 0xb0f3
movq 0x7ce0(%rip), %rdi      # 0x12fe8
leaq 0x24e4(%rip), %rsi      # 0xd7f3
callq 0x4250
jmp 0xb0f3
movq %rax, %rbx
jmp 0xb348
jmp 0xb33b
jmp 0xb33b
jmp 0xb324
movq %rax, %rbx
jmp 0xb352
jmp 0xb33b
jmp 0xb33b
jmp 0xb33b
jmp 0xb33b
jmp 0xb33b
jmp 0xb33b
jmp 0xb33b
jmp 0xb33b
jmp 0xb33b
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x4110
leaq 0x60(%rsp), %rdi
callq 0x4090
movq (%rsp), %rdi
callq 0x4110
movq %rbx, %rdi
callq 0x4430
nop