// File: /workspace/github_c_makefile_star2_O1/ugobas[P]tnm/align_tnm.c
// Function: Align_atoms
int Align_atoms(atom *atoms1, atom *atoms2,          // Output
		struct chain *ch1, struct chain *ch2) // Input
{
  int ini1=ch1->ini_atom, natoms1=ch1->natoms, ini_res1=ch1->ini_res;
  int ini2=ch2->ini_atom, natoms2=ch2->natoms, ini_res2=ch2->ini_res;
  int *alignres=ch1->alignres;
  int n=0, i, i1, i2max=ini2+natoms2;
  printf("Aligning atoms in chain %d %c %d residues and %d %c %d residues\n",
	 ch1->match,ch1->label,ch1->nres, ch2->match,ch2->label,ch2->nres);

  if(0){
    for(i1=0; i1<ch1->nres; i1++){
      printf("%c ", ch1->seq[i1]);
      int i2=ch1->alignres[i1];
      if(i2>=0){printf("%c\n", ch2->seq[i2]);}
      else{printf("-\n");}
    }
    printf("chains %c %c\n", ch1->label, ch2->label);
    exit(8);
  }

  // Initialize
  for(i=ini1; i<(ini1+natoms1); i++)atoms1[i].ali=-1;
  for(i=ini2; i<(ini2+natoms2); i++)atoms2[i].ali=-1;
  // Look if aligned
  int ares2=ini2;
  atom *atom1;
  for(i1=ini1; i1<(ini1+natoms1); i1++){
    atom1=atoms1+i1;
    int res2=alignres[atom1->res-ini_res1];
    if(res2<0){continue;} res2+=ini_res2;
    int iali=-1, i2=ares2;
    atom *atom2=atoms2+ares2; ;
    while((atom2->res<res2)&&(i2<i2max)){atom2++; i2++;}
    ares2=i2;
    while((i2<i2max)&&(atom2->res==res2)){
      if((atom2->ali<0)&&(atom2->name[1]==atom1->name[1])){
	if((atom2->name[0]==atom1->name[0])&&
	   (atom2->name[2]==atom1->name[2])){
	  atom1->ali=i2; atom2->ali=i1; n++; break; // Same name
	}else if(iali<0){
	  iali=i2; // Same side-chain index
	}
      }
      i2++; atom2++;
    }
    if(atom1->ali>=0)continue;
    // For main chain atoms we require that the name coincides exactly
    // For side chain atoms, the same side-chain index is enough
    atom1->main=Is_atom_main(atom1->name, ch1->type);
    if((atom1->main==0)&&(iali>=0)){
      atom1->ali=iali; (atoms2+iali)->ali=i1; n++; continue;
    }
    // Not aligned atom
    if(iali>=0){atom2=atoms2+iali;}
    else{atom2=atoms2+ares2;}
    printf("Not aligned: 1: %s%d%c %c 2: %s%d%c %c",
	   atom1->name, atom1->res, atom1->aa, ch1->label,
	   atom2->name, atom2->res, atom2->aa, ch2->label);
    printf(" Aligned res: %d iali: %d\n", ares2, iali);
  }

  if(DEBUG){
    printf("%d Aligned atoms:\n", n);
    for(i=ini1; i<(ini1+30); i++){
      atom *atom1=atoms1+i;
      if(atom1->ali<0)continue;
      atom *atom2=atoms2+atom1->ali;
      printf("%s %3d %d - %s %3d %d\n",atom1->name,atom1->res,i,
	     atom2->name,atom2->res, atom1->ali);
    }
    //exit(8);
    }
  return(n);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rcx, %rax
movq %rdx, %rcx
movq %rsi, %rbp
movq %rdi, %r15
movslq (%rdx), %r14
movslq 0x4(%rdx), %rbx
movslq 0x18(%rdx), %rdx
movq %rdx, 0x18(%rsp)
movl (%rax), %r13d
movl 0x4(%rax), %r12d
movl 0x18(%rax), %edx
movl %edx, 0xc(%rsp)
movq 0x38(%rcx), %rdx
movq %rdx, 0x10(%rsp)
movl 0x40(%rcx), %esi
movsbl 0x34(%rcx), %edx
movq %rcx, 0x38(%rsp)
movl 0x1c(%rcx), %ecx
movl 0x40(%rax), %r8d
movsbl 0x34(%rax), %r9d
movq %rax, 0x40(%rsp)
movl 0x1c(%rax), %r10d
subq $0x8, %rsp
leaq 0x43bf8(%rip), %rdi     # 0x56388
xorl %eax, %eax
pushq %r10
callq 0x20f0
movq %r15, %rdi
addq $0x10, %rsp
leaq (%rbx,%r14), %rax
testq %rbx, %rbx
jle 0x127c9
imulq $0x70, %r14, %rcx
addq %rdi, %rcx
addq $0x54, %rcx
movq %r14, %rdx
movl $0xffffffff, (%rcx)     # imm = 0xFFFFFFFF
incq %rdx
addq $0x70, %rcx
cmpq %rax, %rdx
jl 0x127b7
leal (%r12,%r13), %r15d
testl %r12d, %r12d
jle 0x127f5
movslq %r13d, %rcx
movslq %r15d, %rdx
imulq $0x70, %rcx, %rsi
addq %rbp, %rsi
addq $0x54, %rsi
movl $0xffffffff, (%rsi)     # imm = 0xFFFFFFFF
incq %rcx
addq $0x70, %rsi
cmpq %rdx, %rcx
jl 0x127e3
testl %ebx, %ebx
movq 0x18(%rsp), %r8
movl 0xc(%rsp), %r9d
movq 0x10(%rsp), %r10
jle 0x129bf
movslq %eax, %r11
movl $0x0, 0x8(%rsp)
movq %rbp, 0x30(%rsp)
movq %rdi, 0x28(%rsp)
movq %r11, 0x20(%rsp)
imulq $0x70, %r14, %r12
movslq 0x64(%rdi,%r12), %rax
subq %r8, %rax
movl (%r10,%rax,4), %eax
testl %eax, %eax
js 0x1299f
addl %r9d, %eax
movslq %r13d, %rdx
imulq $0x70, %rdx, %rsi
leaq (%rsi,%rbp), %rcx
cmpl %eax, 0x64(%rbp,%rsi)
setl %sil
cmpl %r15d, %edx
setl %dl
andb %sil, %dl
cmpb $0x1, %dl
jne 0x12879
movq %rcx, %rdx
addq $0x70, %rcx
incl %r13d
cmpl %eax, 0xd4(%rdx)
jge 0x12879
cmpl %r15d, %r13d
jl 0x12862
addq %rdi, %r12
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
cmpl %r15d, %r13d
jge 0x128cc
addq $0x18, %rcx
movl %r13d, %edx
cmpl %eax, 0x4c(%rcx)
jne 0x128cc
cmpl $0x0, 0x3c(%rcx)
jns 0x128c1
movb 0x1(%rcx), %sil
cmpb 0x19(%r12), %sil
jne 0x128c1
movb (%rcx), %sil
cmpb 0x18(%r12), %sil
jne 0x128bc
movb 0x2(%rcx), %sil
cmpb 0x1a(%r12), %sil
je 0x129ad
testl %ebx, %ebx
cmovsl %edx, %ebx
incl %edx
addq $0x70, %rcx
cmpl %edx, %r15d
jne 0x1288d
cmpl $0x0, 0x54(%r12)
jns 0x1299f
leaq 0x18(%r12), %rbp
movq 0x38(%rsp), %rax
movl 0x28(%rax), %esi
movq %rbp, %rdi
callq 0x15bde
movl %eax, 0x48(%r12)
movl %ebx, %ecx
testl %eax, %eax
jne 0x12915
testl %ebx, %ebx
js 0x12915
movl %ebx, 0x54(%r12)
imulq $0x70, %rcx, %rax
movq 0x30(%rsp), %rbp
movl %r14d, 0x54(%rbp,%rax)
incl 0x8(%rsp)
jmp 0x12986
testl %ebx, %ebx
movslq %r13d, %rax
cmovnsq %rcx, %rax
imulq $0x70, %rax, %rax
movl 0x64(%r12), %edx
movsbl 0x68(%r12), %ecx
movq 0x38(%rsp), %rsi
movsbl 0x34(%rsi), %r8d
movq %rbp, %rsi
movq 0x30(%rsp), %rbp
leaq 0x18(%rbp,%rax), %r9
movl 0x4c(%r9), %r10d
movsbl 0x50(%r9), %r11d
movq 0x40(%rsp), %rax
movsbl 0x34(%rax), %r12d
subq $0x8, %rsp
leaq 0x43a67(%rip), %rdi     # 0x563c9
xorl %eax, %eax
pushq %r12
pushq %r11
pushq %r10
callq 0x20f0
addq $0x20, %rsp
leaq 0x43a76(%rip), %rdi     # 0x563f0
movl %r13d, %esi
movl %ebx, %edx
xorl %eax, %eax
callq 0x20f0
movq 0x28(%rsp), %rdi
movq 0x18(%rsp), %r8
movl 0xc(%rsp), %r9d
movq 0x10(%rsp), %r10
movq 0x20(%rsp), %r11
incq %r14
cmpq %r11, %r14
jl 0x12826
jmp 0x129c7
movl %edx, 0x54(%r12)
movl %r14d, 0x3c(%rcx)
incl 0x8(%rsp)
jmp 0x128cc
movl $0x0, 0x8(%rsp)
movl 0x8(%rsp), %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq