// File: /workspace/github_cpp_makefile_star2_O3/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18738, %rsp          # imm = 0x18738
movq %rsi, %rbx
movq %rdi, %r15
leaq 0xa21f(%rip), %rsi      # 0xd137
movq %rbx, %rdi
callq 0x2330
testq %rax, %rax
je 0x3392
leaq 0x90(%rsp), %r14
movq %rax, 0x48(%rsp)
movq %rax, %rdi
movq %r14, %rsi
movl $0x186a0, %edx          # imm = 0x186A0
callq 0x23e0
leaq 0xa1e6(%rip), %rbx      # 0xd133
movq %r14, %rdi
movq %rbx, %rsi
callq 0x23a0
xorl %r14d, %r14d
xorl %edi, %edi
movq %rbx, %rsi
callq 0x23a0
incl %r14d
testq %rax, %rax
jne 0x2f5b
imull $0xaaaaaaab, %r14d, %eax # imm = 0xAAAAAAAB
addl $0x2aaaaaa9, %eax       # imm = 0x2AAAAAA9
cmpl $0x55555555, %eax       # imm = 0x55555555
jae 0x339a
movq %r14, 0x18(%rsp)
leal -0x3(%r14), %eax
cltq
imulq $0x55555556, %rax, %rcx # imm = 0x55555556
movq %rcx, %rax
shrq $0x3f, %rax
shrq $0x20, %rcx
addl %eax, %ecx
movq %rcx, 0x10(%rsp)
movl %ecx, 0x24(%r15)
xorpd %xmm0, %xmm0
leaq 0x20(%rsp), %rbx
movapd %xmm0, (%rbx)
movq $0x0, 0x10(%rbx)
leaq 0x90(%rsp), %r14
leaq 0x88(%rsp), %r12
movq 0x48(%rsp), %rdi
movq %r14, %rsi
movl $0x186a0, %edx          # imm = 0x186A0
callq 0x23e0
testq %rax, %rax
je 0x3005
movq %r14, %rdi
callq 0x2430
movq %rax, 0x88(%rsp)
movq %rbx, %rdi
movq %r12, %rsi
callq 0x6044
jmp 0x2fd1
movq 0x28(%rsp), %rax
subq 0x20(%rsp), %rax
shrq $0x3, %rax
movl %eax, 0x20(%r15)
movq %rax, (%rsp)
movslq %eax, %rbx
movq %rbx, %rdi
callq 0x2030
movq %rax, %r12
movq %rax, 0x8(%r15)
movq %rbx, %rdi
callq 0x2030
movq %rax, 0x8(%rsp)
movq 0x8(%rsp), %rax
movq %rax, 0x10(%r15)
leaq (,%rbx,8), %rax
testl %ebx, %ebx
movq $-0x1, %r14
cmovnsq %rax, %r14
movq %r14, %rdi
callq 0x2030
movq %rax, %rbp
movq %rax, 0x18(%r15)
movq %r14, %rdi
callq 0x2030
movq %rax, %r13
movq %rbp, 0x80(%rsp)
movq %r14, 0x50(%rsp)
movq %rbx, 0x58(%rsp)
movq %r15, 0x40(%rsp)
movq %rax, (%r15)
cmpl $0x0, 0x101d5(%rip)     # 0x13268
movq 0x18(%rsp), %r14
je 0x3200
cmpl $0x0, (%rsp)
jle 0x3200
movq 0x10(%rsp), %rcx
leal (%rcx,%rcx,2), %eax
movslq %eax, %r15
leaq (,%r15,8), %rax
movq %rax, 0x78(%rsp)
cmpl $0x2, %r15d
movl $0x1, %eax
cmovll %eax, %r15d
cmpl $0x2, %ecx
cmovgel %ecx, %eax
movq %rax, 0x60(%rsp)
movq (%rsp), %rax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movq %rax, 0x70(%rsp)
xorl %ebx, %ebx
leaq 0xa044(%rip), %rbp      # 0xd133
movq %r12, 0x68(%rsp)
movq 0x20(%rsp), %rax
movq (%rax,%rbx,8), %rdi
movq %rbp, %rsi
callq 0x23a0
movq %rax, %rdi
callq 0x2430
movq 0x80(%rsp), %rcx
movq %rax, (%rcx,%rbx,8)
xorl %edi, %edi
movq %rbp, %rsi
callq 0x23a0
movb (%rax), %al
movb %al, (%r12,%rbx)
xorl %edi, %edi
movq %rbp, %rsi
callq 0x23a0
movb (%rax), %al
movq 0x8(%rsp), %rcx
movb %al, (%rcx,%rbx)
movq 0x78(%rsp), %rdi
callq 0x2030
movq %rax, (%r13,%rbx,8)
cmpl $0x6, %r14d
jb 0x31db
leaq (,%rbx,8), %r12
addq %r13, %r12
xorl %r14d, %r14d
xorl %edi, %edi
movq %rbp, %rsi
callq 0x23a0
movq %rax, %rdi
callq 0x22b0
movq (%r12), %rax
movsd %xmm0, (%rax,%r14,8)
xorpd %xmm1, %xmm1
ucomisd %xmm0, %xmm1
ja 0x337c
incq %r14
cmpq %r14, %r15
jne 0x3164
movq 0x18(%rsp), %r14
cmpl $0x6, %r14d
movq 0x68(%rsp), %r12
movq 0x60(%rsp), %rdx
jb 0x31db
xorl %esi, %esi
xorpd %xmm0, %xmm0
xorl %ecx, %ecx
addsd (%rax,%rcx,8), %xmm0
incq %rcx
cmpq $0x3, %rcx
jne 0x31b3
ucomisd 0x9e57(%rip), %xmm0     # 0xd020
jbe 0x338a
incq %rsi
addq $0x18, %rax
cmpq %rdx, %rsi
jne 0x31ad
movq 0x20(%rsp), %rax
movq (%rax,%rbx,8), %rdi
callq 0x2280
cmpl $0x0, 0x10078(%rip)     # 0x13268
je 0x3200
incq %rbx
cmpq 0x70(%rsp), %rbx
jb 0x30f4
movq 0x50(%rsp), %rdi
callq 0x2030
movq %rax, %rbx
movq 0x40(%rsp), %r14
movq 0x58(%rsp), %rax
shlq $0x2, %rax
cmpl $0x0, (%rsp)
movq %rbx, 0x28(%r14)
movq $-0x1, %r12
cmovnsq %rax, %r12
movq %r12, %rdi
callq 0x2030
movq %rax, %r15
movq %rax, 0x30(%r14)
movq %r12, %rdi
callq 0x2030
movq %rax, %r12
movq %r15, 0x8(%rsp)
movq %rax, 0x38(%r14)
cmpl $0x0, (%rsp)
jle 0x3344
movq 0x10(%rsp), %rax
movslq %eax, %rbp
cmpl $0x2, %eax
movl $0x1, %r15d
cmovgel %eax, %r15d
movq (%rsp), %rax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movq %rax, (%rsp)
xorl %r14d, %r14d
movq %rbp, %rdi
callq 0x2030
xorl %r8d, %r8d
movq %rax, (%rbx,%r14,8)
cmpl $0x6, 0x18(%rsp)
jb 0x3305
xorl %eax, %eax
movl $0x10, %ecx
xorl %r8d, %r8d
movq (%r13,%r14,8), %rdx
movsd (%rdx,%rcx), %xmm0
movsd -0x10(%rdx,%rcx), %xmm1
movsd -0x8(%rdx,%rcx), %xmm2
movapd %xmm0, %xmm3
minsd %xmm2, %xmm3
minsd %xmm1, %xmm3
maxsd %xmm2, %xmm0
maxsd %xmm1, %xmm0
subsd %xmm3, %xmm0
andpd 0x9d7a(%rip), %xmm0     # 0xd050
movsd 0xff82(%rip), %xmm1     # 0x13260
ucomisd %xmm0, %xmm1
movq (%rbx,%r14,8), %rdx
jbe 0x32ee
movb $0x0, (%rdx,%rax)
jmp 0x32f5
movb $0x1, (%rdx,%rax)
incl %r8d
incq %rax
addq $0x18, %rcx
cmpq %rax, %r15
jne 0x32a0
movq (%rbx,%r14,8), %rax
movq 0x8(%rsp), %rcx
movl %r8d, (%rcx,%r14,4)
movq (%r13,%r14,8), %rdi
movq 0x10(%rsp), %rsi
movl $0x14, %edx
movsd 0x9cf3(%rip), %xmm0     # 0xd018
movq %rax, %rcx
callq 0x2daa
cvtsd2ss %xmm0, %xmm0
movss %xmm0, (%r12,%r14,4)
incq %r14
cmpq (%rsp), %r14
jne 0x3280
movq 0x48(%rsp), %rdi
callq 0x23d0
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x3365
movq 0x30(%rsp), %rsi
subq %rdi, %rsi
callq 0x2230
movq 0x40(%rsp), %rax
addq $0x18738, %rsp          # imm = 0x18738
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rbx, %rdi
movq %r14, %rsi
movq %r12, %rdx
callq 0x28ef
movq %rbx, %rdi
callq 0x289b
movq %rbx, %rdi
callq 0x295f
movl %r14d, %edi
callq 0x2879
jmp 0x33aa
jmp 0x33aa
jmp 0x33aa
jmp 0x33aa
movq %rax, %rbx
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x33c4
movq 0x30(%rsp), %rsi
subq %rdi, %rsi
callq 0x2230
movq %rbx, %rdi
callq 0x2400