void Graph::insertMutEvents(nat genC, AddrArrayBackwardIter<Node,true> &mutBackIter, Node** nodeBufferNowGen, Chromosome &chrom, Randomness &rng) { bool canGoBack = NOT mutBackIter.empty(); nat chromId = chrom.getId(); while(canGoBack && mutBackIter()->originGen == genC) { Node *node = mutBackIter(); nat indiNr = node->indiNr; node->ancId1 = nodeBufferNowGen[indiNr] ? nodeBufferNowGen[indiNr]->id : NO_NODE ; // determine the base // :TODO: this currently does not allow for a double mutation occuring in one line node->base = chrom.mutateSite(rng, node->loc); #ifdef DEBUG_HOOKUP cout << "MUT: [" << *node << "]" << "\t===>" << (nodeBufferNowGen[indiNr] ? nodeBufferNowGen[indiNr]->id : 0) << endl; #endif nodeBufferNowGen[indiNr] = node; canGoBack = mutBackIter.back(); } }
/** Algorithm: * * two buffers, nodes are propagated according to survivor information * * when recombinations are introduced, the "directions" of these nodes have to alternate * * laying the mutations on top of the recombinations should not be a problem */ void Graph::hookup(const Survivors &survivors, const Ancestry &ancestry, const PopulationManager &popMan, Chromosome &chrom, Randomness &rng, nat startGen, nat endOfSection) { nat chromId = chrom.getId(); // set up both buffers Node **nodeBufferPrevGen = (Node**) malloc(previousState.size() * sizeof(Node*)), **nodeBufferNowGen = (Node**) malloc(popMan.getTotalNumHaploByGen(startGen) * sizeof(Node*)); nat i = 0; for(Node *node : previousState) nodeBufferPrevGen[i++] = node; AddrArrayBackwardIter<Node,true> mutBackIter; mutNodes.getEnd(mutBackIter); AddrArrayBackwardIter<Node,true> recBackIter; recNodes.getEnd(recBackIter); for(nat genC = startGen; genC < endOfSection; ++genC) { #ifdef DEBUG_HOOKUP cout << "======== hooking up generation " << genC << endl; #endif // resize buffer nodeBufferNowGen = (Node**) myRealloc(nodeBufferNowGen, popMan.getTotalNumHaploByGen(genC) * sizeof(Node*)); memset(nodeBufferNowGen,0, popMan.getTotalNumHaploByGen(genC) * sizeof(Node*)); propagateSurvivorNodes(genC, chromId, nodeBufferNowGen, nodeBufferPrevGen, ancestry, survivors); insertRecEvents(genC, chromId, recBackIter, nodeBufferNowGen, nodeBufferPrevGen, ancestry); insertMutEvents(genC, mutBackIter, nodeBufferNowGen, chrom, rng); std::swap(nodeBufferPrevGen, nodeBufferNowGen); } // we swapped once too much std::swap(nodeBufferNowGen, nodeBufferPrevGen); nat lastSize = popMan.getTotalNumHaploByGen(endOfSection-1); previousState.resize(lastSize); for(nat i = 0; i < lastSize; ++i) previousState[i] = nodeBufferNowGen[i]; free(nodeBufferPrevGen); free(nodeBufferNowGen); #ifdef DEBUG_HOOKUP cout << "================> hookup finished"<< endl; #endif }