// File: /workspace/github_c_makefile_star2_O2/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, 0x8(%rsp)
movq %rdi, %r15
movslq (%rdx), %r14
movslq 0x4(%rdx), %rbp
movslq 0x18(%rdx), %rdx
movq %rdx, 0x10(%rsp)
movl (%rax), %r13d
movl 0x18(%rax), %edx
movl %edx, 0x4(%rsp)
movslq %r13d, %rbx
movslq 0x4(%rax), %r12
movq 0x38(%rcx), %rdx
movq %rdx, 0x40(%rsp)
movl 0x40(%rcx), %esi
movsbl 0x34(%rcx), %edx
movq %rcx, 0x28(%rsp)
movl 0x1c(%rcx), %ecx
movl 0x40(%rax), %r8d
movsbl 0x34(%rax), %r9d
movq %rax, 0x30(%rsp)
movl 0x1c(%rax), %r10d
subq $0x8, %rsp
leaq 0x3ec7b(%rip), %rdi     # 0x502d8
xorl %eax, %eax
pushq %r10
callq 0x20f0
movq %rbp, %r9
movq %r15, %r8
addq $0x10, %rsp
addq %r14, %r9
imulq $0x70, %r14, %rax
addq %r15, %rax
addq $0x54, %rax
movq %r14, %rcx
cmpq %r9, %rcx
jge 0x11692
orl $-0x1, (%rax)
incq %rcx
addq $0x70, %rax
jmp 0x11681
addq %rbx, %r12
imulq $0x70, %rbx, %rax
movq 0x8(%rsp), %rdi
addq %rdi, %rax
addq $0x54, %rax
movq 0x10(%rsp), %r10
movl 0x4(%rsp), %r11d
cmpq %r12, %rbx
jge 0x116c0
orl $-0x1, (%rax)
incq %rbx
addq $0x70, %rax
jmp 0x116af
leaq 0x18(%rdi), %rax
movq %rax, 0x38(%rsp)
movl $0x0, (%rsp)
movq %r8, 0x20(%rsp)
movq %r9, 0x18(%rsp)
cmpq %r9, %r14
jge 0x11848
imulq $0x70, %r14, %r15
movslq 0x64(%r8,%r15), %rax
subq %r10, %rax
movq 0x40(%rsp), %rcx
movl (%rcx,%rax,4), %eax
testl %eax, %eax
js 0x11840
addq %r8, %r15
addl %r11d, %eax
movslq %r13d, %r13
imulq $0x70, %r13, %rcx
leaq (%rdi,%rcx), %rdx
addq 0x38(%rsp), %rcx
cmpl %eax, 0x64(%rdx)
jge 0x1172c
cmpl %r12d, %r13d
jge 0x1172c
addq $0x70, %rdx
incq %r13
addq $0x70, %rcx
jmp 0x11715
leaq 0x18(%r15), %rbp
pushq $-0x1
popq %rbx
movl %r13d, %edx
cmpl %r12d, %edx
jge 0x1177b
cmpl %eax, 0x4c(%rcx)
jne 0x1177b
cmpl $0x0, 0x3c(%rcx)
jns 0x11768
movb 0x1(%rcx), %sil
cmpb 0x19(%r15), %sil
jne 0x11768
movb (%rcx), %sil
cmpb (%rbp), %sil
jne 0x11763
movb 0x2(%rcx), %sil
cmpb 0x1a(%r15), %sil
je 0x11770
testl %ebx, %ebx
cmovsl %edx, %ebx
incl %edx
addq $0x70, %rcx
jmp 0x11736
movl %edx, 0x54(%r15)
movl %r14d, 0x3c(%rcx)
incl (%rsp)
cmpl $0x0, 0x54(%r15)
jns 0x11840
movq 0x28(%rsp), %rax
movl 0x28(%rax), %esi
movq %rbp, %rdi
callq 0x144a7
movl %eax, 0x48(%r15)
movl %ebx, %ecx
testl %eax, %eax
jne 0x117bb
testl %ebx, %ebx
js 0x117bb
movl %ebx, 0x54(%r15)
imulq $0x70, %rcx, %rax
movq 0x8(%rsp), %rdi
movl %r14d, 0x54(%rdi,%rax)
incl (%rsp)
jmp 0x1182c
testl %ebx, %ebx
cmovsq %r13, %rcx
imulq $0x70, %rcx, %rax
movl 0x64(%r15), %edx
movsbl 0x68(%r15), %ecx
movq 0x28(%rsp), %rsi
movsbl 0x34(%rsi), %r8d
movq 0x8(%rsp), %rsi
leaq 0x18(%rsi,%rax), %r9
movl 0x4c(%r9), %r10d
movsbl 0x50(%r9), %r11d
movq 0x30(%rsp), %rax
movsbl 0x34(%rax), %r15d
subq $0x8, %rsp
leaq 0x3eb19(%rip), %rdi     # 0x50319
movq %rbp, %rsi
xorl %eax, %eax
pushq %r15
pushq %r11
pushq %r10
callq 0x20f0
addq $0x20, %rsp
leaq 0x3eb25(%rip), %rdi     # 0x50340
movl %r13d, %esi
movl %ebx, %edx
xorl %eax, %eax
callq 0x20f0
movq 0x8(%rsp), %rdi
movq 0x20(%rsp), %r8
movq 0x18(%rsp), %r9
movq 0x10(%rsp), %r10
movl 0x4(%rsp), %r11d
incq %r14
jmp 0x116da
movl (%rsp), %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq