bool capsAreAdjacent(Cap *cap1, Cap *cap2, int64_t *separationDistance) { if (cap_getName(cap2) != cap_getName(cap1) && cap_getCoordinate(cap1) != cap_getCoordinate(cap2)) { //This can happen if end1 == end2 if (sequence_getMetaSequence(cap_getSequence(cap1)) == sequence_getMetaSequence(cap_getSequence(cap2))) { assert(strcmp(event_getHeader(cap_getEvent(cap1)), event_getHeader( cap_getEvent(cap2))) == 0); assert(cap_getPositiveOrientation(cap1) != cap_getPositiveOrientation(cap2)); assert(cap_getName(cap1) != cap_getName(cap2)); assert(sequence_getMetaSequence(cap_getSequence(cap1)) == sequence_getMetaSequence(cap_getSequence(cap2))); if (!cap_getStrand(cap1)) { cap1 = cap_getReverse(cap1); } if (!cap_getStrand(cap2)) { cap2 = cap_getReverse(cap2); } assert(cap_getStrand(cap1)); assert(cap_getStrand(cap2)); if (cap_getCoordinate(cap1) < cap_getCoordinate(cap2)) { if (!cap_getSide(cap1) && cap_getSide(cap2)) { *separationDistance = cap_getCoordinate(cap2) - cap_getCoordinate(cap1) - 1; //The minus 1, to give the length of the sequence between the two caps. return 1; } } else { if (cap_getSide(cap1) && !cap_getSide(cap2)) { *separationDistance = cap_getCoordinate(cap1) - cap_getCoordinate(cap2) - 1; return 1; } } } } return 0; }
bool trueAdjacency(Cap *cap, stList *eventStrings) { if(getTerminalAdjacencyLength(cap) > 0) { return 0; } cap = getTerminalCap(cap); assert(cap != NULL); Cap *otherCap = cap_getAdjacency(cap); assert(otherCap != NULL); assert(cap_getAdjacency(otherCap) == cap); //So is the adjacency present in one of the haplotypes? That's what we're going to answer.. End *otherEnd = end_getPositiveOrientation(cap_getEnd(otherCap)); End_InstanceIterator *endInstanceIt = end_getInstanceIterator(cap_getEnd(cap)); Cap *cap2; while ((cap2 = end_getNext(endInstanceIt)) != NULL) { Cap *otherCap2 = cap_getAdjacency(cap2); assert(otherCap2 != NULL); if (otherEnd == end_getPositiveOrientation(cap_getEnd(otherCap2))) { //const char *eventName = event_getHeader(cap_getEvent(cap2)); assert(event_getHeader(cap_getEvent(cap2)) == event_getHeader( cap_getEvent(otherCap2))); if (capHasGivenEvents(cap2, eventStrings)) { //strcmp(eventName, "hapA1") == 0 || strcmp(eventName, "hapA2") == 0) { if(getTerminalAdjacencyLength(cap2) == 0) { end_destructInstanceIterator(endInstanceIt); return 1; } } } } end_destructInstanceIterator(endInstanceIt); return 0; }
static bool capHasGivenEvents(Cap *cap, stList *eventStrings) { const char *headerSeq = event_getHeader(cap_getEvent(cap)); for (int64_t i = 0; i < stList_length(eventStrings); i++) { if (strcmp(headerSeq, stList_get(eventStrings, i)) == 0) { return 1; } } return 0; }
// Used for interactive debugging. void stCaf_printBlock(stPinchBlock *block) { stPinchBlockIt blockIt = stPinchBlock_getSegmentIterator(block); stPinchSegment *segment; while ((segment = stPinchBlockIt_getNext(&blockIt)) != NULL) { stPinchThread *thread = stPinchSegment_getThread(segment); Cap *cap = flower_getCap(flower, stPinchThread_getName(thread)); Event *event = cap_getEvent(cap); Sequence *sequence = cap_getSequence(cap); printf("%s.%s:%" PRIi64 "-%" PRIi64 ":%s\n", event_getHeader(event), sequence_getHeader(sequence), stPinchSegment_getStart(segment), stPinchSegment_getStart(segment) + stPinchSegment_getLength(segment), stPinchSegment_getBlockOrientation(segment) ? "+" : "-"); } }
bool hasCapNotInEvent(End *end, const char *eventString) { Cap *cap; End_InstanceIterator *instanceIt = end_getInstanceIterator(end); while ((cap = end_getNext(instanceIt)) != NULL) { if (strcmp(event_getHeader(cap_getEvent(cap)), eventString) != 0) { end_destructInstanceIterator(instanceIt); return 1; } } end_destructInstanceIterator(instanceIt); return 0; }
bool endsAreConnected(End *end1, End *end2, stList *eventStrings) { if (end_getName(end1) == end_getName(end2)) { //Then the ends are the same and are part of the same chromosome by definition. End_InstanceIterator *instanceIterator = end_getInstanceIterator(end1); Cap *cap1; while ((cap1 = end_getNext(instanceIterator)) != NULL) { if (capHasGivenEvents(cap1, eventStrings)) { end_destructInstanceIterator(instanceIterator); return 1; } } return 0; } End_InstanceIterator *instanceIterator = end_getInstanceIterator(end1); Cap *cap1; while ((cap1 = end_getNext(instanceIterator)) != NULL) { if (capHasGivenEvents(cap1, eventStrings)) { End_InstanceIterator *instanceIterator2 = end_getInstanceIterator(end2); Cap *cap2; while ((cap2 = end_getNext(instanceIterator2)) != NULL) { assert(cap_getName(cap2) != cap_getName(cap1)); //This could only happen if end1 == end2 if (sequence_getMetaSequence(cap_getSequence(cap1)) == sequence_getMetaSequence(cap_getSequence(cap2))) { assert(strcmp(event_getHeader(cap_getEvent(cap1)), event_getHeader(cap_getEvent(cap2))) == 0); assert(cap_getPositiveOrientation(cap1) != cap_getPositiveOrientation(cap2)); assert(cap_getName(cap1) != cap_getName(cap2)); //they could have the same coordinate if they represent two ends of a block of length 1. end_destructInstanceIterator(instanceIterator); end_destructInstanceIterator(instanceIterator2); return 1; } } end_destructInstanceIterator(instanceIterator2); } } end_destructInstanceIterator(instanceIterator); return 0; }
static MetaSequence *addMetaSequence(Flower *flower, Cap *cap, int64_t index, char *string, bool trivialString) { /* * Adds a meta sequence representing a top level thread to the cactus disk. * The sequence is all 'N's at this stage. */ Event *referenceEvent = cap_getEvent(cap); assert(referenceEvent != NULL); char *sequenceName = stString_print("%srefChr%" PRIi64 "", event_getHeader(referenceEvent), index); //char *sequenceName = stString_print("refChr%" PRIi64 "", index); MetaSequence *metaSequence = metaSequence_construct3(1, strlen(string), string, sequenceName, event_getName(referenceEvent), trivialString, flower_getCactusDisk(flower)); free(sequenceName); return metaSequence; }
Cap *getCapForReferenceEvent(End *end, Name referenceEventName) { /* * Get the cap for a given event. */ End_InstanceIterator *it = end_getInstanceIterator(end); Cap *cap; while ((cap = end_getNext(it)) != NULL) { if (event_getName(cap_getEvent(cap)) == referenceEventName) { end_destructInstanceIterator(it); return cap; } } end_destructInstanceIterator(it); //assert(0); return NULL; }
static stSortedSet *getEventStrings(End *end, stList *eventStrings) { stSortedSet *eventStringsSet = stSortedSet_construct3( (int(*)(const void *, const void *)) strcmp, NULL); End_InstanceIterator *instanceIt = end_getInstanceIterator(end); Cap *cap; while ((cap = end_getNext(instanceIt)) != NULL) { const char *header = event_getHeader(cap_getEvent(cap)); for(int64_t i=0; i<stList_length(eventStrings); i++) { if(strcmp(stList_get(eventStrings, i), header) == 0) { stSortedSet_insert(eventStringsSet, (void *) header); } } } end_destructInstanceIterator(instanceIt); return eventStringsSet; }
// Get the number of possible pairwise alignments that could support // this block. Ordinarily this is (degree choose 2), but since we // don't do outgroup self-alignment, it's a bit smaller. static uint64_t numPossibleSupportingHomologies(stPinchBlock *block, Flower *flower) { uint64_t outgroupDegree = 0, ingroupDegree = 0; stPinchBlockIt segIt = stPinchBlock_getSegmentIterator(block); stPinchSegment *segment; while ((segment = stPinchBlockIt_getNext(&segIt)) != NULL) { Name capName = stPinchSegment_getName(segment); Cap *cap = flower_getCap(flower, capName); Event *event = cap_getEvent(cap); if (event_isOutgroup(event)) { outgroupDegree++; } else { ingroupDegree++; } } assert(outgroupDegree + ingroupDegree == stPinchBlock_getDegree(block)); // We do the ingroup-ingroup alignments as an all-against-all // alignment, so we can see each ingroup-ingroup homology up to // twice. return choose2(ingroupDegree) * 2 + ingroupDegree * outgroupDegree; }
void testCap_getEvent(CuTest* testCase) { cactusCapTestSetup(); CuAssertTrue(testCase, cap_getEvent(rootCap) == rootEvent); CuAssertTrue(testCase, cap_getEvent(cap_getReverse(rootCap)) == rootEvent); cactusCapTestTeardown(); }