bool flower_removeIfRedundant(Flower *flower) { if (!flower_isLeaf(flower) && flower_getParentGroup(flower) != NULL && flower_getBlockNumber(flower) == 0) { //We will remove this flower.. Group *parentGroup = flower_getParentGroup(flower); //This group will be destructed //Deal with any parent chain.. if (group_isLink(parentGroup)) { link_split(group_getLink(parentGroup)); } Flower *parentFlower = group_getFlower(parentGroup); //We will add the groups in the flower to the parent /* * For each group in the flower we take its nested flower and attach it to the parent. */ Group *group; Flower_GroupIterator *groupIt = flower_getGroupIterator(flower); while ((group = flower_getNextGroup(groupIt)) != NULL) { if (!group_isLeaf(group)) { //Copy the group into the parent.. Flower *nestedFlower = group_getNestedFlower(group); assert(nestedFlower != NULL); Group *newParentGroup = group_construct(parentFlower, nestedFlower); flower_setParentGroup(nestedFlower, newParentGroup); group_constructChainForLink(newParentGroup); } else { Group *newParentGroup = group_construct2(parentFlower); End *end; Group_EndIterator *endIt = group_getEndIterator(group); while ((end = group_getNextEnd(endIt)) != NULL) { End *parentEnd = flower_getEnd(parentFlower, end_getName(end)); assert(parentEnd != NULL); end_setGroup(parentEnd, newParentGroup); } group_destructEndIterator(endIt); group_constructChainForLink(newParentGroup); } } flower_destructGroupIterator(groupIt); //The group attached to the flower should now be empty assert(group_getEndNumber(parentGroup) == 0); group_destruct(parentGroup); //Now wipe the flower out.. cactusDisk_deleteFlowerFromDisk(flower_getCactusDisk(flower), flower); flower_destruct(flower, 0); return 1; } return 0; }
bool flower_deleteIfEmpty(Flower *flower) { if (flower_getEndNumber(flower) == 0 && flower_getParentGroup(flower) != NULL) { //contains nothing useful.. assert(flower_getChainNumber(flower) == 0); assert(flower_getBlockNumber(flower) == 0); while (flower_getGroupNumber(flower) > 0) { Group *group = flower_getFirstGroup(flower); if (!group_isLeaf(group)) { bool i = flower_deleteIfEmpty(group_getNestedFlower(group)); (void) i; assert(i); } } assert(flower_getGroupNumber(flower) == 0); //This needs modification so that we don't do this directly.. cactusDisk_deleteFlowerFromDisk(flower_getCactusDisk(flower), flower); Group *parentGroup = flower_getParentGroup(flower); group_destruct(parentGroup); flower_destruct(flower, 0); return 1; } return 0; }
void sequence_check(Sequence *sequence) { Flower *flower = sequence_getFlower(sequence); cactusCheck(flower_getSequence(flower, sequence_getName(sequence)) == sequence); //properly connected to the flower.. Group *parentGroup = flower_getParentGroup(flower); if(parentGroup != NULL) { Flower *parentFlower = group_getFlower(parentGroup); Sequence *parentSequence = flower_getSequence(parentFlower, sequence_getName(sequence)); if(parentSequence != NULL) { cactusCheck(event_getName(sequence_getEvent(sequence)) == event_getName(sequence_getEvent(parentSequence))); } } }
void event_check(Event *event) { EventTree *eventTree = event_getEventTree(event); Event *ancestorEvent = event_getParent(event); //Check event and eventree properly linked cactusCheck(eventTree_getEvent(event_getEventTree(event), event_getName(event)) == event); //Event has parent, unless it is root. if (eventTree_getRootEvent(eventTree) == event) { cactusCheck(ancestorEvent == NULL); } else { //not root, so must have ancestor. cactusCheck(ancestorEvent != NULL); } //Each child event has event as parent. int64_t i = 0; for (i = 0; i < event_getChildNumber(event); i++) { Event *childEvent = event_getChild(event, i); cactusCheck(event_getParent(childEvent) == event); } //Ancestor-event --> event edge is consistent with any event tree that is in the parent of the containing flower. Group *parentGroup = flower_getParentGroup(eventTree_getFlower( event_getEventTree(event))); if (parentGroup != NULL) { EventTree *parentEventTree = flower_getEventTree(group_getFlower( parentGroup)); Event *parentEvent = eventTree_getEvent(parentEventTree, event_getName( event)); if (parentEvent != NULL) { if (ancestorEvent == NULL) { //the case where they are both root. cactusCheck(eventTree_getRootEvent(parentEventTree) == parentEvent); } else { //Check edge ancestorEvent --> event is in parent event tree. while (1) { Event *parentAncestorEvent = eventTree_getEvent( parentEventTree, event_getName(ancestorEvent)); if (parentAncestorEvent != NULL) { cactusCheck(event_isAncestor(parentEvent, parentAncestorEvent)); break; } ancestorEvent = event_getParent(ancestorEvent); cactusCheck(ancestorEvent != NULL); } } } } }
static Cap *copyCapToParent(Cap *cap, stList *recoveredCaps) { /* * Get the adjacent stub end by looking at the reference adjacency in the parent. */ End *end = cap_getEnd(cap); assert(end != NULL); Group *parentGroup = flower_getParentGroup(end_getFlower(end)); assert(parentGroup != NULL); End *copiedEnd = end_copyConstruct(end, group_getFlower(parentGroup)); end_setGroup(copiedEnd, parentGroup); //Set group Cap *copiedCap = end_getInstance(copiedEnd, cap_getName(cap)); assert(copiedCap != NULL); copiedCap = cap_getStrand(copiedCap) ? copiedCap : cap_getReverse(copiedCap); if (!cap_getSide(copiedCap)) { stList_append(recoveredCaps, copiedCap); } return copiedCap; }
void flower_delete2(Flower *flower, bool isOnDisk) { Flower_GroupIterator *groupIt = flower_getGroupIterator(flower); Group *group; while ((group = flower_getNextGroup(groupIt)) != NULL) { if (!group_isLeaf(group)) { flower_delete2(group_getNestedFlower(group), isOnDisk); } } flower_destructGroupIterator(groupIt); Group *parentGroup = flower_getParentGroup(flower); if(parentGroup != NULL) { parentGroup->leafGroup = 1; } //This needs modification so that we don't do this directly.. if(isOnDisk) { cactusDisk_deleteFlowerFromDisk(flower_getCactusDisk(flower), flower); } flower_destruct(flower, 0); }
void testGroup_makeNonLeaf(CuTest *testCase) { cactusGroupTestSetup(); CuAssertTrue(testCase, group_isLeaf(group2)); end_setGroup(end4, group2); group_makeNestedFlower(group2); CuAssertTrue(testCase, !group_isLeaf(group2)); Flower *nestedFlower = group_getNestedFlower(group2); CuAssertTrue(testCase, nestedFlower != NULL); CuAssertTrue(testCase, !flower_builtBlocks(flower)); CuAssertTrue(testCase, !flower_builtTrees(flower)); CuAssertTrue(testCase, !flower_builtFaces(flower)); CuAssertTrue(testCase, flower_getName(nestedFlower) == group_getName(group2)); CuAssertTrue(testCase, flower_getParentGroup(nestedFlower) == group2); CuAssertTrue(testCase, flower_getEndNumber(nestedFlower) == 1); End *nestedEnd = flower_getFirstEnd(nestedFlower); CuAssertTrue(testCase, end_getName(end4) == end_getName(nestedEnd)); CuAssertTrue(testCase, end_getGroup(nestedEnd) != NULL); CuAssertTrue(testCase, flower_getGroupNumber(nestedFlower) == 1); CuAssertTrue(testCase, flower_isTerminal(nestedFlower)); cactusGroupTestTeardown(); }
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; }
void makeCactusTree_flower(Flower *flower, FILE *fileHandle, const char *parentNodeName, const char *parentEdgeColour) { if(flower_isTerminal(flower)) { makeCactusTree_terminalNode(flower, fileHandle, parentNodeName, parentEdgeColour); } else { //Write the flower nodes. char *flowerNameString = cactusMisc_nameToString(flower_getName(flower)); const char *edgeColour = graphViz_getColour(); addNodeToGraph(flowerNameString, fileHandle, flower_getTotalBaseLength(flower) / totalProblemSize, "ellipse", flowerNameString); //Write in the parent edge. if (parentNodeName != NULL) { graphViz_addEdgeToGraph(parentNodeName, flowerNameString, fileHandle, "", parentEdgeColour, 10, 1, "forward"); } //Create the chains. Flower_ChainIterator *chainIterator = flower_getChainIterator(flower); Chain *chain; while ((chain = flower_getNextChain(chainIterator)) != NULL) { makeCactusTree_chain(chain, fileHandle, flowerNameString, edgeColour); } flower_destructChainIterator(chainIterator); //Create the diamond node char *diamondNodeNameString = st_malloc(sizeof(char) * (strlen( flowerNameString) + 2)); sprintf(diamondNodeNameString, "z%s", flowerNameString); const char *diamondEdgeColour = graphViz_getColour(); //Create all the groups linked to the diamond. Flower_GroupIterator *groupIterator = flower_getGroupIterator(flower); Group *group; double size = 0.0; //get the size of the group organising node.. int64_t nonTrivialGroupCount = 0; while ((group = flower_getNextGroup(groupIterator)) != NULL) { assert(!group_isLeaf(group)); if (group_isTangle(group)) { size += group_getTotalBaseLength(group); nonTrivialGroupCount++; } } flower_destructGroupIterator(groupIterator); if(nonTrivialGroupCount == 0) { assert(flower_getParentGroup(flower) == 0); } else { //assert(nonTrivialGroupCount > 0); addNodeToGraph(diamondNodeNameString, fileHandle, size / totalProblemSize, "diamond", ""); graphViz_addEdgeToGraph(flowerNameString, diamondNodeNameString, fileHandle, "", edgeColour, 10, 1, "forward"); groupIterator = flower_getGroupIterator(flower); while ((group = flower_getNextGroup(groupIterator)) != NULL) { if (group_isTangle(group)) { assert(!group_isLeaf(group)); makeCactusTree_flower(group_getNestedFlower(group), fileHandle, diamondNodeNameString, diamondEdgeColour); } } flower_destructGroupIterator(groupIterator); } free(flowerNameString); free(diamondNodeNameString); } }
void testFlower_removeIfRedundant(CuTest *testCase) { /* * Do a simple test to see if function can remove a redundant flower. */ cactusFlowerTestSetup(); endsSetup(); //First construct a redundant flower from the root. Flower *flower2 = flower_construct(cactusDisk); Group *group = group_construct(flower, flower2); end_setGroup(end, group); end_setGroup(end2, group); //Now hang another couple of flowers of that. Flower *flower3 = flower_construct(cactusDisk); group_construct(flower2, flower3); //Now hang another flower of that. Group *group3b = group_construct2(flower2); //Finally hang one more flower on the end.. Flower *flower4 = flower_construct(cactusDisk); group_construct(flower3, flower4); //Copy the ends into the flowers. end_copyConstruct(end, flower2); end_copyConstruct(end2, flower2); end_copyConstruct(end, flower3); end_setGroup(flower_getEnd(flower2, end_getName(end2)), group3b); end_copyConstruct(end, flower4); //st_uglyf("I got %" PRIi64 " %" PRIi64 " %" PRIi64 " %" PRIi64 "\n", flower_getName(flower), flower_getName(flower2), flower_getName(flower3), flower_getName(flower4)); //Write the mess to disk. cactusDisk_write(cactusDisk); //Now test the removal function (check we get a negative on this leaf). CuAssertTrue(testCase, !flower_removeIfRedundant(flower4)); //Check we can't remove the root.. CuAssertTrue(testCase, !flower_removeIfRedundant(flower)); //We will remove flower2 //Before CuAssertTrue(testCase, flower_getGroupNumber(flower) == 1); CuAssertTrue(testCase, group_getFlower(flower_getParentGroup(flower2)) == flower); CuAssertTrue(testCase, flower_removeIfRedundant(flower2)); //After, check the flower/group connections CuAssertTrue(testCase, flower_getGroupNumber(flower) == 2); CuAssertTrue(testCase, !flower_isLeaf(flower)); CuAssertTrue(testCase, group_getFlower(flower_getParentGroup(flower3)) == flower); group3b = end_getGroup(end2); CuAssertTrue(testCase, group_getFlower(group3b) == flower); CuAssertTrue(testCase, group_isLeaf(group3b)); CuAssertTrue(testCase, flower_getGroup(flower, flower_getName(flower3)) == flower_getParentGroup(flower3)); //Check the ends.. CuAssertTrue(testCase, flower_getEndNumber(flower) == 2); CuAssertTrue(testCase, flower_getEndNumber(flower3) == 1); CuAssertTrue(testCase, group_getEndNumber(group3b) == 1); CuAssertTrue(testCase, end_getGroup(end) == flower_getParentGroup(flower3)); CuAssertTrue(testCase, end_getGroup(end2) == group3b); CuAssertTrue(testCase, flower_getEnd(flower3, end_getName(end)) != NULL); //Check the child of 3 is still okay.. CuAssertTrue(testCase, group_getFlower(flower_getParentGroup(flower4)) == flower3); //Now do removal of flower3 CuAssertTrue(testCase, !flower_removeIfRedundant(flower)); CuAssertTrue(testCase, !flower_removeIfRedundant(flower4)); CuAssertTrue(testCase, flower_removeIfRedundant(flower3)); //Check groups again CuAssertTrue(testCase, flower_getGroupNumber(flower) == 2); CuAssertTrue(testCase, !flower_isLeaf(flower)); CuAssertTrue(testCase, group_getFlower(flower_getParentGroup(flower4)) == flower); CuAssertTrue(testCase, group_getFlower(group3b) == flower); CuAssertTrue(testCase, flower_getGroup(flower, flower_getName(flower4)) == flower_getParentGroup(flower4)); //Check the ends again.. CuAssertTrue(testCase, flower_getEndNumber(flower) == 2); CuAssertTrue(testCase, flower_getEndNumber(flower4) == 1); CuAssertTrue(testCase, group_getEndNumber(group3b) == 1); CuAssertTrue(testCase, end_getGroup(end) == flower_getParentGroup(flower4)); CuAssertTrue(testCase, end_getGroup(end2) == group3b); CuAssertTrue(testCase, flower_getEnd(flower4, end_getName(end)) != NULL); cactusFlowerTestTeardown(); }