<commit_before>///////////////////////////////////////////////////////////////////////////////
//                   SOFTWARE COPYRIGHT NOTICE AGREEMENT                     //
//       This software and its documentation are copyright (2016) by the     //
//  Earlham Institute.  All rights are reserved.  This software is supplied  //
//   without any warranty or guaranteed support whatsoever. The Earlham      //
//   Institute is not responsible for its use, misuse, or functionality.     //
///////////////////////////////////////////////////////////////////////////////
/*
 * HBVFromEdges.cc
 *
 *  Created on: Sept 26, 2016
 *      Author: bjclavijo/kebarr
 */

#include "paths/long/HBVFromEdges.h"
#include "dna/CanonicalForm.h"
#include "paths/KmerPathInterval.h"
#include "system/ID.h"
#include <list>



class EdgeEnd{
public:
    std::string seq;
    bool distal,rc;
    uint64_t edge_index;
    EdgeEnd(const uint64_t _edge_index, const bvec & bvseq,const bool &_rc,const bool &_distal, const unsigned K) {//K is the HBV's k, overlaps are k-1
        edge_index=_edge_index;
        distal=_distal;
        rc=_rc;
        auto b=bvseq;
        if (rc) seq=b.ReverseComplement().ToString();
        seq=b.ToString();
        if (_distal)
            seq=seq.substr(seq.length()-K+1,seq.length());
        else
            seq.resize(K-1);
    };
    bool operator<(const EdgeEnd & other){return seq<other.seq;};//WARNING, for simplicity
    bool operator==(const EdgeEnd & other){return seq==other.seq;};//WARNING, for simplicity

};

typedef struct {
    uint64_t fw_v1,fw_v2,rc_v1,rc_v2;
} edge_vertex_list;


void buildHBVFromEdges( vecbvec const& edges, unsigned K, HyperBasevector* pHBV,
                            vec<int>* pFwdEdgeXlat, vec<int>* pRevEdgeXlat )
{
    pHBV->Clear();
    pFwdEdgeXlat->clear();
    pRevEdgeXlat->clear();
    if ( edges.empty() )
    {
        return;
    }

    std::vector<EdgeEnd> ends;
    ends.reserve(2*edges.size());

    for (uint64_t i=0;i<edges.size();++i){
        ends.push_back(EdgeEnd(i,edges[i],false,false,K));
        ends.push_back(EdgeEnd(i,edges[i],false,true,K));
        if ( edges[i].getCanonicalForm() != CanonicalForm::PALINDROME ) {
            ends.push_back(EdgeEnd(i,edges[i],true,false,K));
            ends.push_back(EdgeEnd(i,edges[i],true,true,K));
        }
    }
    std::sort(ends.begin(),ends.end());

    //number the vertices and fill a list of vertex numbers for the edges
    std::vector<edge_vertex_list> edge_vertices;
    edge_vertices.resize(edges.size());
    uint64_t vID=0;
    //Can't be parallel, because vID depends on previous iteration
    for (auto i=0; i<ends.size(); ++i){
        if (i>0 and not (ends[i-1]==ends[i])) vID++;
        if (!ends[i].rc) {
            if (!ends[i].distal) edge_vertices[ends[i].edge_index].fw_v1=vID;
            else edge_vertices[ends[i].edge_index].fw_v2=vID;
        } else {
            if (!ends[i].distal) edge_vertices[ends[i].edge_index].rc_v1=vID;
            else edge_vertices[ends[i].edge_index].rc_v2=vID;
        }
    }
    ++vID;

    pHBV->SetK(K);
    pHBV->AddVertices(vID);
    pHBV->EdgesMutable().reserve(2*edges.size());

    pFwdEdgeXlat->resize(edges.size(),-1);
    pRevEdgeXlat->resize(edges.size(),-1);

    //Now add the edges, and their rcs to the graph, this probably shouldn't be parallel neither (data corruption)
    for (uint64_t i=0;i<edges.size();++i){
        auto fwEdgeId = pHBV->EdgeObjectCount();
        pHBV->AddEdge(edge_vertices[i].fw_v1,edge_vertices[i].fw_v2,edges[i]);
        (*pFwdEdgeXlat)[i]=fwEdgeId;
        if ( edges[i].getCanonicalForm() != CanonicalForm::PALINDROME ) {
            auto bwEdgeId = pHBV->EdgeObjectCount();
            auto rcedge=edges[i];
            rcedge.ReverseComplement();
            pHBV->AddEdge(edge_vertices[i].rc_v1, edge_vertices[i].rc_v2, rcedge);
            (*pRevEdgeXlat)[i] = bwEdgeId;
        }
    }
}


void buildHKPFromHBV( HyperBasevector const& hbv,
                        vec<int> const& fwdEdgeXlat,
                        vec<int> const& revEdgeXlat,
                        HyperKmerPath* pHKP )
{
    unsigned K = hbv.K();<commit_msg>Fixed translation for palindrome edges on HBVFromEdges<commit_after>///////////////////////////////////////////////////////////////////////////////
//                   SOFTWARE COPYRIGHT NOTICE AGREEMENT                     //
//       This software and its documentation are copyright (2016) by the     //
//  Earlham Institute.  All rights are reserved.  This software is supplied  //
//   without any warranty or guaranteed support whatsoever. The Earlham      //
//   Institute is not responsible for its use, misuse, or functionality.     //
///////////////////////////////////////////////////////////////////////////////
/*
 * HBVFromEdges.cc
 *
 *  Created on: Sept 26, 2016
 *      Author: bjclavijo/kebarr
 */

#include "paths/long/HBVFromEdges.h"
#include "dna/CanonicalForm.h"
#include "paths/KmerPathInterval.h"
#include "system/ID.h"
#include <list>



class EdgeEnd{
public:
    std::string seq;
    bool distal,rc;
    uint64_t edge_index;
    EdgeEnd(const uint64_t _edge_index, const bvec & bvseq,const bool &_rc,const bool &_distal, const unsigned K) {//K is the HBV's k, overlaps are k-1
        edge_index=_edge_index;
        distal=_distal;
        rc=_rc;
        auto b=bvseq;
        if (rc) seq=b.ReverseComplement().ToString();
        seq=b.ToString();
        if (_distal)
            seq=seq.substr(seq.length()-K+1,seq.length());
        else
            seq.resize(K-1);
    };
    bool operator<(const EdgeEnd & other){return seq<other.seq;};//WARNING, for simplicity
    bool operator==(const EdgeEnd & other){return seq==other.seq;};//WARNING, for simplicity

};

typedef struct {
    uint64_t fw_v1,fw_v2,rc_v1,rc_v2;
} edge_vertex_list;


void buildHBVFromEdges( vecbvec const& edges, unsigned K, HyperBasevector* pHBV,
                            vec<int>* pFwdEdgeXlat, vec<int>* pRevEdgeXlat )
{
    pHBV->Clear();
    pFwdEdgeXlat->clear();
    pRevEdgeXlat->clear();
    if ( edges.empty() )
    {
        return;
    }

    std::vector<EdgeEnd> ends;
    ends.reserve(2*edges.size());

    for (uint64_t i=0;i<edges.size();++i){
        ends.push_back(EdgeEnd(i,edges[i],false,false,K));
        ends.push_back(EdgeEnd(i,edges[i],false,true,K));
        if ( edges[i].getCanonicalForm() != CanonicalForm::PALINDROME ) {
            ends.push_back(EdgeEnd(i,edges[i],true,false,K));
            ends.push_back(EdgeEnd(i,edges[i],true,true,K));
        }
    }
    std::sort(ends.begin(),ends.end());

    //number the vertices and fill a list of vertex numbers for the edges
    std::vector<edge_vertex_list> edge_vertices;
    edge_vertices.resize(edges.size());
    uint64_t vID=0;
    //Can't be parallel, because vID depends on previous iteration
    for (auto i=0; i<ends.size(); ++i){
        if (i>0 and not (ends[i-1]==ends[i])) vID++;
        if (!ends[i].rc) {
            if (!ends[i].distal) edge_vertices[ends[i].edge_index].fw_v1=vID;
            else edge_vertices[ends[i].edge_index].fw_v2=vID;
        } else {
            if (!ends[i].distal) edge_vertices[ends[i].edge_index].rc_v1=vID;
            else edge_vertices[ends[i].edge_index].rc_v2=vID;
        }
    }
    ++vID;

    pHBV->SetK(K);
    pHBV->AddVertices(vID);
    pHBV->EdgesMutable().reserve(2*edges.size());

    pFwdEdgeXlat->resize(edges.size(),-1);
    pRevEdgeXlat->resize(edges.size(),-1);

    //Now add the edges, and their rcs to the graph, this probably shouldn't be parallel neither (data corruption)
    for (uint64_t i=0;i<edges.size();++i){
        auto fwEdgeId = pHBV->EdgeObjectCount();
        pHBV->AddEdge(edge_vertices[i].fw_v1,edge_vertices[i].fw_v2,edges[i]);
        (*pFwdEdgeXlat)[i]=fwEdgeId;
        if ( edges[i].getCanonicalForm() != CanonicalForm::PALINDROME ) {
            auto bwEdgeId = pHBV->EdgeObjectCount();
            auto rcedge=edges[i];
            rcedge.ReverseComplement();
            pHBV->AddEdge(edge_vertices[i].rc_v1, edge_vertices[i].rc_v2, rcedge);
            (*pRevEdgeXlat)[i] = bwEdgeId;
        } else {
            (*pRevEdgeXlat)[i] = fwEdgeId;
        }
    }
}


void buildHKPFromHBV( HyperBasevector const& hbv,
                        vec<int> const& fwdEdgeXlat,
                        vec<int> const& revEdgeXlat,
                        HyperKmerPath* pHKP )
{
    unsigned K = hbv.K();
{'fraction_non_alphanumeric': 0.17377436503248672, 'fraction_numerical': 0.011104548139397518, 'mean_word_length': 2.3083235638921455, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1339257', 'n_tokens_mistral': 2966, 'n_tokens_neox': 2821, 'n_words': 550}