// File: /workspace/github_cpp_makefile_star2_O2/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 $0x18728, %rsp          # imm = 0x18728
movq %rsi, %rbx
movq %rdi, %r12
leaq 0x886a(%rip), %rsi      # 0xb0f7
movq %rbx, %rdi
callq 0x2340
testq %rax, %rax
je 0x2cf9
leaq 0x80(%rsp), %rbx
movq %rax, 0x10(%rsp)
movq %rax, %rdi
movq %rbx, %rsi
movl $0x186a0, %edx          # imm = 0x186A0
callq 0x23f0
leaq 0x8831(%rip), %r14      # 0xb0f3
movq %rbx, %rdi
movq %r14, %rsi
callq 0x23b0
pushq $-0x3
popq %rbx
xorl %edi, %edi
movq %r14, %rsi
callq 0x23b0
incl %ebx
testq %rax, %rax
jne 0x28d0
pushq $0x3
popq %rcx
movl %ebx, %eax
cltd
idivl %ecx
testl %edx, %edx
jne 0x2d16
movl %eax, %r13d
movl %eax, 0x24(%r12)
leaq 0x30(%rsp), %rbx
andq $0x0, 0x10(%rbx)
xorpd %xmm0, %xmm0
movapd %xmm0, (%rbx)
leaq 0x80(%rsp), %r14
leaq 0x78(%rsp), %r15
movq 0x10(%rsp), %rdi
movq %r14, %rsi
movl $0x186a0, %edx          # imm = 0x186A0
callq 0x23f0
testq %rax, %rax
je 0x2949
movq %r14, %rdi
callq 0x2440
movq %rax, 0x78(%rsp)
movq %rbx, %rdi
movq %r15, %rsi
callq 0x56f8
jmp 0x2918
movq 0x38(%rsp), %rax
subq 0x30(%rsp), %rax
shrq $0x3, %rax
movl %eax, 0x20(%r12)
movq %rax, 0x20(%rsp)
movslq %eax, %r14
movq %r14, %rdi
callq 0x2030
movq %rax, 0x8(%rsp)
movq %r12, %rbx
movq 0x8(%rsp), %rax
movq %rax, 0x8(%r12)
movq %r14, %rdi
callq 0x2030
movq %rax, (%rsp)
movq (%rsp), %rax
movq %rax, 0x10(%rbx)
leaq (,%r14,8), %r15
testl %r14d, %r14d
pushq $-0x1
popq %rax
cmovsq %rax, %r15
movq %r15, %rdi
callq 0x2030
movq %rax, %rbp
movq %rax, 0x18(%rbx)
movq %r15, %rdi
callq 0x2030
movq %rax, %r12
movq %rbp, 0x68(%rsp)
movq %r15, 0x50(%rsp)
movq %r14, 0x58(%rsp)
leal (%r13,%r13,2), %eax
movslq %eax, %r15
leaq (,%r15,8), %rax
movq %rax, 0x60(%rsp)
xorl %ebp, %ebp
testl %r15d, %r15d
cmovlel %ebp, %r15d
testl %r13d, %r13d
movl $0x0, %r14d
movq %r13, 0x28(%rsp)
cmovgl %r13d, %r14d
movq %rbx, 0x18(%rsp)
movq %r12, (%rbx)
movslq 0x20(%rsp), %rax
movq %rax, 0x70(%rsp)
leaq 0x86dd(%rip), %rbx      # 0xb0f3
cmpl $0x0, 0xe84b(%rip)      # 0x11268
je 0x2b07
cmpq 0x70(%rsp), %rbp
jge 0x2b07
movq 0x30(%rsp), %rax
movq (%rax,%rbp,8), %rdi
movq %rbx, %rsi
callq 0x23b0
movq %rax, %rdi
callq 0x2440
movq 0x68(%rsp), %rcx
movq %rax, (%rcx,%rbp,8)
xorl %edi, %edi
movq %rbx, %rsi
callq 0x23b0
movb (%rax), %al
movq 0x8(%rsp), %rcx
movb %al, (%rcx,%rbp)
xorl %edi, %edi
movq %rbx, %rsi
callq 0x23b0
movb (%rax), %al
movq (%rsp), %rcx
movb %al, (%rcx,%rbp)
movq 0x60(%rsp), %rdi
callq 0x2030
movq %rax, (%r12,%rbp,8)
xorl %r13d, %r13d
cmpq %r13, %r15
je 0x2abc
xorl %edi, %edi
movq %rbx, %rsi
callq 0x23b0
movq %rax, %rdi
callq 0x22a0
movq (%r12,%rbp,8), %rax
movsd %xmm0, (%rax,%r13,8)
xorpd %xmm1, %xmm1
ucomisd %xmm0, %xmm1
ja 0x2c57
incq %r13
jmp 0x2a88
xorl %r13d, %r13d
cmpq %r14, %r13
je 0x2af1
xorpd %xmm0, %xmm0
xorl %ecx, %ecx
cmpq $0x3, %rcx
je 0x2ada
addsd (%rax,%rcx,8), %xmm0
incq %rcx
jmp 0x2aca
ucomisd 0x8546(%rip), %xmm0     # 0xb028
jbe 0x2cb4
incq %r13
addq $0x18, %rax
jmp 0x2abf
movq 0x30(%rsp), %rax
movq (%rax,%rbp,8), %rdi
callq 0x2270
incq %rbp
jmp 0x2a16
movq 0x50(%rsp), %rdi
callq 0x2030
movq %rax, %rbx
movq 0x18(%rsp), %r13
movq 0x58(%rsp), %rax
leaq (,%rax,4), %r15
testl %eax, %eax
movq %rbx, 0x28(%r13)
pushq $-0x1
popq %rax
cmovsq %rax, %r15
movq %r15, %rdi
callq 0x2030
movq %rax, %rbp
movq %rax, 0x30(%r13)
movq %r15, %rdi
callq 0x2030
movq %rbp, 0x8(%rsp)
movq %rax, (%rsp)
movq %rax, 0x38(%r13)
movslq 0x28(%rsp), %r13
xorl %ebp, %ebp
movq 0x20(%rsp), %rax
testl %eax, %eax
movl $0x0, %r15d
cmovgl %eax, %r15d
cmpq %r15, %rbp
je 0x2c29
movq %r13, %rdi
callq 0x2030
movq %rax, (%rbx,%rbp,8)
xorl %eax, %eax
pushq $0x10
popq %rcx
xorl %r8d, %r8d
cmpq %rax, %r14
je 0x2bee
movq (%r12,%rbp,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 0x848a(%rip), %xmm0     # 0xb050
movsd 0xe692(%rip), %xmm1     # 0x11260
ucomisd %xmm0, %xmm1
movq (%rbx,%rbp,8), %rdx
jbe 0x2bde
movb $0x0, (%rdx,%rax)
jmp 0x2be5
movb $0x1, (%rdx,%rax)
incl %r8d
incq %rax
addq $0x18, %rcx
jmp 0x2b8c
movq 0x8(%rsp), %rax
movl %r8d, (%rax,%rbp,4)
movq (%r12,%rbp,8), %rdi
movq (%rbx,%rbp,8), %rcx
movq 0x28(%rsp), %rsi
pushq $0x14
popq %rdx
movsd 0x8409(%rip), %xmm0     # 0xb018
callq 0x26d0
cvtsd2ss %xmm0, %xmm0
movq (%rsp), %rax
movss %xmm0, (%rax,%rbp,4)
incq %rbp
jmp 0x2b6f
movq 0x10(%rsp), %rdi
callq 0x23e0
movq 0x18(%rsp), %rbx
leaq 0x30(%rsp), %rdi
callq 0x56c4
movq %rbx, %rax
addq $0x18728, %rsp          # imm = 0x18728
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0xe37a(%rip), %rbx      # 0x10fd8
movq (%rbx), %rcx
leaq 0x84b3(%rip), %rdi      # 0xb11b
pushq $0x1d
popq %rsi
pushq $0x1
popq %rdx
callq 0x2470
movq (%rbx), %rdi
cvtsi2sd %r13d, %xmm0
divsd 0x839d(%rip), %xmm0     # 0xb020
cvttsd2si %xmm0, %ecx
movl %r13d, %eax
xorl %edx, %edx
pushq $0x3
popq %rsi
divl %esi
imull $-0x3, %eax, %r8d
addl %r13d, %r8d
movq (%r12,%rbp,8), %rax
movsd (%rax,%r13,8), %xmm0
leaq 0x8490(%rip), %rsi      # 0xb139
movl %ebp, %edx
movb $0x1, %al
callq 0x2320
jmp 0x2cf2
movq 0xe31d(%rip), %rbx      # 0x10fd8
movq (%rbx), %rcx
leaq 0x8499(%rip), %rdi      # 0xb15e
pushq $0x38
popq %rsi
pushq $0x1
popq %rdx
movsd %xmm0, 0x10(%rsp)
callq 0x2470
movq (%rbx), %rdi
leaq 0x84b7(%rip), %rsi      # 0xb197
movl %r13d, %edx
movl %ebp, %ecx
movsd 0x10(%rsp), %xmm0
movb $0x1, %al
callq 0x2320
xorl %edi, %edi
callq 0x2280
movq 0xe2d8(%rip), %rax      # 0x10fd8
movq (%rax), %rdi
leaq 0x83ef(%rip), %rsi      # 0xb0f9
movq %rbx, %rdx
xorl %eax, %eax
callq 0x2320
jmp 0x2cf2
addl $0x3, %ebx
movq 0xe2b8(%rip), %rax      # 0x10fd8
movq (%rax), %rdi
leaq 0x83e7(%rip), %rsi      # 0xb111
movl %ebx, %edx
xorl %eax, %eax
callq 0x2320
jmp 0x2cf2
jmp 0x2d3d
jmp 0x2d3d
jmp 0x2d3d
jmp 0x2d3d
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x56c4
movq %rbx, %rdi
callq 0x2410