// File: 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
movq %rsp, %rbp
subq $0x380, %rsp            # imm = 0x380
movq %rsi, -0x2c0(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x2d0(%rbp)
leaq 0xf2ac(%rip), %rax      # 0x25ca8
addq $0x10, %rax
movq %rax, (%rdi)
addq $0x8, %rdi
movq %rdi, -0x2c8(%rbp)
callq 0x44b0
movq -0x2c0(%rbp), %rdi
callq 0x4570
testb $0x1, %al
jne 0x16a25
jmp 0x16a52
movq 0xf5bc(%rip), %rdi      # 0x25fe8
leaq 0x4d35(%rip), %rsi      # 0x1b768
callq 0x4330
jmp 0x16a3a
xorl %edi, %edi
callq 0x4400
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x17409
callq 0x5150
movq %rax, -0x2d8(%rbp)
jmp 0x16a60
movq -0x2d8(%rbp), %rax
testb $0x1, 0xec(%rax)
je 0x16abf
movq 0xf549(%rip), %rdi      # 0x25fc0
leaq 0x4d12(%rip), %rsi      # 0x1b790
callq 0x4330
movq %rax, -0x2e0(%rbp)
jmp 0x16a8c
movq -0x2c0(%rbp), %rsi
movq -0x2e0(%rbp), %rdi
callq 0x4320
movq %rax, -0x2e8(%rbp)
jmp 0x16aa8
movq -0x2e8(%rbp), %rdi
leaq 0x4a40(%rip), %rsi      # 0x1b4f6
callq 0x4330
jmp 0x16abd
jmp 0x16abf
movq -0x2c0(%rbp), %rdi
callq 0x4130
movq %rax, %rsi
leaq -0x228(%rbp), %rdi
movl $0x8, %edx
callq 0x4630
jmp 0x16ae1
movq -0x228(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x228(%rbp,%rax), %rdi
callq 0x4590
movb %al, -0x2e9(%rbp)
jmp 0x16b01
movb -0x2e9(%rbp), %al
testb $0x1, %al
jne 0x16b72
jmp 0x16b0d
movq 0xf4d4(%rip), %rdi      # 0x25fe8
leaq 0x4505(%rip), %rsi      # 0x1b020
callq 0x4330
movq %rax, -0x2f8(%rbp)
jmp 0x16b29
movq -0x2c0(%rbp), %rsi
movq -0x2f8(%rbp), %rdi
callq 0x4320
movq %rax, -0x300(%rbp)
jmp 0x16b45
movq -0x300(%rbp), %rdi
leaq 0x49a3(%rip), %rsi      # 0x1b4f6
callq 0x4330
jmp 0x16b5a
xorl %edi, %edi
callq 0x4400
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x173fd
leaq -0x248(%rbp), %rdi
movq %rdi, -0x308(%rbp)
callq 0x44b0
movq -0x308(%rbp), %rsi
leaq -0x228(%rbp), %rdi
callq 0x4080
jmp 0x16b9a
jmp 0x16b9c
movq -0x228(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x228(%rbp,%rax), %rdi
callq 0x4590
movb %al, -0x309(%rbp)
jmp 0x16bbc
movb -0x309(%rbp), %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x30a(%rbp)
jne 0x16bd1
jmp 0x16c00
xorl %eax, %eax
movl %eax, %esi
leaq -0x248(%rbp), %rdi
callq 0x46c0
movq %rax, -0x318(%rbp)
jmp 0x16bea
movq -0x318(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x4d, %eax
setne %al
movb %al, -0x30a(%rbp)
movb -0x30a(%rbp), %al
testb $0x1, %al
jne 0x16c0c
jmp 0x16c43
leaq -0x228(%rbp), %rdi
leaq -0x248(%rbp), %rsi
callq 0x4080
jmp 0x16c21
jmp 0x16b9c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0x248(%rbp), %rdi
callq 0x41e0
jmp 0x173fd
xorl %eax, %eax
movl %eax, %edx
movq %rdx, -0x328(%rbp)
leaq -0x248(%rbp), %rdi
movq %rdi, -0x320(%rbp)
movl $0x3d, %esi
callq 0x4480
movq -0x328(%rbp), %rdx
movq -0x320(%rbp), %rdi
addl $0x2, %eax
movl %eax, -0x24c(%rbp)
movl $0x2c, %esi
callq 0x4480
movq -0x320(%rbp), %rsi
movl -0x24c(%rbp), %ecx
subl %ecx, %eax
movl %eax, -0x250(%rbp)
movslq -0x24c(%rbp), %rdx
movslq -0x250(%rbp), %rcx
leaq -0x270(%rbp), %rdi
callq 0x4360
jmp 0x16cb8
movq -0x2d0(%rbp), %rdi
addq $0x8, %rdi
leaq -0x270(%rbp), %rsi
callq 0x4420
leaq -0x270(%rbp), %rdi
callq 0x41e0
movslq -0x250(%rbp), %rdi
movl $0x8, %esi
callq 0x4220
movq %rax, %rcx
movq -0x2d0(%rbp), %rax
movq %rcx, 0x28(%rax)
cmpq $0x0, 0x28(%rax)
jne 0x16d1d
movq 0xf2e0(%rip), %rdi      # 0x25fe8
leaq 0x4a99(%rip), %rsi      # 0x1b7a8
callq 0x4330
jmp 0x16d16
xorl %edi, %edi
callq 0x4400
movl $0x0, -0x274(%rbp)
movl -0x274(%rbp), %eax
cmpl -0x250(%rbp), %eax
jge 0x16de3
movl -0x274(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdi
movl $0x4, %esi
callq 0x4220
movq %rax, %rsi
movq -0x2d0(%rbp), %rax
movq 0x28(%rax), %rcx
movslq -0x274(%rbp), %rdx
movq %rsi, (%rcx,%rdx,8)
movq 0x28(%rax), %rax
movslq -0x274(%rbp), %rcx
cmpq $0x0, (%rax,%rcx,8)
jne 0x16dcd
movq 0xf267(%rip), %rdi      # 0x25fe8
leaq 0x4a40(%rip), %rsi      # 0x1b7c8
callq 0x4330
movq %rax, -0x330(%rbp)
jmp 0x16d96
movq -0x330(%rbp), %rdi
movl -0x274(%rbp), %esi
callq 0x45c0
movq %rax, -0x338(%rbp)
jmp 0x16db1
movq -0x338(%rbp), %rdi
leaq 0x4a29(%rip), %rsi      # 0x1b7e8
callq 0x4330
jmp 0x16dc6
xorl %edi, %edi
callq 0x4400
jmp 0x16dcf
movl -0x274(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x274(%rbp)
jmp 0x16d27
movq -0x2d0(%rbp), %rax
movss 0x4972(%rip), %xmm0     # 0x1b764
movss %xmm0, 0x44(%rax)
movss 0x4961(%rip), %xmm0     # 0x1b760
movss %xmm0, 0x40(%rax)
movl $0x0, -0x278(%rbp)
movl -0x278(%rbp), %eax
cmpl -0x250(%rbp), %eax
jge 0x16f8b
leaq -0x228(%rbp), %rdi
leaq -0x248(%rbp), %rsi
callq 0x4080
jmp 0x16e35
movl $0x0, -0x27c(%rbp)
movl -0x27c(%rbp), %eax
cmpl -0x278(%rbp), %eax
jg 0x16f75
movl -0x27c(%rbp), %eax
shll $0x3, %eax
movslq %eax, %rdx
leaq -0x2a0(%rbp), %rdi
leaq -0x248(%rbp), %rsi
movl $0x8, %ecx
callq 0x4360
jmp 0x16e77
leaq -0x2a0(%rbp), %rdi
callq 0x4130
movq %rax, %rdi
callq 0x4450
movq -0x2d0(%rbp), %rax
cvtsd2ss %xmm0, %xmm0
movq 0x28(%rax), %rax
movslq -0x278(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x27c(%rbp), %rcx
movss %xmm0, (%rax,%rcx,4)
leaq -0x2a0(%rbp), %rdi
callq 0x41e0
movq -0x2d0(%rbp), %rax
movq 0x28(%rax), %rcx
movslq -0x278(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movslq -0x27c(%rbp), %rdx
movss (%rcx,%rdx,4), %xmm1
movss 0x44(%rax), %xmm0
ucomiss %xmm1, %xmm0
jbe 0x16f10
movq -0x2d0(%rbp), %rax
movq 0x28(%rax), %rcx
movslq -0x278(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movslq -0x27c(%rbp), %rdx
movss (%rcx,%rdx,4), %xmm0
movss %xmm0, 0x44(%rax)
movq -0x2d0(%rbp), %rax
movq 0x28(%rax), %rcx
movslq -0x278(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movslq -0x27c(%rbp), %rdx
movss (%rcx,%rdx,4), %xmm0
ucomiss 0x40(%rax), %xmm0
jbe 0x16f5f
movq -0x2d0(%rbp), %rax
movq 0x28(%rax), %rcx
movslq -0x278(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movslq -0x27c(%rbp), %rdx
movss (%rcx,%rdx,4), %xmm0
movss %xmm0, 0x40(%rax)
jmp 0x16f61
movl -0x27c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x27c(%rbp)
jmp 0x16e3f
jmp 0x16f77
movl -0x278(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x278(%rbp)
jmp 0x16e0e
movslq -0x250(%rbp), %rdi
movl $0x8, %esi
callq 0x4220
movq %rax, %rcx
movq -0x2d0(%rbp), %rax
movq %rcx, 0x38(%rax)
cmpq $0x0, 0x38(%rax)
jne 0x16fcd
movq 0xf030(%rip), %rdi      # 0x25fe8
leaq 0x482c(%rip), %rsi      # 0x1b7eb
callq 0x4330
jmp 0x16fc6
xorl %edi, %edi
callq 0x4400
movl $0x0, -0x2a4(%rbp)
movl -0x2a4(%rbp), %eax
cmpl -0x250(%rbp), %eax
jge 0x17093
movl -0x2a4(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdi
movl $0x4, %esi
callq 0x4220
movq %rax, %rsi
movq -0x2d0(%rbp), %rax
movq 0x38(%rax), %rcx
movslq -0x2a4(%rbp), %rdx
movq %rsi, (%rcx,%rdx,8)
movq 0x38(%rax), %rax
movslq -0x2a4(%rbp), %rcx
cmpq $0x0, (%rax,%rcx,8)
jne 0x1707d
movq 0xefb7(%rip), %rdi      # 0x25fe8
leaq 0x47e5(%rip), %rsi      # 0x1b81d
callq 0x4330
movq %rax, -0x340(%rbp)
jmp 0x17046
movq -0x340(%rbp), %rdi
movl -0x2a4(%rbp), %esi
callq 0x45c0
movq %rax, -0x348(%rbp)
jmp 0x17061
movq -0x348(%rbp), %rdi
leaq 0x4779(%rip), %rsi      # 0x1b7e8
callq 0x4330
jmp 0x17076
xorl %edi, %edi
callq 0x4400
jmp 0x1707f
movl -0x2a4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2a4(%rbp)
jmp 0x16fd7
movl $0x0, -0x2a8(%rbp)
movl -0x2a8(%rbp), %eax
cmpl -0x250(%rbp), %eax
jge 0x171aa
movl $0x0, -0x2ac(%rbp)
movl -0x2ac(%rbp), %eax
cmpl -0x2a8(%rbp), %eax
jg 0x17194
movq -0x2d0(%rbp), %rdi
addq $0x8, %rdi
movslq -0x2a8(%rbp), %rsi
callq 0x46c0
movq %rax, -0x350(%rbp)
jmp 0x170eb
movq -0x2d0(%rbp), %rdi
movq -0x350(%rbp), %rax
movb (%rax), %al
movb %al, -0x359(%rbp)
addq $0x8, %rdi
movslq -0x2ac(%rbp), %rsi
callq 0x46c0
movq %rax, -0x358(%rbp)
jmp 0x1711a
movq -0x2d0(%rbp), %rdi
movb -0x359(%rbp), %al
movq -0x358(%rbp), %rcx
movsbl (%rcx), %edx
movsbl %al, %esi
callq 0x17420
movss %xmm0, -0x360(%rbp)
jmp 0x17143
movq -0x2d0(%rbp), %rax
movss -0x360(%rbp), %xmm0
subss 0x44(%rax), %xmm0
movss 0x40(%rax), %xmm1
subss 0x44(%rax), %xmm1
divss %xmm1, %xmm0
movq 0x38(%rax), %rax
movslq -0x2a8(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x2ac(%rbp), %rcx
movss %xmm0, (%rax,%rcx,4)
movl -0x2ac(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2ac(%rbp)
jmp 0x170b9
jmp 0x17196
movl -0x2a8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2a8(%rbp)
jmp 0x1709d
callq 0x5150
movq %rax, -0x368(%rbp)
jmp 0x171b8
movq -0x368(%rbp), %rax
testb $0x1, 0xec(%rax)
je 0x173d1
movq 0xeded(%rip), %rdi      # 0x25fc0
leaq 0x4660(%rip), %rsi      # 0x1b83a
callq 0x4330
jmp 0x171e1
movl $0x0, -0x2b0(%rbp)
movl -0x2b0(%rbp), %eax
cmpl -0x250(%rbp), %eax
jge 0x172f5
movq 0xedbc(%rip), %rdi      # 0x25fc0
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
movl $0x9, %esi
callq 0x176d0
jmp 0x1721a
movq -0x2d0(%rbp), %rdi
addq $0x8, %rdi
movslq -0x2b0(%rbp), %rsi
callq 0x46c0
movq %rax, -0x370(%rbp)
jmp 0x1723a
movq -0x370(%rbp), %rax
movsbl (%rax), %esi
movq 0xed75(%rip), %rdi      # 0x25fc0
callq 0x43e0
jmp 0x17252
movl $0x0, -0x2b4(%rbp)
movl -0x2b4(%rbp), %eax
cmpl -0x2b0(%rbp), %eax
jg 0x172ca
movq 0xed4f(%rip), %rdi      # 0x25fc0
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
movl $0x9, %esi
callq 0x176d0
jmp 0x17287
movq -0x2d0(%rbp), %rax
movq 0x38(%rax), %rax
movslq -0x2b0(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x2b4(%rbp), %rcx
movss (%rax,%rcx,4), %xmm0
movq 0xed10(%rip), %rdi      # 0x25fc0
callq 0x4290
jmp 0x172b7
jmp 0x172b9
movl -0x2b4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2b4(%rbp)
jmp 0x1725c
movq 0xecef(%rip), %rdi      # 0x25fc0
leaq 0x421e(%rip), %rsi      # 0x1b4f6
callq 0x4330
jmp 0x172df
jmp 0x172e1
movl -0x2b0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2b0(%rbp)
jmp 0x171eb
movq 0xecc4(%rip), %rdi      # 0x25fc0
leaq 0x41f3(%rip), %rsi      # 0x1b4f6
callq 0x4330
jmp 0x1730a
movq 0xecaf(%rip), %rdi      # 0x25fc0
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
movl $0x9, %esi
callq 0x176d0
jmp 0x17327
movq 0xec92(%rip), %rdi      # 0x25fc0
movl $0x20, %esi
callq 0x43e0
jmp 0x1733a
movl $0x0, -0x2b8(%rbp)
movl -0x2b8(%rbp), %eax
cmpl -0x250(%rbp), %eax
jg 0x173ba
movq 0xec67(%rip), %rdi      # 0x25fc0
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
movl $0x9, %esi
callq 0x176d0
jmp 0x1736f
movq -0x2d0(%rbp), %rdi
addq $0x8, %rdi
movslq -0x2b8(%rbp), %rsi
callq 0x46c0
movq %rax, -0x378(%rbp)
jmp 0x1738f
movq -0x378(%rbp), %rax
movsbl (%rax), %esi
movq 0xec20(%rip), %rdi      # 0x25fc0
callq 0x43e0
jmp 0x173a7
jmp 0x173a9
movl -0x2b8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2b8(%rbp)
jmp 0x17344
movq 0xebff(%rip), %rdi      # 0x25fc0
leaq 0x412d(%rip), %rsi      # 0x1b4f5
callq 0x4330
jmp 0x173cf
jmp 0x173d1
movq -0x2d0(%rbp), %rax
movb $0x1, 0x30(%rax)
leaq -0x248(%rbp), %rdi
callq 0x41e0
leaq -0x228(%rbp), %rdi
callq 0x40b0
addq $0x380, %rsp            # imm = 0x380
popq %rbp
retq
leaq -0x228(%rbp), %rdi
callq 0x40b0
movq -0x2c8(%rbp), %rdi
callq 0x41e0
movq -0x18(%rbp), %rdi
callq 0x45e0
nop