// File: GenisGE[P]evalAdmix/Cinterface.cpp
// Function: readBeagle(char const*)
bgl readBeagle(const char* fname) {
  const char *delims = "\t \n";
  gzFile fp = NULL;
  if(Z_NULL==(fp=gzopen(fname,"r"))){
    fprintf(stderr,"Error opening file: %s\n",fname);
    exit(0);
  }
  
  bgl ret;
  char buf[LENS];

  //find number of columns
  gzgets(fp,buf,LENS);
  strtok(buf,delims);
  int ncols=1;
  while(strtok(NULL,delims))
    ncols++;
  if(0!=(ncols-3) %3 ){
    fprintf(stderr,"ncols=%d\n",ncols);
    exit(0);
  }
  ret.nInd = (ncols-3)/3;//this is the number of samples
  
  //read every line into a vector
  std::vector<char*> tmp;
  while(gzgets(fp,buf,LENS))
    tmp.push_back(strdup(buf));
  
  //now we now the number of sites
  ret.nSites=tmp.size();
  ret.major= new char[ret.nSites];
  
  ret.minor= new char[ret.nSites];
  ret.ids = new char*[ret.nSites];
  ret.genos= new double*[ret.nSites];

  //then loop over the vector and parsing every line
  
    
  for(int s=0;SIG_COND&& (s<ret.nSites);s++){
    ret.ids[s] = strdup(strtok(tmp[s],delims));
    ret.major[s] =strtok(NULL,delims)[0];
    ret.minor[s] =strtok(NULL,delims)[0];
    ret.genos[s]= new double[3*ret.nInd];
    for(int i=0;i<ret.nInd*3;i++){
      ret.genos[s][i] = atof(strtok(NULL,delims));
      if(ret.genos[s][i]<0){
	fprintf(stderr,"Likelihoods must be positive\n");
	fprintf(stderr,"site %d ind %d geno %d has value %f\n",s,int(i*1.0/3),i%3,ret.genos[s][i]);
	exit(0);
      }
    }
    for(int i=0;i<ret.nInd;i++){
      double tmpS = 0.0;
      for(int g=0;g<3;g++)
	tmpS += ret.genos[s][i*3+g];
      if(!(tmpS>0)){
	fprintf(stderr,"The sum of likelihoods for a genotypes must be positive\n");
	fprintf(stderr,"individual %d site %d has sum %f\n",i,s,tmpS);
	exit(0);
      } 
    }
    free(tmp[s]);
  }
  
  // Here additional stuff is calculated from the likelihoods
  // this must be done again while filtering later in main
  ret.keeps=new char*[ret.nSites]; // array nSites x nInd 0 if missing info
  ret.keepInd = new int[ret.nSites];
  ret.mafs = new float[ret.nSites];

  for(int s=0;s<ret.nSites;s++){
    ret.keeps[s] = new char[ret.nInd];
    int nKeep =0;
    for(int i=0;i<ret.nInd;i++){
      double mmin=std::min(ret.genos[s][i*3],std::min(ret.genos[s][i*3+1],ret.genos[s][i*3+2]));
      double mmax=std::max(ret.genos[s][i*3],std::max(ret.genos[s][i*3+1],ret.genos[s][i*3+2]));
      if(fabs(mmax-mmin)<misTol)
	ret.keeps[s][i] =0;
      else{
	ret.keeps[s][i] =1;
	nKeep++;
      }
    }
    ret.keepInd[s] = nKeep;
    ret.mafs[s] = emFrequency(ret.genos[s],ret.nInd,MAF_ITER,MAF_START,ret.keeps[s],ret.keepInd[s]);
  }
  //  keeps=ret.keeps;
  gzclose(fp); //clean up filepointer
  return ret;
}

// Assembly:
subq $0x187d8, %rsp          # imm = 0x187D8
movq %rdi, 0xa0(%rsp)
movq %rdi, 0xa8(%rsp)
movq %rsi, 0x187d0(%rsp)
leaq 0x14300(%rip), %rax     # 0x180f6
movq %rax, 0x187c8(%rsp)
movq $0x0, 0x187c0(%rsp)
movq 0x187d0(%rsp), %rdi
leaq 0x142e1(%rip), %rsi     # 0x180fa
callq 0x33f0
movq %rax, %rcx
movq %rcx, 0x187c0(%rsp)
xorl %eax, %eax
cmpq %rcx, %rax
jne 0x3e57
movq 0x1b1a1(%rip), %rax     # 0x1efd8
movq (%rax), %rdi
movq 0x187d0(%rsp), %rdx
leaq 0x142b3(%rip), %rsi     # 0x180fc
movb $0x0, %al
callq 0x33c0
xorl %edi, %edi
callq 0x3340
movq 0x187c0(%rsp), %rdi
leaq 0x120(%rsp), %rsi
movl $0x186a0, %edx          # imm = 0x186A0
callq 0x34d0
leaq 0x120(%rsp), %rdi
movq 0x187c8(%rsp), %rsi
callq 0x3470
movl $0x1, 0x11c(%rsp)
movq 0x187c8(%rsp), %rsi
xorl %eax, %eax
movl %eax, %edi
callq 0x3470
cmpq $0x0, %rax
je 0x3ebb
movl 0x11c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x11c(%rsp)
jmp 0x3e91
movl 0x11c(%rsp), %eax
subl $0x3, %eax
movl $0x3, %ecx
cltd
idivl %ecx
xorl %eax, %eax
cmpl %edx, %eax
je 0x3ef9
movq 0x1b0fe(%rip), %rax     # 0x1efd8
movq (%rax), %rdi
movl 0x11c(%rsp), %edx
leaq 0x14229(%rip), %rsi     # 0x18114
movb $0x0, %al
callq 0x33c0
xorl %edi, %edi
callq 0x3340
movl 0x11c(%rsp), %eax
subl $0x3, %eax
movl $0x3, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq 0xa0(%rsp), %rax
movl %ecx, 0x24(%rax)
leaq 0x100(%rsp), %rdi
callq 0x9120
movq 0x187c0(%rsp), %rdi
leaq 0x120(%rsp), %rsi
movl $0x186a0, %edx          # imm = 0x186A0
callq 0x34d0
movq %rax, 0x98(%rsp)
jmp 0x3f49
movq 0x98(%rsp), %rax
cmpq $0x0, %rax
je 0x3fab
leaq 0x120(%rsp), %rdi
callq 0x3530
movq %rax, 0xe8(%rsp)
leaq 0x100(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x9130
jmp 0x3f83
jmp 0x3f25
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
leaq 0x100(%rsp), %rdi
callq 0x9220
jmp 0x47a4
leaq 0x100(%rsp), %rdi
callq 0x9160
movq %rax, %rcx
movq 0xa0(%rsp), %rax
movl %ecx, 0x20(%rax)
movslq 0x20(%rax), %rdi
callq 0x3030
movq %rax, 0x90(%rsp)
jmp 0x3fd9
movq 0xa0(%rsp), %rax
movq 0x90(%rsp), %rcx
movq %rcx, 0x8(%rax)
movslq 0x20(%rax), %rdi
callq 0x3030
movq %rax, 0x88(%rsp)
jmp 0x4000
movq 0xa0(%rsp), %rax
movq 0x88(%rsp), %rcx
movq %rcx, 0x10(%rax)
movslq 0x20(%rax), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x3030
movq %rax, 0x80(%rsp)
jmp 0x403d
movq 0xa0(%rsp), %rax
movq 0x80(%rsp), %rcx
movq %rcx, 0x18(%rax)
movslq 0x20(%rax), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x3030
movq %rax, 0x78(%rsp)
jmp 0x4077
movq 0xa0(%rsp), %rax
movq 0x78(%rsp), %rcx
movq %rcx, (%rax)
movl $0x0, 0xe4(%rsp)
xorl %eax, %eax
cmpl $0x0, 0x1b245(%rip)     # 0x1f2e0
movb %al, 0x77(%rsp)
je 0x40ba
movq 0xa0(%rsp), %rcx
movl 0xe4(%rsp), %eax
cmpl 0x20(%rcx), %eax
setl %al
movb %al, 0x77(%rsp)
movb 0x77(%rsp), %al
testb $0x1, %al
jne 0x40c7
jmp 0x443c
movslq 0xe4(%rsp), %rsi
leaq 0x100(%rsp), %rdi
callq 0x9180
movq (%rax), %rdi
movq 0x187c8(%rsp), %rsi
callq 0x3470
movq %rax, %rdi
callq 0x3530
movq %rax, %rdx
movq 0xa0(%rsp), %rax
movq 0x18(%rax), %rax
movslq 0xe4(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movq 0x187c8(%rsp), %rsi
xorl %eax, %eax
movl %eax, %edi
movq %rdi, 0x60(%rsp)
callq 0x3470
movq 0x60(%rsp), %rdi
movq %rax, %rcx
movq 0xa0(%rsp), %rax
movb (%rcx), %dl
movq 0x8(%rax), %rax
movslq 0xe4(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x187c8(%rsp), %rsi
callq 0x3470
movq %rax, %rcx
movq 0xa0(%rsp), %rax
movb (%rcx), %sil
movq 0x10(%rax), %rcx
movslq 0xe4(%rsp), %rdx
movb %sil, (%rcx,%rdx)
movl 0x24(%rax), %ecx
movl %ecx, %eax
leal (%rax,%rax,2), %eax
cltq
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x3030
movq %rax, 0x68(%rsp)
jmp 0x419d
movq 0x68(%rsp), %rdx
movq 0xa0(%rsp), %rax
movq (%rax), %rax
movslq 0xe4(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movl $0x0, 0xe0(%rsp)
movq 0xa0(%rsp), %rcx
movl 0xe0(%rsp), %eax
imull $0x3, 0x24(%rcx), %ecx
cmpl %ecx, %eax
jge 0x42fa
movq 0x187c8(%rsp), %rsi
xorl %eax, %eax
movl %eax, %edi
callq 0x3470
movq %rax, %rdi
callq 0x3370
movq 0xa0(%rsp), %rax
movq (%rax), %rcx
movslq 0xe4(%rsp), %rdx
movq (%rcx,%rdx,8), %rcx
movslq 0xe0(%rsp), %rdx
movsd %xmm0, (%rcx,%rdx,8)
movq (%rax), %rax
movslq 0xe4(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movslq 0xe0(%rsp), %rcx
xorps %xmm0, %xmm0
ucomisd (%rax,%rcx,8), %xmm0
jbe 0x42e2
movq 0x1ad90(%rip), %rax     # 0x1efd8
movq (%rax), %rdi
leaq 0x13ecc(%rip), %rsi     # 0x1811e
movb $0x0, %al
callq 0x33c0
movq 0x1ad78(%rip), %rax     # 0x1efd8
movq (%rax), %rdi
movl 0xe4(%rsp), %eax
movl %eax, 0x5c(%rsp)
cvtsi2sdl 0xe0(%rsp), %xmm0
movsd 0x13d89(%rip), %xmm1    # 0x18008
mulsd %xmm1, %xmm0
movsd 0x13d9d(%rip), %xmm1    # 0x18028
divsd %xmm1, %xmm0
cvttsd2si %xmm0, %ecx
movl 0xe0(%rsp), %eax
movl $0x3, %esi
cltd
idivl %esi
movq 0xa0(%rsp), %rax
movl %edx, %r8d
movl 0x5c(%rsp), %edx
movq (%rax), %rax
movslq 0xe4(%rsp), %rsi
movq (%rax,%rsi,8), %rax
movslq 0xe0(%rsp), %rsi
movsd (%rax,%rsi,8), %xmm0
leaq 0x13e68(%rip), %rsi     # 0x1813c
movb $0x1, %al
callq 0x33c0
xorl %edi, %edi
callq 0x3340
jmp 0x42e4
movl 0xe0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe0(%rsp)
jmp 0x41c4
movl $0x0, 0xdc(%rsp)
movq 0xa0(%rsp), %rcx
movl 0xdc(%rsp), %eax
cmpl 0x24(%rcx), %eax
jge 0x4409
xorps %xmm0, %xmm0
movsd %xmm0, 0xd0(%rsp)
movl $0x0, 0xcc(%rsp)
cmpl $0x3, 0xcc(%rsp)
jge 0x4391
movq 0xa0(%rsp), %rax
movq (%rax), %rax
movslq 0xe4(%rsp), %rcx
movq (%rax,%rcx,8), %rax
imull $0x3, 0xdc(%rsp), %ecx
addl 0xcc(%rsp), %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
addsd 0xd0(%rsp), %xmm0
movsd %xmm0, 0xd0(%rsp)
movl 0xcc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xcc(%rsp)
jmp 0x4334
movsd 0xd0(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
ja 0x43f1
movq 0x1ac2e(%rip), %rax     # 0x1efd8
movq (%rax), %rdi
leaq 0x13dad(%rip), %rsi     # 0x18161
movb $0x0, %al
callq 0x33c0
movq 0x1ac16(%rip), %rax     # 0x1efd8
movq (%rax), %rdi
movl 0xdc(%rsp), %edx
movl 0xe4(%rsp), %ecx
movsd 0xd0(%rsp), %xmm0
leaq 0x13db7(%rip), %rsi     # 0x1819a
movb $0x1, %al
callq 0x33c0
xorl %edi, %edi
callq 0x3340
jmp 0x43f3
movl 0xdc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xdc(%rsp)
jmp 0x4305
movslq 0xe4(%rsp), %rsi
leaq 0x100(%rsp), %rdi
callq 0x9180
movq (%rax), %rdi
callq 0x3330
movl 0xe4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe4(%rsp)
jmp 0x4092
movq 0xa0(%rsp), %rax
movslq 0x20(%rax), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x3030
movq %rax, 0x50(%rsp)
jmp 0x446a
movq 0xa0(%rsp), %rax
movq 0x50(%rsp), %rcx
movq %rcx, 0x28(%rax)
movslq 0x20(%rax), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x3030
movq %rax, 0x48(%rsp)
jmp 0x44a1
movq 0xa0(%rsp), %rax
movq 0x48(%rsp), %rcx
movq %rcx, 0x30(%rax)
movslq 0x20(%rax), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x3030
movq %rax, 0x40(%rsp)
jmp 0x44d8
movq 0xa0(%rsp), %rax
movq 0x40(%rsp), %rcx
movq %rcx, 0x38(%rax)
movl $0x0, 0xc8(%rsp)
movq 0xa0(%rsp), %rcx
movl 0xc8(%rsp), %eax
cmpl 0x20(%rcx), %eax
jge 0x4778
movq 0xa0(%rsp), %rax
movslq 0x24(%rax), %rdi
callq 0x3030
movq %rax, 0x38(%rsp)
jmp 0x4524
movq 0x38(%rsp), %rdx
movq 0xa0(%rsp), %rax
movq 0x28(%rax), %rax
movslq 0xc8(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movl $0x0, 0xc4(%rsp)
movl $0x0, 0xc0(%rsp)
movq 0xa0(%rsp), %rcx
movl 0xc0(%rsp), %eax
cmpl 0x24(%rcx), %eax
jge 0x46e7
movq 0xa0(%rsp), %rax
movq (%rax), %rax
movslq 0xc8(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movl 0xc0(%rsp), %edx
movl %edx, %ecx
leal (%rcx,%rcx,2), %ecx
movslq %ecx, %rcx
leaq (%rax,%rcx,8), %rdx
movq %rdx, 0x28(%rsp)
leaq 0x8(%rax,%rcx,8), %rdi
leaq 0x10(%rax,%rcx,8), %rsi
callq 0x91a0
movq %rax, 0x30(%rsp)
jmp 0x45b4
movq 0x30(%rsp), %rsi
movq 0x28(%rsp), %rdi
callq 0x91a0
movq %rax, 0x20(%rsp)
jmp 0x45ca
movq 0xa0(%rsp), %rax
movq 0x20(%rsp), %rcx
movsd (%rcx), %xmm0
movsd %xmm0, 0xb8(%rsp)
movq (%rax), %rax
movslq 0xc8(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movl 0xc0(%rsp), %edx
movl %edx, %ecx
leal (%rcx,%rcx,2), %ecx
movslq %ecx, %rcx
leaq (%rax,%rcx,8), %rdx
movq %rdx, 0x10(%rsp)
leaq 0x8(%rax,%rcx,8), %rdi
leaq 0x10(%rax,%rcx,8), %rsi
callq 0x91e0
movq %rax, 0x18(%rsp)
jmp 0x4621
movq 0x18(%rsp), %rsi
movq 0x10(%rsp), %rdi
callq 0x91e0
movq %rax, 0x8(%rsp)
jmp 0x4637
movq 0x8(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0xb0(%rsp)
movsd 0xb0(%rsp), %xmm1
subsd 0xb8(%rsp), %xmm1
movaps 0x139fe(%rip), %xmm0    # 0x18060
pand %xmm0, %xmm1
movsd 0x1ac6a(%rip), %xmm0    # 0x1f2d8
ucomisd %xmm1, %xmm0
jbe 0x469a
movq 0xa0(%rsp), %rax
movq 0x28(%rax), %rax
movslq 0xc8(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movslq 0xc0(%rsp), %rcx
movb $0x0, (%rax,%rcx)
jmp 0x46cf
movq 0xa0(%rsp), %rax
movq 0x28(%rax), %rax
movslq 0xc8(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movslq 0xc0(%rsp), %rcx
movb $0x1, (%rax,%rcx)
movl 0xc4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc4(%rsp)
jmp 0x46d1
movl 0xc0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc0(%rsp)
jmp 0x4557
movq 0xa0(%rsp), %rax
movl 0xc4(%rsp), %esi
movq 0x30(%rax), %rcx
movslq 0xc8(%rsp), %rdx
movl %esi, (%rcx,%rdx,4)
movq (%rax), %rcx
movslq 0xc8(%rsp), %rdx
movq (%rcx,%rdx,8), %rdi
movl 0x24(%rax), %esi
movq 0x28(%rax), %rcx
movq (%rcx,%rdx,8), %rcx
movq 0x30(%rax), %rax
movl (%rax,%rdx,4), %r8d
movl $0x14, %edx
movsd 0x138ec(%rip), %xmm0    # 0x18020
callq 0x3870
movsd %xmm0, (%rsp)
jmp 0x4740
movq 0xa0(%rsp), %rax
movsd (%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x38(%rax), %rax
movslq 0xc8(%rsp), %rcx
movss %xmm0, (%rax,%rcx,4)
movl 0xc8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc8(%rsp)
jmp 0x44f4
movq 0x187c0(%rsp), %rdi
callq 0x34c0
jmp 0x4787
leaq 0x100(%rsp), %rdi
callq 0x9220
movq 0xa8(%rsp), %rax
addq $0x187d8, %rsp          # imm = 0x187D8
retq
movq 0xf8(%rsp), %rdi
callq 0x34f0
nopw %cs:(%rax,%rax)