src/c++/lib/grm/GraphInput.cpp
/**
 * Initialize graph from JSON
 * @param in Input JSON node
 * @param reference reference fasta name
 * @param out Output graph to initialize
 */
Initialize graph from JSON
@param in Input JSON node
@param reference reference fasta name
@param out Output graph to initialize
Initialize graph from JSON @param in Input JSON node @param reference reference fasta name @param out Output graph to initialize
Graph graphFromJson(Json::Value const& in, string const& reference, bool store_ref_sequence)
{
    common::FastaFile ref(reference);
    Json::Value const* in_graph = &in;
    if (in.isMember("graph"))
    {
        in_graph = &in["graph"];
    }
    assert((*in_graph)["nodes"].type() == Json::ValueType::arrayValue);
    Graph result{ (*in_graph)["nodes"].size(), false };
    if ((*in_graph)["edges"].type() != Json::ValueType::nullValue)
    {
        assert((*in_graph)["edges"].type() == Json::ValueType::arrayValue);
    }
    std::map<string, NodeId> node_map;
    for (NodeId i = 0; i < (*in_graph)["nodes"].size(); ++i)
    {
        auto const& in_n = (*in_graph)["nodes"][(int)i];
        const string name = in_n.isMember("name") ? in_n["name"].asString() : string("node-") + std::to_string(i + 1);
        assert(!node_map.count(name));
        node_map[name] = i;
        result.setNodeName(i, name);
        string uc_name = name;
        common::stringutil::toUpper(uc_name);
        const bool is_source_or_sink
            = (i == 0 || i == (*in_graph)["nodes"].size() - 1) && (uc_name == "SOURCE" || uc_name == "SINK");
        assert(in_n.isMember("sequence") || in_n.isMember("reference") || is_source_or_sink);
        if (is_source_or_sink)
        {
            result.setNodeSeq(i, "X");
        }
        else if (in_n.isMember("sequence"))
        {
            result.setNodeSeq(i, in_n["sequence"].asString());
        }
        else
        {
            string reference_sequence;
            if (in_n["reference"].type() == Json::ValueType::stringValue)
            {
                const string reference_location = in_n["reference"].asString();
                reference_sequence = ref.query(reference_location);
            }
            else
            {
                assert(in_n["reference"].type() == Json::ValueType::arrayValue);
                for (const auto& ref_inst : in_n["reference"])
                {
                    assert(ref_inst.type() == Json::ValueType::stringValue);
                    const string reference_location = ref_inst.asString();
                    const string curr_seq(ref.query(reference_location));
                    if (!reference_sequence.empty())
                    {
                        assert(reference_sequence == curr_seq);
                    }
                    reference_sequence = curr_seq;
                }
            }
            if (store_ref_sequence)
            {
                assert(!reference_sequence.empty());
                result.setNodeSeq(i, reference_sequence);
            }
        }
    }
    for (size_t i = 0; i < (*in_graph)["edges"].size(); ++i)
    {
        auto const& in_e = (*in_graph)["edges"][(int)i];
        assert(node_map.count(in_e["from"].asString()));
        assert(node_map.count(in_e["to"].asString()));
        const auto from_node = node_map[in_e["from"].asString()];
        const auto to_node = node_map[in_e["to"].asString()];
        result.addEdge(from_node, to_node);
        for (auto& sequence : in_e["sequences"])
        {
            result.addLabelToEdge(from_node, to_node, sequence.asString());
        }
    }
    for (NodeId i = 0; i < (*in_graph)["nodes"].size(); ++i)
    {
        auto const& in_n = (*in_graph)["nodes"][(int)i];
        for (auto& sequence : in_n["sequences"])
        {
            for (auto h : result.predecessors(i))
            {
                result.addLabelToEdge(h, i, sequence.asString());
            }
            for (auto j : result.successors(i))
            {
                result.addLabelToEdge(i, j, sequence.asString());
            }
        }
    }
    return result;
}
Graph graphFromJson ( Json :: Value const & in , string const & reference , bool store_ref_sequence ) { common :: FastaFile ref ( reference ) ; Json :: Value const * in_graph = & in ; if ( in . isMember ( " " ) ) { in_graph = & in [ " " ] ; } assert ( ( * in_graph ) [ " " ] . type ( ) == Json :: ValueType :: arrayValue ) ; Graph result { ( * in_graph ) [ " " ] . size ( ) , false } ; if ( ( * in_graph ) [ " " ] . type ( ) != Json :: ValueType :: nullValue ) { assert ( ( * in_graph ) [ " " ] . type ( ) == Json :: ValueType :: arrayValue ) ; } std :: map < string , NodeId > node_map ; for ( NodeId i = 0 ; i < ( * in_graph ) [ " " ] . size ( ) ; ++ i ) { auto const & in_n = ( * in_graph ) [ " " ] [ ( int ) i ] ; const string name = in_n . isMember ( " " ) ? in_n [ " " ] . asString ( ) : string ( " " ) + std :: to_string ( i + 1 ) ; assert ( ! node_map . count ( name ) ) ; node_map [ name ] = i ; result . setNodeName ( i , name ) ; string uc_name = name ; common :: stringutil :: toUpper ( uc_name ) ; const bool is_source_or_sink = ( i == 0 || i == ( * in_graph ) [ " " ] . size ( ) - 1 ) && ( uc_name == " " || uc_name == " " ) ; assert ( in_n . isMember ( " " ) || in_n . isMember ( " " ) || is_source_or_sink ) ; if ( is_source_or_sink ) { result . setNodeSeq ( i , " " ) ; } else if ( in_n . isMember ( " " ) ) { result . setNodeSeq ( i , in_n [ " " ] . asString ( ) ) ; } else { string reference_sequence ; if ( in_n [ " " ] . type ( ) == Json :: ValueType :: stringValue ) { const string reference_location = in_n [ " " ] . asString ( ) ; reference_sequence = ref . query ( reference_location ) ; } else { assert ( in_n [ " " ] . type ( ) == Json :: ValueType :: arrayValue ) ; for ( const auto & ref_inst : in_n [ " " ] ) { assert ( ref_inst . type ( ) == Json :: ValueType :: stringValue ) ; const string reference_location = ref_inst . asString ( ) ; const string curr_seq ( ref . query ( reference_location ) ) ; if ( ! reference_sequence . empty ( ) ) { assert ( reference_sequence == curr_seq ) ; } reference_sequence = curr_seq ; } } if ( store_ref_sequence ) { assert ( ! reference_sequence . empty ( ) ) ; result . setNodeSeq ( i , reference_sequence ) ; } } } for ( size_t i = 0 ; i < ( * in_graph ) [ " " ] . size ( ) ; ++ i ) { auto const & in_e = ( * in_graph ) [ " " ] [ ( int ) i ] ; assert ( node_map . count ( in_e [ " " ] . asString ( ) ) ) ; assert ( node_map . count ( in_e [ " " ] . asString ( ) ) ) ; const auto from_node = node_map [ in_e [ " " ] . asString ( ) ] ; const auto to_node = node_map [ in_e [ " " ] . asString ( ) ] ; result . addEdge ( from_node , to_node ) ; for ( auto & sequence : in_e [ " " ] ) { result . addLabelToEdge ( from_node , to_node , sequence . asString ( ) ) ; } } for ( NodeId i = 0 ; i < ( * in_graph ) [ " " ] . size ( ) ; ++ i ) { auto const & in_n = ( * in_graph ) [ " " ] [ ( int ) i ] ; for ( auto & sequence : in_n [ " " ] ) { for ( auto h : result . predecessors ( i ) ) { result . addLabelToEdge ( h , i , sequence . asString ( ) ) ; } for ( auto j : result . successors ( i ) ) { result . addLabelToEdge ( i , j , sequence . asString ( ) ) ; } } } return result ; }
Initialize graph from JSON
 @param in Input JSON node
 @param reference reference fasta name
 @param out Output graph to initialize
Initialize graph from JSON @param in Input JSON node @param reference reference fasta name @param out Output graph to initialize
// Node label shortcut: add label to all in and out edges