// File: gchen98[P]macs/algorithm.cpp
// Function: GraphBuilder::build()
void GraphBuilder::build(){
    double curPos = 0.0,lastPos = 0.0,dMaxPos = 1.0;
    unsigned int iLastCumulativePos = 0;
    cerr<<"Debugging: "<<pConfig->bDebug<<endl;

    HotSpotBinPtrList::iterator hotSpotIt;
    if (pConfig->bVariableRecomb){
      hotSpotIt=pConfig->pHotSpotBinPtrList->begin();
    }
    // gene conversion stuff
    GeneConversionPtr newGC;
    double dLogTractRatio = log((pConfig->iGeneConvTract-1.)/pConfig->iGeneConvTract);
    const int XOVER=0,GCSTART=1,GCEND=2;
    int xovers=0,gcstarts=0,gcends=0;
    int lastRE;
    int iHistoryMax = 0;
    do{
        if (iGraphIteration==0){
            cerr<<endl<<"Graph Builder begin"<<endl;
            NodePtr dummy1;
            EventPtr dummy2;
            double current=clock();
            this->traverseEvents(false,dummy1,dummy2);
            cerr<<"Time for build prior tree: "<<(clock()-current)<<" seconds\n";
        }else{
            // at this point decide whether we invoke a plain x-over
            // or a new gene conversion event
            this->bBeginGeneConversion = false;
            lastRE=XOVER;
            if (this->bEndGeneConversion){
              lastRE=GCEND;
            }else{
              this->bBeginGeneConversion = pRandNumGenerator->unifRV()<
              (pConfig->dGeneConvRatio/(pConfig->dGeneConvRatio+1))?true:false;
              if (bBeginGeneConversion){
                lastRE=GCSTART;
                double dTractLen = (1.+log(pRandNumGenerator->unifRV())/
                dLogTractRatio)/pConfig->dSeqLength;
                if (pConfig->bDebug) cerr<<"Proposing tract length: "
                <<dTractLen<<endl;
                    newGC = GeneConversionPtr(new GeneConversion(
                    curPos+dTractLen));
                    pGeneConversionPtrSet->insert(newGC);
              }
            }
            invokeRecombination(newGC);
            switch(lastRE){
            case XOVER:
              ++xovers;
              break;
            case GCSTART:
              ++gcstarts;
              break;
            case GCEND:
              ++gcends;
              break;
            }
            // mark the graph edges as the local tree
            markCurrentTree();
            if (!bIncrementHistory){
                double dBoundary = curPos - dTrailingGap;
                if (dBoundary>0.){
                  bIncrementHistory = true;
                }
            }else{
                ++iHistoryMax;
            }
            cerr<<"iHistoryMax: "<<iHistoryMax<<endl;
            if (iHistoryMax>=0){
                pruneARG(iHistoryMax);
            }
        }

        initializeCurrentTree();

        cerr<<"Tree:"<<iGraphIteration<<
        ",pos:"<<curPos<<
        ",len:"<<dLastTreeLength<<
        ",TMRCA:"<<localMRCA->getHeight()<<
        ",ARG:"<<
        ",len:"<<dArgLength<<
        ",TMRCA:"<<grandMRCA->getHeight()<<
        endl;
        if (pConfig->bVariableRecomb){
            bool bBinCrossed;
            do{
                bBinCrossed = getNextPos(curPos,hotSpotIt);
            }while(bBinCrossed);
        }else{
            curPos+=pRandNumGenerator->expRV(getRate());
        }
        // check if we reached the end of the region
        if (curPos>dMaxPos) curPos=dMaxPos;
        // check if there was an existing gene conversion event that needs
        // to be closed. backtrack if necessary.
        this->bEndGeneConversion  = checkPendingGeneConversions(curPos);
        if (pConfig->bNewickFormat){
            // Chen
            //uint iSegLength = (curPos-lastPos)*pConfig->dSeqLength;
            // Schiffels following two lines fixes
            uint iSegLength = curPos*pConfig->dSeqLength-iLastCumulativePos;
            iLastCumulativePos += iSegLength; 
            cout<<NEWICKTREE<<"\t["<<iSegLength<<"]"<<
            getNewickTree(localMRCA->getHeight(),localMRCA)<<";"<<endl;
        }
        if (pConfig->dTheta>0.0){
            addMutations(lastPos,curPos);
        }
        lastPos = curPos;
        ++iGraphIteration;
    }while(curPos<dMaxPos);
    cerr<<"Completed the chromosome at position "<<curPos<<endl;
    //if (pMutationPtrVector->size()>0){
    //        cout<<HAPLOEND<<endl;
    //}
    cerr<<"gcstarts:"<<gcstarts<<" gcends:"<<gcends<<" xovers:"<<xovers<<endl;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x160, %rsp            # imm = 0x160
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xe0(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x10(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x18(%rbp)
movsd 0x14a76(%rip), %xmm0    # 0x32008
movsd %xmm0, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movq 0x2ba4b(%rip), %rdi     # 0x48ff0
leaq 0x16e44(%rip), %rsi     # 0x343f0
callq 0x42b0
movq %rax, %rdi
movq -0xe0(%rbp), %rax
movq 0x8(%rax), %rax
movb 0x48(%rax), %al
andb $0x1, %al
movzbl %al, %esi
callq 0x4500
movq %rax, %rdi
movq 0x2b9da(%rip), %rsi     # 0x48fb0
callq 0x4300
leaq -0x30(%rbp), %rdi
callq 0xb970
movq -0xe0(%rbp), %rax
movq 0x8(%rax), %rax
testb $0x1, 0x4b(%rax)
je 0x1d618
movq -0xe0(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x88(%rax), %rdi
callq 0xb990
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0xe0(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x38(%rax), %eax
cvtsi2sd %rax, %xmm1
movsd 0x16615(%rip), %xmm2    # 0x33c48
movaps %xmm1, %xmm0
addsd %xmm2, %xmm0
divsd %xmm1, %xmm0
callq 0x4230
movsd %xmm0, -0x48(%rbp)
movl $0x0, -0x4c(%rbp)
movl $0x1, -0x50(%rbp)
movl $0x2, -0x54(%rbp)
movl $0x0, -0x58(%rbp)
movl $0x0, -0x5c(%rbp)
movl $0x0, -0x60(%rbp)
movl $0x0, -0x68(%rbp)
movq -0xe0(%rbp), %rax
cmpl $0x0, 0xd0(%rax)
jne 0x1d7ab
movq 0x2b95c(%rip), %rdi     # 0x48ff0
movq 0x2b915(%rip), %rsi     # 0x48fb0
movq %rsi, -0xf8(%rbp)
callq 0x4300
movq %rax, %rdi
leaq 0x16d4b(%rip), %rsi     # 0x343fc
callq 0x42b0
movq -0xf8(%rbp), %rsi
movq %rax, %rdi
callq 0x4300
leaq -0x70(%rbp), %rdi
movq %rdi, -0xf0(%rbp)
callq 0x1e680
leaq -0x78(%rbp), %rdi
movq %rdi, -0xe8(%rbp)
callq 0xbde0
callq 0x41d0
movq -0xe0(%rbp), %rdi
movq -0xf0(%rbp), %rdx
movq -0xe8(%rbp), %rcx
cvtsi2sd %rax, %xmm0
movsd %xmm0, -0x80(%rbp)
xorl %esi, %esi
callq 0x16ec0
jmp 0x1d712
movq 0x2b8d7(%rip), %rdi     # 0x48ff0
leaq 0x16cf0(%rip), %rsi     # 0x34410
callq 0x42b0
movq %rax, -0x100(%rbp)
jmp 0x1d72e
callq 0x41d0
movq -0x100(%rbp), %rdi
cvtsi2sd %rax, %xmm0
movsd -0x80(%rbp), %xmm1
subsd %xmm1, %xmm0
callq 0x4550
movq %rax, -0x108(%rbp)
jmp 0x1d756
movq -0x108(%rbp), %rdi
leaq 0x16cc8(%rip), %rsi     # 0x3442c
callq 0x42b0
jmp 0x1d76b
leaq -0x78(%rbp), %rdi
callq 0xc150
leaq -0x70(%rbp), %rdi
callq 0x1e420
jmp 0x1da34
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x78(%rbp), %rdi
callq 0xc150
leaq -0x70(%rbp), %rdi
callq 0x1e420
jmp 0x1de45
movq -0xe0(%rbp), %rax
movb $0x0, 0xf8(%rax)
movl $0x0, -0x64(%rbp)
testb $0x1, 0xf9(%rax)
je 0x1d7d5
movl $0x2, -0x64(%rbp)
jmp 0x1d936
movq -0xe0(%rbp), %rax
movq (%rax), %rdi
callq 0x1e170
movq -0xe0(%rbp), %rax
movaps %xmm0, %xmm1
movq 0x8(%rax), %rcx
movsd 0x18(%rcx), %xmm0
movsd 0x14809(%rip), %xmm3    # 0x32008
movaps %xmm0, %xmm2
addsd %xmm3, %xmm2
divsd %xmm2, %xmm0
ucomisd %xmm1, %xmm0
seta %cl
negb %cl
andb $0x1, %cl
movb %cl, 0xf8(%rax)
testb $0x1, 0xf8(%rax)
je 0x1d934
movq -0xe0(%rbp), %rax
movl $0x1, -0x64(%rbp)
movq (%rax), %rdi
callq 0x1e170
callq 0x4230
movq -0xe0(%rbp), %rax
movaps %xmm0, %xmm1
divsd -0x48(%rbp), %xmm1
movsd 0x147ad(%rip), %xmm0    # 0x32008
addsd %xmm1, %xmm0
movq 0x8(%rax), %rcx
divsd 0x20(%rcx), %xmm0
movsd %xmm0, -0x98(%rbp)
movq 0x8(%rax), %rax
testb $0x1, 0x48(%rax)
je 0x1d8ac
movq 0x2b76f(%rip), %rdi     # 0x48ff0
leaq 0x16bae(%rip), %rsi     # 0x34436
callq 0x42b0
movq %rax, %rdi
movsd -0x98(%rbp), %xmm0
callq 0x4550
movq %rax, %rdi
movq 0x2b709(%rip), %rsi     # 0x48fb0
callq 0x4300
movl $0x20, %edi
callq 0x42c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x110(%rbp)
movsd -0x10(%rbp), %xmm0
movsd -0x98(%rbp), %xmm1
addsd %xmm1, %xmm0
callq 0x271f0
jmp 0x1d8db
movq -0xe0(%rbp), %rax
movq -0x110(%rbp), %rcx
movq %rcx, -0x40(%rbp)
movq 0xf0(%rax), %rdi
leaq -0x40(%rbp), %rsi
callq 0x1f9a0
movq %rax, -0xa8(%rbp)
movb %dl, -0xa0(%rbp)
jmp 0x1d934
movq -0x110(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
movl $0x20, %esi
callq 0x42d0
jmp 0x1de45
jmp 0x1d936
movq -0xe0(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x15e50
movl -0x64(%rbp), %eax
movl %eax, -0x114(%rbp)
testl %eax, %eax
je 0x1d96f
jmp 0x1d955
movl -0x114(%rbp), %eax
subl $0x1, %eax
je 0x1d97a
jmp 0x1d962
movl -0x114(%rbp), %eax
subl $0x2, %eax
je 0x1d985
jmp 0x1d98e
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x1d98e
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x1d98e
movl -0x60(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x60(%rbp)
movq -0xe0(%rbp), %rdi
callq 0x1c160
movq -0xe0(%rbp), %rax
testb $0x1, 0xe8(%rax)
jne 0x1d9e7
movq -0xe0(%rbp), %rax
movsd -0x10(%rbp), %xmm0
subsd 0xe0(%rax), %xmm0
movsd %xmm0, -0xb0(%rbp)
movsd -0xb0(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x1d9e5
movq -0xe0(%rbp), %rax
movb $0x1, 0xe8(%rax)
jmp 0x1d9f0
movl -0x68(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x68(%rbp)
movq 0x2b5f9(%rip), %rdi     # 0x48ff0
leaq 0x16a51(%rip), %rsi     # 0x3444f
callq 0x42b0
movq %rax, %rdi
movl -0x68(%rbp), %esi
callq 0x44d0
movq %rax, %rdi
movq 0x2b598(%rip), %rsi     # 0x48fb0
callq 0x4300
cmpl $0x0, -0x68(%rbp)
jl 0x1da32
movq -0xe0(%rbp), %rdi
movl -0x68(%rbp), %esi
callq 0x1c270
jmp 0x1da34
movq -0xe0(%rbp), %rdi
callq 0x2a690
movq 0x2b5a9(%rip), %rdi     # 0x48ff0
leaq 0x16a0f(%rip), %rsi     # 0x3445d
callq 0x42b0
movq %rax, %rdi
movq -0xe0(%rbp), %rax
movl 0xd0(%rax), %esi
callq 0x44d0
movq %rax, %rdi
leaq 0x169f1(%rip), %rsi     # 0x34463
callq 0x42b0
movq %rax, %rdi
movsd -0x10(%rbp), %xmm0
callq 0x4550
movq %rax, %rdi
leaq 0x169db(%rip), %rsi     # 0x34469
callq 0x42b0
movq %rax, %rdi
movq -0xe0(%rbp), %rax
movsd 0x30(%rax), %xmm0
callq 0x4550
movq %rax, %rdi
leaq 0x169be(%rip), %rsi     # 0x3446f
callq 0x42b0
movq -0xe0(%rbp), %rdi
movq %rax, -0x128(%rbp)
addq $0x40, %rdi
callq 0x1ded0
movq %rax, %rdi
callq 0x1df20
movq -0x128(%rbp), %rdi
callq 0x4550
movq %rax, %rdi
leaq 0x1698c(%rip), %rsi     # 0x34477
callq 0x42b0
movq %rax, %rdi
leaq 0x1696f(%rip), %rsi     # 0x34469
callq 0x42b0
movq %rax, %rdi
movq -0xe0(%rbp), %rax
movsd 0x28(%rax), %xmm0
callq 0x4550
movq %rax, %rdi
leaq 0x16952(%rip), %rsi     # 0x3446f
callq 0x42b0
movq -0xe0(%rbp), %rdi
movq %rax, -0x120(%rbp)
addq $0x38, %rdi
callq 0x1ded0
movq %rax, %rdi
callq 0x1df20
movq -0x120(%rbp), %rdi
callq 0x4550
movq %rax, %rdi
movq 0x2b459(%rip), %rsi     # 0x48fb0
callq 0x4300
movq -0xe0(%rbp), %rax
movq 0x8(%rax), %rax
testb $0x1, 0x4b(%rax)
je 0x1db96
jmp 0x1db6f
movq -0xe0(%rbp), %rdi
leaq -0x10(%rbp), %rsi
leaq -0x30(%rbp), %rdx
callq 0x1ce30
andb $0x1, %al
movb %al, -0xb1(%rbp)
testb $0x1, -0xb1(%rbp)
jne 0x1db6f
jmp 0x1dbc2
movq -0xe0(%rbp), %rdi
movq (%rdi), %rax
movq %rax, -0x130(%rbp)
callq 0x1f840
movq -0x130(%rbp), %rdi
callq 0x1ec00
addsd -0x10(%rbp), %xmm0
movsd %xmm0, -0x10(%rbp)
movsd -0x10(%rbp), %xmm0
ucomisd -0x20(%rbp), %xmm0
jbe 0x1dbd8
movsd -0x20(%rbp), %xmm0
movsd %xmm0, -0x10(%rbp)
movq -0xe0(%rbp), %rdi
leaq -0x10(%rbp), %rsi
callq 0x1d050
movb %al, %cl
movq -0xe0(%rbp), %rax
andb $0x1, %cl
movb %cl, 0xf9(%rax)
movq 0x8(%rax), %rax
testb $0x1, 0x4c(%rax)
je 0x1dd4a
movq -0xe0(%rbp), %rax
movsd -0x10(%rbp), %xmm0
movq 0x8(%rax), %rax
movsd 0x20(%rax), %xmm2
movl -0x24(%rbp), %eax
cvtsi2sd %rax, %xmm1
mulsd %xmm2, %xmm0
subsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movl %eax, -0xb8(%rbp)
movl -0xb8(%rbp), %ecx
movl -0x24(%rbp), %eax
addl %ecx, %eax
movl %eax, -0x24(%rbp)
movq 0x2b383(%rip), %rdi     # 0x48fd0
leaq 0x2b85c(%rip), %rsi     # 0x494b0
callq 0x4280
movq %rax, %rdi
leaq 0x1681a(%rip), %rsi     # 0x3447d
callq 0x42b0
movq %rax, %rdi
movl -0xb8(%rbp), %esi
callq 0x43e0
movq %rax, %rdi
leaq 0x16914(%rip), %rsi     # 0x34594
callq 0x42b0
movq -0xe0(%rbp), %rdi
movq %rax, -0x148(%rbp)
addq $0x40, %rdi
movq %rdi, -0x150(%rbp)
callq 0x1ded0
movq %rax, %rdi
callq 0x1df20
movq -0xe0(%rbp), %rsi
movq -0x150(%rbp), %rdx
leaq -0xd8(%rbp), %rdi
movq %rdi, -0x140(%rbp)
callq 0x2b000
movq -0x148(%rbp), %rdi
movq -0x140(%rbp), %rsi
callq 0x4280
movq %rax, -0x138(%rbp)
jmp 0x1dce8
movq -0x138(%rbp), %rdi
leaq 0x1678a(%rip), %rsi     # 0x34480
callq 0x42b0
movq %rax, -0x158(%rbp)
jmp 0x1dd04
movq -0x158(%rbp), %rdi
movq 0x2b29e(%rip), %rsi     # 0x48fb0
callq 0x4300
jmp 0x1dd19
leaq -0xd8(%rbp), %rdi
callq 0x4598
jmp 0x1dd4a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x4598
jmp 0x1de45
movq -0xe0(%rbp), %rax
movq 0x8(%rax), %rax
movsd (%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x1dd78
movq -0xe0(%rbp), %rdi
movsd -0x18(%rbp), %xmm0
movsd -0x10(%rbp), %xmm1
callq 0x1c810
movq -0xe0(%rbp), %rax
movsd -0x10(%rbp), %xmm0
movsd %xmm0, -0x18(%rbp)
movl 0xd0(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0xd0(%rax)
movsd -0x10(%rbp), %xmm1
movsd -0x20(%rbp), %xmm0
ucomisd %xmm1, %xmm0
ja 0x1d679
movq 0x2b23d(%rip), %rdi     # 0x48ff0
leaq 0x166c8(%rip), %rsi     # 0x34482
callq 0x42b0
movq %rax, %rdi
movsd -0x10(%rbp), %xmm0
callq 0x4550
movq %rax, %rdi
movq 0x2b1da(%rip), %rsi     # 0x48fb0
callq 0x4300
movq 0x2b20e(%rip), %rdi     # 0x48ff0
leaq 0x166bf(%rip), %rsi     # 0x344a8
callq 0x42b0
movq %rax, %rdi
movl -0x5c(%rbp), %esi
callq 0x44d0
movq %rax, %rdi
leaq 0x166af(%rip), %rsi     # 0x344b2
callq 0x42b0
movq %rax, %rdi
movl -0x60(%rbp), %esi
callq 0x44d0
movq %rax, %rdi
leaq 0x1669e(%rip), %rsi     # 0x344bb
callq 0x42b0
movq %rax, %rdi
movl -0x58(%rbp), %esi
callq 0x44d0
movq %rax, %rdi
movq 0x2b179(%rip), %rsi     # 0x48fb0
callq 0x4300
addq $0x160, %rsp            # imm = 0x160
popq %rbp
retq
movq -0x88(%rbp), %rdi
callq 0x44e0
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)