void makeCactusTree_terminalNode(Flower *flower, FILE *fileHandle,
        const char *parentNodeName, const char *parentEdgeColour) {
    char *groupNameString = cactusMisc_nameToString(flower_getName(flower));
    double scalingFactor = flower_getTotalBaseLength(flower) / totalProblemSize;
    assert(scalingFactor <= 1.001);
    assert(scalingFactor >= -0.001);
    addNodeToGraph(groupNameString, fileHandle, scalingFactor, "triangle",
            groupNameString);
    //Write in the parent edge.
    if (parentNodeName != NULL) {
        graphViz_addEdgeToGraph(parentNodeName, groupNameString, fileHandle,
                "", parentEdgeColour, 10, 1, "forward");
    }
    free(groupNameString);
}
Exemple #2
0
int main(int argc, char *argv[]) {
    st_setLogLevelFromString(argv[1]);
    st_logDebug("Set up logging\n");

    stKVDatabaseConf *kvDatabaseConf = stKVDatabaseConf_constructFromString(argv[2]);
    CactusDisk *cactusDisk = cactusDisk_construct(kvDatabaseConf, 0);
    stKVDatabaseConf_destruct(kvDatabaseConf);
    st_logDebug("Set up the flower disk\n");

    Name flowerName = cactusMisc_stringToName(argv[3]);
    Flower *flower = cactusDisk_getFlower(cactusDisk, flowerName);

    int64_t totalBases = flower_getTotalBaseLength(flower);
    int64_t totalEnds = flower_getEndNumber(flower);
    int64_t totalFreeEnds = flower_getFreeStubEndNumber(flower);
    int64_t totalAttachedEnds = flower_getAttachedStubEndNumber(flower);
    int64_t totalCaps = flower_getCapNumber(flower);
    int64_t totalBlocks = flower_getBlockNumber(flower);
    int64_t totalGroups = flower_getGroupNumber(flower);
    int64_t totalChains = flower_getChainNumber(flower);
    int64_t totalLinkGroups = 0;
    int64_t maxEndDegree = 0;
    int64_t maxAdjacencyLength = 0;
    int64_t totalEdges = 0;

    Flower_EndIterator *endIt = flower_getEndIterator(flower);
    End *end;
    while((end = flower_getNextEnd(endIt)) != NULL) {
        assert(end_getOrientation(end));
        if(end_getInstanceNumber(end) > maxEndDegree) {
            maxEndDegree = end_getInstanceNumber(end);
        }
        stSortedSet *ends = stSortedSet_construct();
        End_InstanceIterator *capIt = end_getInstanceIterator(end);
        Cap *cap;
        while((cap = end_getNext(capIt)) != NULL) {
            if(cap_getSequence(cap) != NULL) {
                Cap *adjacentCap = cap_getAdjacency(cap);
                assert(adjacentCap != NULL);
                End *adjacentEnd = end_getPositiveOrientation(cap_getEnd(adjacentCap));
                stSortedSet_insert(ends, adjacentEnd);
                int64_t adjacencyLength = cap_getCoordinate(cap) - cap_getCoordinate(adjacentCap);
                if(adjacencyLength < 0) {
                    adjacencyLength *= -1;
                }
                assert(adjacencyLength >= 1);
                if(adjacencyLength >= maxAdjacencyLength) {
                    maxAdjacencyLength = adjacencyLength;
                }
            }
        }
        end_destructInstanceIterator(capIt);
        totalEdges += stSortedSet_size(ends);
        if(stSortedSet_search(ends, end) != NULL) { //This ensures we count self edges twice, so that the division works.
            totalEdges += 1;
        }
        stSortedSet_destruct(ends);
    }
    assert(totalEdges % 2 == 0);
    flower_destructEndIterator(endIt);

    Flower_GroupIterator *groupIt = flower_getGroupIterator(flower);
    Group *group;
    while((group = flower_getNextGroup(groupIt)) != NULL) {
        if(group_getLink(group) != NULL) {
            totalLinkGroups++;
        }
    }
    flower_destructGroupIterator(groupIt);

    printf("flower name: %" PRIi64 " total bases: %" PRIi64 " total-ends: %" PRIi64 " total-caps: %" PRIi64 " max-end-degree: %" PRIi64 " max-adjacency-length: %" PRIi64 " total-blocks: %" PRIi64 " total-groups: %" PRIi64 " total-edges: %" PRIi64 " total-free-ends: %" PRIi64 " total-attached-ends: %" PRIi64 " total-chains: %" PRIi64 " total-link groups: %" PRIi64 "\n",
            flower_getName(flower), totalBases, totalEnds, totalCaps, maxEndDegree, maxAdjacencyLength, totalBlocks, totalGroups, totalEdges/2, totalFreeEnds, totalAttachedEnds, totalChains, totalLinkGroups);

    return 0;
}
int main(int argc, char *argv[]) {
    Flower *flower;
    FILE *fileHandle;

    /*
     * Arguments/options
     */
    char * logLevelString = NULL;
    char * cactusDiskDatabaseString = NULL;
    char * flowerName = NULL;
    char * outputFile = 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,
                'c' }, { "flowerName", required_argument, 0, 'd' }, {
                "outputFile", required_argument, 0, 'e' }, { "scaleNodeSizes",
                no_argument, 0, 'f' }, { "nameLabels", no_argument, 0, 'g' }, {
                "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 } };

        int option_index = 0;

        int key = getopt_long(argc, argv, "a:c:d:e:fgh", long_options,
                &option_index);

        if (key == -1) {
            break;
        }

        switch (key) {
            case 'a':
                logLevelString = stString_copy(optarg);
                break;
            case 'c':
                cactusDiskDatabaseString = stString_copy(optarg);
                break;
            case 'd':
                flowerName = stString_copy(optarg);
                break;
            case 'e':
                outputFile = stString_copy(optarg);
                break;
            case 'f':
                scaleNodeSizes = !scaleNodeSizes;
                break;
            case 'g':
                nameLabels = !nameLabels;
                break;
            case 'h':
                usage();
                return 0;
            default:
                usage();
                return 1;
        }
    }

    ///////////////////////////////////////////////////////////////////////////
    // (0) Check the inputs.
    ///////////////////////////////////////////////////////////////////////////

    assert(cactusDiskDatabaseString != NULL);
    assert(flowerName != NULL);
    assert(outputFile != NULL);

    //////////////////////////////////////////////
    //Set up logging
    //////////////////////////////////////////////

    st_setLogLevelFromString(logLevelString);

    //////////////////////////////////////////////
    //Log (some of) the inputs
    //////////////////////////////////////////////

    st_logInfo("Flower name : %s\n", flowerName);
    st_logInfo("Output graph file : %s\n", outputFile);

    //////////////////////////////////////////////
    //Load the database
    //////////////////////////////////////////////

    stKVDatabaseConf *kvDatabaseConf = stKVDatabaseConf_constructFromString(cactusDiskDatabaseString);
    CactusDisk *cactusDisk = cactusDisk_construct(kvDatabaseConf, 0);
    st_logInfo("Set up the flower disk\n");

    ///////////////////////////////////////////////////////////////////////////
    // Parse the basic reconstruction problem
    ///////////////////////////////////////////////////////////////////////////

    flower = cactusDisk_getFlower(cactusDisk, cactusMisc_stringToName(flowerName));
    st_logInfo("Parsed the top level flower of the cactus tree to build\n");

    ///////////////////////////////////////////////////////////////////////////
    // Build the graph.
    ///////////////////////////////////////////////////////////////////////////

    totalProblemSize = flower_getTotalBaseLength(flower);
    fileHandle = fopen(outputFile, "w");
    graphViz_setupGraphFile(fileHandle);
    makeCactusTree_flower(flower, fileHandle, NULL, NULL);
    graphViz_finishGraphFile(fileHandle);
    fclose(fileHandle);
    st_logInfo("Written the tree to file\n");

    ///////////////////////////////////////////////////////////////////////////
    // Clean up.
    ///////////////////////////////////////////////////////////////////////////

    cactusDisk_destruct(cactusDisk);
    stKVDatabaseConf_destruct(kvDatabaseConf);

    return 0;
}
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);
    }
}