void testEnd_setGroup(CuTest* testCase) { cactusEndTestSetup(); Flower *flower2 = flower_construct(cactusDisk); Group *group2 = group_construct2(flower2); End *end2 = end_construct(1, flower2); End *end3 = end_construct(1, flower2); CuAssertTrue(testCase, group_getEndNumber(group2) == 0); CuAssertTrue(testCase, end_getGroup(end2) == NULL); CuAssertTrue(testCase, end_getGroup(end3) == NULL); end_setGroup(end2, group2); CuAssertTrue(testCase, group_getEndNumber(group2) == 1); CuAssertTrue(testCase, end_getGroup(end2) == group2); CuAssertTrue(testCase, group_getEnd(group2, end_getName(end2)) == end2); CuAssertTrue(testCase, end_getGroup(end3) == NULL); end_setGroup(end3, group2); CuAssertTrue(testCase, group_getEndNumber(group2) == 2); CuAssertTrue(testCase, end_getGroup(end2) == group2); CuAssertTrue(testCase, group_getEnd(group2, end_getName(end2)) == end2); CuAssertTrue(testCase, end_getGroup(end3) == group2); CuAssertTrue(testCase, group_getEnd(group2, end_getName(end3)) == end3); end_setGroup(end3, NULL); end_setGroup(end2, group2); CuAssertTrue(testCase, group_getEndNumber(group2) == 1); CuAssertTrue(testCase, end_getGroup(end2) == group2); CuAssertTrue(testCase, group_getEnd(group2, end_getName(end2)) == end2); CuAssertTrue(testCase, end_getGroup(end3) == NULL); cactusEndTestTeardown(); }
void testFlower_isLeaf(CuTest *testCase) { cactusFlowerTestSetup(); CuAssertTrue(testCase, flower_isLeaf(flower)); Group *group = group_construct2(flower); CuAssertTrue(testCase, flower_isLeaf(flower)); group_makeNestedFlower(group); CuAssertTrue(testCase, !flower_isLeaf(flower)); cactusFlowerTestTeardown(); }
void testFlower_isTerminal(CuTest *testCase) { cactusFlowerTestSetup(); CuAssertTrue(testCase, flower_isTerminal(flower)); group_construct2(flower); CuAssertTrue(testCase, flower_isTerminal(flower)); end_construct(0, flower); CuAssertTrue(testCase, flower_isTerminal(flower)); block_construct(1, flower); CuAssertTrue(testCase, !flower_isTerminal(flower)); cactusFlowerTestTeardown(); }
void testBlock_isTrivialChain(CuTest *testCase) { cactusBlockTestSetup(); Group *group = group_construct2(flower); end_setGroup(block_get5End(block), group); end_setGroup(block_get3End(block), group); Chain *chain = chain_construct(flower); Group *group2 = group_construct2(flower); CuAssertTrue(testCase, block_isTrivialChain(block)); Block *block1 = block_construct(1, flower); Block *block2 = block_construct(1, flower); end_setGroup(block_get5End(block2), group2); end_setGroup(block_get3End(block1), group2); link_construct(block_get3End(block1), block_get5End(block2), group2, chain); end_setGroup(block_get5End(block1), group); end_setGroup(block_get3End(block2), group); CuAssertTrue(testCase, block_isTrivialChain(block)); CuAssertTrue(testCase, !block_isTrivialChain(block1)); CuAssertTrue(testCase, !block_isTrivialChain(block2)); cactusBlockTestTeardown(); }
void testFlower_getTrivialChainNumber(CuTest* testCase) { cactusFlowerTestSetup(); CuAssertIntEquals(testCase, 0, flower_getTrivialChainNumber(flower)); chain = chain_construct(flower); chain2 = chain_construct(flower); CuAssertIntEquals(testCase, 0, flower_getTrivialChainNumber(flower)); group = group_construct2(flower); group2 = group_construct2(flower); block = block_construct(1, flower); end_setGroup(block_get5End(block), group); end_setGroup(block_get3End(block), group2); CuAssertIntEquals(testCase, 1, flower_getTrivialChainNumber(flower)); block2 = block_construct(1, flower); end_setGroup(block_get5End(block2), group2); end_setGroup(block_get3End(block2), group); CuAssertIntEquals(testCase, 2, flower_getTrivialChainNumber(flower)); link_construct(block_get3End(block), block_get5End(block2), group2, chain); CuAssertIntEquals(testCase, 0, flower_getTrivialChainNumber(flower)); link_construct(block_get3End(block2), block_get5End(block), group, chain); CuAssertIntEquals(testCase, 0, flower_getTrivialChainNumber(flower)); cactusFlowerTestTeardown(); }
static void cactusGroupTestSetup() { cactusGroupTestTeardown(); cactusDisk = testCommon_getTemporaryCactusDisk(); flower = flower_construct(cactusDisk); nestedFlower = flower_construct(cactusDisk); end1 = end_construct2(0, 0, flower); end2 = end_construct(0, flower); end3 = end_construct(0, flower); nestedEnd1 = end_copyConstruct(end1, nestedFlower); nestedEnd2 = end_copyConstruct(end2, nestedFlower); group = group_construct(flower, nestedFlower); group2 = group_construct2(flower); end4 = end_construct(0, flower); }
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; }
void testGroup_constructChainForLink(CuTest *testCase) { cactusGroupTestSetup(); //Create a link group and test function works! Group *group3 = group_construct2(flower); End *_5End = end_construct2(1, 1, flower); End *_3End = end_construct2(0, 1, flower); End *stubEnd = end_construct2(1, 0, flower); end_setGroup(_5End, group3); end_setGroup(_3End, group3); end_setGroup(stubEnd, group3); CuAssertTrue(testCase, group_isTangle(group3)); CuAssertTrue(testCase, group_getEndNumber(group3) == 3); group_constructChainForLink(group3); CuAssertTrue(testCase, group_isLink(group3)); Link *link = group_getLink(group3); CuAssertTrue(testCase, link_get5End(link) == _5End); CuAssertTrue(testCase, link_get3End(link) == _3End); cactusGroupTestTeardown(); }
void testEventTree_addSiblingUnaryEvent(CuTest *testCase) { cactusEventTreeTestSetup(); //Create two sibling flowers with the basic event tree.. //then try adding events from on into the other. Group *group1 = group_construct2(flower); Group *group2 = group_construct2(flower); Flower *flower2 = flower_construct(cactusDisk); Flower *flower3 = flower_construct(cactusDisk); flower_setParentGroup(flower2, group1); flower_setParentGroup(flower3, group2); EventTree *eventTree2 = eventTree_copyConstruct(flower_getEventTree(flower), flower2, NULL); Event *parentUnaryEvent1 = event_construct4("UNARY1", 0.1, internalEvent, leafEvent1, eventTree); Event *parentUnaryEvent2 = event_construct4("UNARY2", 0.1, parentUnaryEvent1, leafEvent1, eventTree); Event *parentUnaryEvent3 = event_construct4("UNARY3", 0.1, internalEvent, leafEvent2, eventTree); //now event tree contains the added unary events. EventTree *eventTree3 = eventTree_copyConstruct(flower_getEventTree(flower), flower3, NULL); //add a couple of denovo events into the new event tree Event *internalEventChild = eventTree_getEvent(eventTree3, event_getName(internalEvent)); Event *unaryEvent1 = eventTree_getEvent(eventTree3, event_getName(parentUnaryEvent1)); Event *unaryEvent2 = eventTree_getEvent(eventTree3, event_getName(parentUnaryEvent2)); Event *unaryEvent3 = eventTree_getEvent(eventTree3, event_getName(parentUnaryEvent3)); Event *unaryEvent4 = event_construct4("UNARY4", 0.1, internalEventChild, unaryEvent3, eventTree3); Event *unaryEvent5 = event_construct4("UNARY5", 0.1, internalEventChild, unaryEvent4, eventTree3); //Now event-tree 2 does not contain the unary events but event-tree 3 does.. CuAssertTrue(testCase, eventTree_getEvent(eventTree2, event_getName(unaryEvent1)) == NULL); CuAssertTrue(testCase, eventTree_getEvent(eventTree2, event_getName(unaryEvent2)) == NULL); CuAssertTrue(testCase, eventTree_getEvent(eventTree2, event_getName(unaryEvent3)) == NULL); CuAssertTrue(testCase, eventTree_getEvent(eventTree2, event_getName(unaryEvent4)) == NULL); CuAssertTrue(testCase, eventTree_getEvent(eventTree2, event_getName(unaryEvent5)) == NULL); eventTree_addSiblingUnaryEvent(eventTree2, unaryEvent1); Event *unaryEvent12 = eventTree_getEvent(eventTree2, event_getName(unaryEvent1)); CuAssertTrue(testCase, unaryEvent12 != NULL); CuAssertTrue(testCase, event_getName(event_getParent(unaryEvent12)) == event_getName(internalEvent)); CuAssertTrue(testCase, event_getChildNumber(unaryEvent12) == 1); CuAssertTrue(testCase, event_getName(event_getChild(unaryEvent12, 0)) == event_getName(leafEvent1)); eventTree_addSiblingUnaryEvent(eventTree2, unaryEvent2); Event *unaryEvent22 = eventTree_getEvent(eventTree2, event_getName(unaryEvent2)); CuAssertTrue(testCase, unaryEvent22 != NULL); CuAssertTrue(testCase, event_getName(event_getParent(unaryEvent22)) == event_getName(unaryEvent1)); CuAssertTrue(testCase, event_getChildNumber(unaryEvent22) == 1); CuAssertTrue(testCase, event_getName(event_getChild(unaryEvent22, 0)) == event_getName(leafEvent1)); eventTree_addSiblingUnaryEvent(eventTree2, unaryEvent3); Event *unaryEvent32 = eventTree_getEvent(eventTree2, event_getName(unaryEvent3)); CuAssertTrue(testCase, unaryEvent32 != NULL); CuAssertTrue(testCase, event_getName(event_getParent(unaryEvent32)) == event_getName(internalEvent)); CuAssertTrue(testCase, event_getChildNumber(unaryEvent32) == 1); CuAssertTrue(testCase, event_getName(event_getChild(unaryEvent32, 0)) == event_getName(leafEvent2)); eventTree_addSiblingUnaryEvent(eventTree2, unaryEvent4); Event *unaryEvent42 = eventTree_getEvent(eventTree2, event_getName(unaryEvent4)); CuAssertTrue(testCase, unaryEvent42 != NULL); CuAssertTrue(testCase, event_getName(event_getParent(unaryEvent42)) == event_getName(internalEvent)); CuAssertTrue(testCase, event_getChildNumber(unaryEvent42) == 1); CuAssertTrue(testCase, event_getName(event_getChild(unaryEvent42, 0)) == event_getName(unaryEvent3)); eventTree_addSiblingUnaryEvent(eventTree2, unaryEvent5); Event *unaryEvent52 = eventTree_getEvent(eventTree2, event_getName(unaryEvent5)); CuAssertTrue(testCase, unaryEvent52 != NULL); CuAssertTrue(testCase, event_getName(event_getParent(unaryEvent52)) == event_getName(internalEvent)); CuAssertTrue(testCase, event_getChildNumber(unaryEvent52) == 1); CuAssertTrue(testCase, event_getName(event_getChild(unaryEvent52, 0)) == event_getName(unaryEvent4)); //uglyf("Event-tree-1 %s\n", eventTree_makeNewickString(eventTree)); //uglyf("Event-tree-2 %s\n", eventTree_makeNewickString(eventTree3)); //uglyf("Event-tree-3 %s\n", eventTree_makeNewickString(eventTree2)); cactusEventTreeTestTeardown(); }
int main(int argc, char *argv[]) { /* * Open the database. * Construct a flower. * Construct an event tree representing the species tree. * For each sequence contruct two ends each containing an cap. * Make a file for the sequence. * Link the two caps. * Finish! */ int64_t key, j; Group *group; Flower_EndIterator *endIterator; End *end; bool makeEventHeadersAlphaNumeric = 0; /* * Arguments/options */ char * logLevelString = NULL; char * speciesTree = NULL; char * outgroupEvents = NULL; /////////////////////////////////////////////////////////////////////////// // (0) Parse the inputs handed by genomeCactus.py / setup stuff. /////////////////////////////////////////////////////////////////////////// while (1) { static struct option long_options[] = { { "logLevel", required_argument, 0, 'a' }, { "cactusDisk", required_argument, 0, 'b' }, { "speciesTree", required_argument, 0, 'f' }, { "outgroupEvents", required_argument, 0, 'g' }, { "help", no_argument, 0, 'h' }, { "makeEventHeadersAlphaNumeric", no_argument, 0, 'i' }, { 0, 0, 0, 0 } }; int option_index = 0; key = getopt_long(argc, argv, "a:b:f:hg:i", long_options, &option_index); if (key == -1) { break; } switch (key) { case 'a': logLevelString = optarg; break; case 'b': cactusDiskDatabaseString = optarg; break; case 'f': speciesTree = optarg; break; case 'g': outgroupEvents = optarg; break; case 'h': usage(); return 0; case 'i': makeEventHeadersAlphaNumeric = 1; break; default: usage(); return 1; } } /////////////////////////////////////////////////////////////////////////// // (0) Check the inputs. /////////////////////////////////////////////////////////////////////////// //assert(logLevelString == NULL || strcmp(logLevelString, "CRITICAL") == 0 || strcmp(logLevelString, "INFO") == 0 || strcmp(logLevelString, "DEBUG") == 0); assert(cactusDiskDatabaseString != NULL); assert(speciesTree != NULL); ////////////////////////////////////////////// //Set up logging ////////////////////////////////////////////// st_setLogLevelFromString(logLevelString); ////////////////////////////////////////////// //Log (some of) the inputs ////////////////////////////////////////////// st_logInfo("Flower disk name : %s\n", cactusDiskDatabaseString); for (j = optind; j < argc; j++) { st_logInfo("Sequence file/directory %s\n", argv[j]); } ////////////////////////////////////////////// //Load the database ////////////////////////////////////////////// stKVDatabaseConf *kvDatabaseConf = kvDatabaseConf = stKVDatabaseConf_constructFromString(cactusDiskDatabaseString); if (stKVDatabaseConf_getType(kvDatabaseConf) == stKVDatabaseTypeTokyoCabinet || stKVDatabaseConf_getType(kvDatabaseConf) == stKVDatabaseTypeKyotoTycoon) { assert(stKVDatabaseConf_getDir(kvDatabaseConf) != NULL); cactusDisk = cactusDisk_construct2(kvDatabaseConf, "cactusSequences"); } else { cactusDisk = cactusDisk_construct(kvDatabaseConf, 1); } st_logInfo("Set up the flower disk\n"); ////////////////////////////////////////////// //Construct the flower ////////////////////////////////////////////// if (cactusDisk_getFlower(cactusDisk, 0) != NULL) { cactusDisk_destruct(cactusDisk); st_logInfo("The first flower already exists\n"); return 0; } flower = flower_construct2(0, cactusDisk); assert(flower_getName(flower) == 0); st_logInfo("Constructed the flower\n"); ////////////////////////////////////////////// //Construct the event tree ////////////////////////////////////////////// st_logInfo("Going to build the event tree with newick string: %s\n", speciesTree); stTree *tree = stTree_parseNewickString(speciesTree); st_logInfo("Parsed the tree\n"); if (makeEventHeadersAlphaNumeric) { makeEventHeadersAlphaNumericFn(tree); } stTree_setBranchLength(tree, INT64_MAX); checkBranchLengthsAreDefined(tree); eventTree = eventTree_construct2(flower); //creates the event tree and the root even totalEventNumber = 1; st_logInfo("Constructed the basic event tree\n"); // Construct a set of outgroup names so that ancestral outgroups // get recognized. stSet *outgroupNameSet = stSet_construct3(stHash_stringKey, stHash_stringEqualKey, free); if(outgroupEvents != NULL) { stList *outgroupNames = stString_split(outgroupEvents); for(int64_t i = 0; i < stList_length(outgroupNames); i++) { char *outgroupName = stList_get(outgroupNames, i); stSet_insert(outgroupNameSet, stString_copy(outgroupName)); } stList_destruct(outgroupNames); } //now traverse the tree j = optind; assignEventsAndSequences(eventTree_getRootEvent(eventTree), tree, outgroupNameSet, argv, &j); char *eventTreeString = eventTree_makeNewickString(eventTree); st_logInfo( "Constructed the initial flower with %" PRIi64 " sequences and %" PRIi64 " events with string: %s\n", totalSequenceNumber, totalEventNumber, eventTreeString); assert(event_getSubTreeBranchLength(eventTree_getRootEvent(eventTree)) >= 0.0); free(eventTreeString); //assert(0); ////////////////////////////////////////////// //Label any outgroup events. ////////////////////////////////////////////// if (outgroupEvents != NULL) { stList *outgroupEventsList = stString_split(outgroupEvents); for (int64_t i = 0; i < stList_length(outgroupEventsList); i++) { char *outgroupEvent = makeEventHeadersAlphaNumeric ? makeAlphaNumeric(stList_get(outgroupEventsList, i)) : stString_copy(stList_get(outgroupEventsList, i)); Event *event = eventTree_getEventByHeader(eventTree, outgroupEvent); if (event == NULL) { st_errAbort("Got an outgroup string that does not match an event, outgroup string %s", outgroupEvent); } assert(!event_isOutgroup(event)); event_setOutgroupStatus(event, 1); assert(event_isOutgroup(event)); free(outgroupEvent); } stList_destruct(outgroupEventsList); } ////////////////////////////////////////////// //Construct the terminal group. ////////////////////////////////////////////// if (flower_getEndNumber(flower) > 0) { group = group_construct2(flower); endIterator = flower_getEndIterator(flower); while ((end = flower_getNextEnd(endIterator)) != NULL) { end_setGroup(end, group); } flower_destructEndIterator(endIterator); assert(group_isLeaf(group)); // Create a one link chain if there is only one pair of attached ends.. group_constructChainForLink(group); assert(!flower_builtBlocks(flower)); } else { flower_setBuiltBlocks(flower, 1); } /////////////////////////////////////////////////////////////////////////// // Write the flower to disk. /////////////////////////////////////////////////////////////////////////// //flower_check(flower); cactusDisk_write(cactusDisk); st_logInfo("Updated the flower on disk\n"); /////////////////////////////////////////////////////////////////////////// // Cleanup. /////////////////////////////////////////////////////////////////////////// cactusDisk_destruct(cactusDisk); return 0; //Exit without clean up is quicker, enable cleanup when doing memory leak detection. stSet_destruct(outgroupNameSet); stTree_destruct(tree); stKVDatabaseConf_destruct(kvDatabaseConf); return 0; }
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(); }