static int64_t traceThreadLength(Cap *cap, Cap **terminatingCap) { /* * Gets the length in bases of the thread in the flower, starting from a given attached stub cap. * The thread length includes the lengths of adjacencies that it contains. * * Terminating cap is initialised with the final cap on the thread from cap. */ assert(end_isStubEnd(cap_getEnd(cap))); int64_t threadLength = 0; while (1) { assert(cap_getCoordinate(cap) != INT64_MAX); int64_t adjacencyLength = cap_getCoordinate(cap); threadLength += adjacencyLength; Cap *adjacentCap = cap_getAdjacency(cap); assert(adjacentCap != NULL); assert(adjacencyLength == cap_getCoordinate(adjacentCap)); //Traverse any block.. if (cap_getSegment(adjacentCap) != NULL) { threadLength += segment_getLength(cap_getSegment(adjacentCap)); cap = cap_getOtherSegmentCap(adjacentCap); assert(cap != NULL); } else { assert(end_isStubEnd(cap_getEnd(adjacentCap))); *terminatingCap = adjacentCap; return threadLength; } } return 1; }
void testEnd_isBlockOrStubEnd(CuTest* testCase) { cactusEndTestSetup(); CuAssertTrue(testCase, end_isStubEnd(end)); CuAssertTrue(testCase, !end_isBlockEnd(end)); Block *block = block_construct(2, flower); End *leftEnd = block_get5End(block); End *rightEnd = block_get3End(block); CuAssertTrue(testCase, end_isBlockEnd(leftEnd)); CuAssertTrue(testCase, end_isBlockEnd(rightEnd)); CuAssertTrue(testCase, !end_isStubEnd(leftEnd)); CuAssertTrue(testCase, !end_isStubEnd(rightEnd)); cactusEndTestTeardown(); }
static void recoverBrokenAdjacencies(Flower *flower, stList *recoveredCaps, Name referenceEventName) { /* * Find reference intervals that are book-ended by stubs created in a child flower. */ Flower_GroupIterator *groupIt = flower_getGroupIterator(flower); Group *group; while((group = flower_getNextGroup(groupIt)) != NULL) { Flower *nestedFlower; if((nestedFlower = group_getNestedFlower(group)) != NULL) { Flower_EndIterator *endIt = flower_getEndIterator(nestedFlower); End *childEnd; while((childEnd = flower_getNextEnd(endIt)) != NULL) { if(end_isStubEnd(childEnd) && flower_getEnd(flower, end_getName(childEnd)) == NULL) { //We have a thread we need to promote Cap *childCap = getCapForReferenceEvent(childEnd, referenceEventName); //The cap in the reference assert(childCap != NULL); assert(!end_isAttached(childEnd)); childCap = cap_getStrand(childCap) ? childCap : cap_getReverse(childCap); if (!cap_getSide(childCap)) { Cap *adjacentChildCap = NULL; int64_t adjacencyLength = traceThreadLength(childCap, &adjacentChildCap); Cap *cap = copyCapToParent(childCap, recoveredCaps); assert(adjacentChildCap != NULL); assert(!end_isAttached(cap_getEnd(adjacentChildCap))); assert(!cap_getSide(cap)); Cap *adjacentCap = copyCapToParent(adjacentChildCap, recoveredCaps); cap_makeAdjacent(cap, adjacentCap); setAdjacencyLength(cap, adjacentCap, adjacencyLength); } } } flower_destructEndIterator(endIt); } } flower_destructGroupIterator(groupIt); }
int64_t flower_getFreeStubEndNumber(Flower *flower) { End *end; Flower_EndIterator *iterator = flower_getEndIterator(flower); int64_t i = 0; while ((end = flower_getNextEnd(iterator)) != NULL) { if (end_isStubEnd(end) && end_isFree(end)) { i++; } } flower_destructEndIterator(iterator); return i; }
static stList *getCaps(stList *flowers, Name referenceEventName) { stList *caps = stList_construct(); for (int64_t i = 0; i < stList_length(flowers); i++) { Flower *flower = stList_get(flowers, i); //Get list of caps Flower_EndIterator *endIt = flower_getEndIterator(flower); End *end; while ((end = flower_getNextEnd(endIt)) != NULL) { if (end_isStubEnd(end)) { Cap *cap = getCapForReferenceEvent(end, referenceEventName); //The cap in the reference if(cap != NULL) { cap = cap_getStrand(cap) ? cap : cap_getReverse(cap); if (!cap_getSide(cap)) { stList_append(caps, cap); } } } } flower_destructEndIterator(endIt); } return caps; }
Segment *getCapsSegment(Cap *cap) { if (cap_getSegment(cap) != NULL) { return cap_getSegment(cap); } assert(!end_isBlockEnd(cap_getEnd(cap))); assert(end_isStubEnd(cap_getEnd(cap))); //Walk up to get the next adjacency. Group *parentGroup = flower_getParentGroup(end_getFlower(cap_getEnd(cap))); if (parentGroup != NULL) { Cap *parentCap = flower_getCap(group_getFlower(parentGroup), cap_getName(cap)); if (parentCap != NULL) { assert(cap_getOrientation(parentCap)); if (!cap_getOrientation(cap)) { parentCap = cap_getReverse(parentCap); } return getCapsSegment(parentCap); } else { //Cap must be a free stub end. assert(0); //Not in the current alignments. assert(end_isFree(cap_getEnd(cap))); } } return NULL; }
static stList *getSubstringsForFlowers(stList *flowers) { /* * Get the set of substrings for sequence intervals in the given set of flowers. */ stList *substrings = stList_construct3(0, (void (*)(void *)) substring_destruct); for (int64_t i = 0; i < stList_length(flowers); i++) { Flower *flower = stList_get(flowers, i); Flower_EndIterator *endIt = flower_getEndIterator(flower); End *end; while ((end = flower_getNextEnd(endIt)) != NULL) { if (end_isStubEnd(end)) { End_InstanceIterator *instanceIt = end_getInstanceIterator(end); Cap *cap; while ((cap = end_getNext(instanceIt)) != NULL) { Sequence *sequence; if ((sequence = cap_getSequence(cap)) != NULL) { cap = cap_getStrand(cap) ? cap : cap_getReverse(cap); if (!cap_getSide(cap)) { //We have a sequence interval of interest Cap *adjacentCap = cap_getAdjacency(cap); assert(adjacentCap != NULL); int64_t length = cap_getCoordinate(adjacentCap) - cap_getCoordinate(cap) - 1; assert(length >= 0); if (length > 0) { stList_append(substrings, substring_construct(sequence_getMetaSequence(sequence)->stringName, cap_getCoordinate(cap) + 1 - sequence_getStart(sequence), length)); } } } } end_destructInstanceIterator(instanceIt); } } flower_destructEndIterator(endIt); } return substrings; }