// File: /workspace/github_c_makefile_star2_O0/ToniWestbrook[P]paladin/protein.c
// Function: writeReadsProtein
int writeReadsProtein(const char * passPrefix, const char * passProName, mem_opt_t * passOptions) {
	CDS * orfList;
	gzFile inputSeqPtr;
	FILE * outputProPtr, * outputNTPtr;
	char * outputProBuffer, * outputNTName;
	kseq_t * seq;
	unsigned long seqIdx, transIdx, transTable, outputSize, orfCount, orfTotal, orfIdx;

	// Check for incompatible combinations
	if ((passOptions->proteinFlag & ALIGN_FLAG_BRUTE_ORF) && passOptions->indexInfo.multiFrame) {
		logMessage(__func__, LOG_LEVEL_WARNING, "Brute force ORF detection redundant to MF index, disabling...\n");
		passOptions->flag &= ~ALIGN_FLAG_BRUTE_ORF;
	}

	// Prepare file handles
	inputSeqPtr = xzopen(passPrefix, "r");
	outputProPtr = err_xopen_core(__func__, passProName, "w");
	outputNTPtr = 0;

	if (passOptions->proteinFlag & ALIGN_FLAG_GEN_NT) {
		outputNTName = malloc(strlen(passPrefix) + 5);
		sprintf(outputNTName, "%s.orf", passPrefix);
		outputNTPtr = err_xopen_core(__func__, outputNTName, "w");
		free(outputNTName);
	}

	logMessage(__func__, LOG_LEVEL_MESSAGE, "Detecting open reading frames...\n");

	// Iterate through each read
	orfTotal = 0;
	seqIdx = 0;
	seq = kseq_init(inputSeqPtr);

	while(kseq_read(seq) >= 0) {
        transIdx = 0;

        while((passOptions->translations)[transIdx++] != 0) {
            // Lookup current translation table
            transTable = (passOptions->translations)[transIdx - 1] - 1;

            // Search for ORFs
            getSequenceORF(seq->seq.s, seq->seq.l, transTable, passOptions, &orfList, &orfCount);

            // Write out the corresponding protein sequence for each ORF
            for (orfIdx = 0 ; orfIdx < orfCount ; orfIdx++) {
                convertToAA(seq->seq.s, orfList+orfIdx, transTable, &outputProBuffer, &outputSize);

                // Sequence ID : ORF Index per Sequence : Relative Frame per Sequence : Sequence Header
                fprintf(outputProPtr, ">%lu:%lu:%lu:%s\n%.*s\n", 
                        seqIdx, orfIdx, transTable * 6 + orfList[orfIdx].relFrame, seq->name.s, (int) outputSize, outputProBuffer);
                free(outputProBuffer);

                if (passOptions->proteinFlag & ALIGN_FLAG_GEN_NT) {
                    // Sequence ID : ORF Index per Sequence : Relative Frame per Sequence : Sequence Header
                    fprintf(outputNTPtr, ">%lu:%lu:%lu:%s\n%.*s\n", 
                            seqIdx, orfIdx, transTable * 6 + orfList[orfIdx].relFrame, seq->name.s, (int) (orfList[orfIdx].endIdx - orfList[orfIdx].startIdx + 1), seq->seq.s + orfList[orfIdx].startIdx);

                }
            }

            free(orfList);
            orfTotal += orfCount;
        }
        seqIdx++;
	}

	// Close files
	fflush(outputProPtr);
	err_gzclose(inputSeqPtr);
	err_fclose(outputProPtr);
	kseq_destroy(seq);

	if (passOptions->proteinFlag & ALIGN_FLAG_GEN_NT) {
		fflush(outputNTPtr);
		err_fclose(outputNTPtr);
	}

	if (passOptions->proteinFlag & ALIGN_FLAG_BRUTE_ORF) orfTotal /= 6;
	logMessage(__func__, LOG_LEVEL_MESSAGE, "Detected and translated %d open reading frames in %d sequences\n", orfTotal, seqIdx);

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x18(%rbp), %rax
movl 0x4c(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0xba27
movq -0x18(%rbp), %rax
cmpl $0x0, 0x54(%rax)
je 0xba27
leaq 0x2d674(%rip), %rdi     # 0x3907b
movl $0x2, %esi
leaq 0x2d67a(%rip), %rdx     # 0x3908d
movb $0x0, %al
callq 0x12510
movq -0x18(%rbp), %rax
movl 0x48(%rax), %ecx
andl $-0x2, %ecx
movl %ecx, 0x48(%rax)
movq -0x8(%rbp), %rsi
leaq 0x2d649(%rip), %rdi     # 0x3907b
leaq 0x2d2c9(%rip), %rdx     # 0x38d02
callq 0x12990
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rsi
leaq 0x2d62e(%rip), %rdi     # 0x3907b
leaq 0x2f8c4(%rip), %rdx     # 0x3b318
callq 0x12740
movq %rax, -0x30(%rbp)
movq $0x0, -0x38(%rbp)
movq -0x18(%rbp), %rax
movl 0x4c(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0xbada
movq -0x8(%rbp), %rdi
callq 0x30f0
movq %rax, %rdi
addq $0x5, %rdi
leaq 0x2d52f(%rip), %rsi     # 0x38fba
movl $0x224, %edx            # imm = 0x224
leaq 0x2d5e4(%rip), %rcx     # 0x3907b
callq 0x31ca0
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
movq -0x8(%rbp), %rdx
leaq 0x2d61d(%rip), %rsi     # 0x390cc
movb $0x0, %al
callq 0x3070
movq -0x48(%rbp), %rsi
leaq 0x2d5ba(%rip), %rdi     # 0x3907b
leaq 0x2f850(%rip), %rdx     # 0x3b318
callq 0x12740
movq %rax, -0x38(%rbp)
movq -0x48(%rbp), %rdi
callq 0x3380
leaq 0x2d59a(%rip), %rdi     # 0x3907b
movl $0x3, %esi
leaq 0x2d5e6(%rip), %rdx     # 0x390d3
movb $0x0, %al
callq 0x12510
movq $0x0, -0x80(%rbp)
movq $0x0, -0x58(%rbp)
movq -0x28(%rbp), %rdi
callq 0x11a10
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
callq 0x11b70
cmpl $0x0, %eax
jl 0xbd2c
movq $0x0, -0x60(%rbp)
movq -0x18(%rbp), %rax
movq 0x70(%rax), %rax
movq -0x60(%rbp), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, -0x60(%rbp)
cmpl $0x0, (%rax,%rcx,4)
je 0xbd1b
movq -0x18(%rbp), %rax
movq 0x70(%rax), %rax
movq -0x60(%rbp), %rcx
subq $0x1, %rcx
movl (%rax,%rcx,4), %eax
subl $0x1, %eax
cltq
movq %rax, -0x68(%rbp)
movq -0x50(%rbp), %rax
movq 0x40(%rax), %rdi
movq -0x50(%rbp), %rax
movq 0x30(%rax), %rsi
movq -0x68(%rbp), %rax
movl %eax, %edx
movq -0x18(%rbp), %rcx
leaq -0x20(%rbp), %r8
leaq -0x78(%rbp), %r9
callq 0xab70
movq $0x0, -0x88(%rbp)
movq -0x88(%rbp), %rax
cmpq -0x78(%rbp), %rax
jae 0xbd01
movq -0x50(%rbp), %rax
movq 0x40(%rax), %rdi
movq -0x20(%rbp), %rsi
imulq $0x2018, -0x88(%rbp), %rax # imm = 0x2018
addq %rax, %rsi
movq -0x68(%rbp), %rax
movl %eax, %edx
leaq -0x40(%rbp), %rcx
leaq -0x70(%rbp), %r8
callq 0xa4f0
movq -0x30(%rbp), %rdi
movq -0x58(%rbp), %rdx
movq -0x88(%rbp), %rcx
imulq $0x6, -0x68(%rbp), %r8
movq -0x20(%rbp), %rax
imulq $0x2018, -0x88(%rbp), %rsi # imm = 0x2018
addq %rsi, %rax
movswq 0x14(%rax), %rax
addq %rax, %r8
movq -0x50(%rbp), %rax
movq 0x10(%rax), %r9
movq -0x70(%rbp), %rax
movl %eax, %r10d
movq -0x40(%rbp), %rax
leaq 0x2d4d5(%rip), %rsi     # 0x390f5
movl %r10d, (%rsp)
movq %rax, 0x8(%rsp)
movb $0x0, %al
callq 0x34e0
movq -0x40(%rbp), %rdi
callq 0x3380
movq -0x18(%rbp), %rax
movl 0x4c(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0xbce8
movq -0x38(%rbp), %rdi
movq -0x58(%rbp), %rdx
movq -0x88(%rbp), %rcx
imulq $0x6, -0x68(%rbp), %r8
movq -0x20(%rbp), %rax
imulq $0x2018, -0x88(%rbp), %rsi # imm = 0x2018
addq %rsi, %rax
movswq 0x14(%rax), %rax
addq %rax, %r8
movq -0x50(%rbp), %rax
movq 0x10(%rax), %r9
movq -0x20(%rbp), %rax
imulq $0x2018, -0x88(%rbp), %rsi # imm = 0x2018
addq %rsi, %rax
movq 0x8(%rax), %rax
movq -0x20(%rbp), %rsi
imulq $0x2018, -0x88(%rbp), %r10 # imm = 0x2018
addq %r10, %rsi
subq (%rsi), %rax
addq $0x1, %rax
movl %eax, %r10d
movq -0x50(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x20(%rbp), %rsi
imulq $0x2018, -0x88(%rbp), %r11 # imm = 0x2018
addq %r11, %rsi
addq (%rsi), %rax
leaq 0x2d41d(%rip), %rsi     # 0x390f5
movl %r10d, (%rsp)
movq %rax, 0x8(%rsp)
movb $0x0, %al
callq 0x34e0
jmp 0xbcea
movq -0x88(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
jmp 0xbb9a
movq -0x20(%rbp), %rdi
callq 0x3380
movq -0x78(%rbp), %rax
addq -0x80(%rbp), %rax
movq %rax, -0x80(%rbp)
jmp 0xbb2b
movq -0x58(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
jmp 0xbb11
movq -0x30(%rbp), %rdi
callq 0x3360
movq -0x28(%rbp), %rdi
callq 0x13200
movq -0x30(%rbp), %rdi
callq 0x131b0
movq -0x50(%rbp), %rdi
callq 0x11ad0
movq -0x18(%rbp), %rax
movl 0x4c(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0xbd71
movq -0x38(%rbp), %rdi
callq 0x3360
movq -0x38(%rbp), %rdi
callq 0x131b0
movq -0x18(%rbp), %rax
movl 0x4c(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0xbd92
movq -0x80(%rbp), %rax
movl $0x6, %ecx
xorl %edx, %edx
divq %rcx
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rcx
movq -0x58(%rbp), %r8
leaq 0x2d2da(%rip), %rdi     # 0x3907b
movl $0x3, %esi
leaq 0x2d35e(%rip), %rdx     # 0x3910b
movb $0x0, %al
callq 0x12510
xorl %eax, %eax
addq $0xa0, %rsp
popq %rbp
retq
nop