final DP-based assembly

This commit is contained in:
Haoyu Cheng
2019-11-13 20:18:11 -05:00
parent d6c6a1fa11
commit ada03ea388
22 changed files with 19432 additions and 1178 deletions
+10 -1
View File
@@ -16,6 +16,15 @@
"string": "cpp",
"array": "cpp",
"utility": "cpp",
"cmath": "cpp"
"cmath": "cpp",
"unordered_map": "cpp",
"system_error": "cpp",
"set": "cpp",
"sstream": "cpp",
"istream": "cpp",
"ostream": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"typeinfo": "cpp"
}
}
+1444 -405
View File
File diff suppressed because it is too large Load Diff
+19 -2
View File
@@ -9,6 +9,7 @@ char* read_file_name = NULL;
char* output_file_name = NULL;
int thread_num = 1;
int k_mer_length = 40;
int coverage = -1;
//int k_mer_min_freq = 9;
int k_mer_min_freq = 3;
//int k_mer_min_freq = 2;
@@ -16,7 +17,10 @@ int k_mer_max_freq = 66;
int load_index_from_disk = 0;
int write_index_to_disk = 0;
int number_of_round = 1;
int read_graph = 0;
int c_round = 4;
int adapterLen = 0;
char* required_read_name = NULL;
double Get_T(void)
{
@@ -28,6 +32,8 @@ double Get_T(void)
void Print_H()
{
fprintf(stderr, "Incorrect options.\n");
fprintf(stderr, "./ccs_assembly -w -l -q NA12878_chr1_10M.fq -o output_NA12878_v11_2.fa -c 31 -k 40 -t 32 -r 2 -a 4 -z 0\n");
}
@@ -50,7 +56,7 @@ int CommandLine_process (int argc, char *argv[])
ketopt_t opt = KETOPT_INIT;
int i, c;
while ((c = ketopt(&opt, argc, argv, 1, "ht:o:q:k:lwm:n:r:", longopts)) >= 0) {
while ((c = ketopt(&opt, argc, argv, 1, "ht:o:q:k:lwm:n:r:c:a:b:z:", longopts)) >= 0) {
if (c == 100 || c == 'h') Print_H();
else if (c == 103 || c == 't') thread_num = atoi(opt.arg);
else if (c == 102 || c == 'o') output_file_name = opt.arg;
@@ -61,6 +67,10 @@ int CommandLine_process (int argc, char *argv[])
else if (c == 'k') k_mer_length = atoi(opt.arg);
else if (c == 'l') load_index_from_disk = 1;
else if (c == 'w') write_index_to_disk = 1;
else if (c == 'c') coverage = atoi(opt.arg);
else if (c == 'a') c_round = atoi(opt.arg);
else if (c == 'z') adapterLen = atoi(opt.arg);
else if (c == 'b') required_read_name = opt.arg;
else if (c == '?') printf("unknown opt: -%c\n", opt.opt? opt.opt : ':');
else if (c == ':') printf("missing arg: -%c\n", opt.opt? opt.opt : ':');
}
@@ -72,6 +82,13 @@ int CommandLine_process (int argc, char *argv[])
return 0;
}
if(coverage == -1)
{
fprintf(stdout, "Please set -c!\n");
Print_H();
return 0;
}
return 1;
}
+6
View File
@@ -13,6 +13,12 @@ extern int k_mer_max_freq;
extern int load_index_from_disk;
extern int write_index_to_disk;
extern int number_of_round;
extern int roundID;
extern int coverage;
extern int read_graph;
extern int c_round;
extern char* required_read_name;
extern int adapterLen;
int CommandLine_process (int argc, char *argv[]);
+5589 -547
View File
File diff suppressed because it is too large Load Diff
+817 -32
View File
File diff suppressed because it is too large Load Diff
+1477 -63
View File
File diff suppressed because it is too large Load Diff
+127 -11
View File
@@ -17,23 +17,23 @@ typedef khash_t(POS64) Pos_Table;
///#define THRESHOLD 14
#define WINDOW 375
#define WINDOW_BOUNDARY 150
//#define WINDOW_BOUNDARY 150
#define WINDOW_BOUNDARY 375
///for one side, the first or last WINDOW_UNCORRECT_SINGLE_SIDE_BOUNDARY bases should not be corrected
#define WINDOW_UNCORRECT_SINGLE_SIDE_BOUNDARY 25
#define THRESHOLD 15
#define THRESHOLD_RATE 0.04
#define OVERLAP_THRESHOLD 0.9
#define TAIL_LENGTH int(1/THRESHOLD_RATE)
///#define OVERLAP_THRESHOLD 0.9
#define OVERLAP_THRESHOLD_FILTER 0.9
#define WINDOW_MAX_SIZE WINDOW + TAIL_LENGTH + 3
#define THRESHOLD_MAX_SIZE 31
/**
#define WINDOW 500
#define THRESHOLD 15
#define THRESHOLD_RATE 0.03
#define OVERLAP_THRESHOLD 0.95
**/
#define GROUP_SIZE 4
///最长是10M10D10M10D10M这种
#define CIGAR_MAX_LENGTH THRESHOLD*2+2
///#define CIGAR_MAX_LENGTH THRESHOLD*2+2
#define CIGAR_MAX_LENGTH 31*2+4
typedef struct
{
@@ -92,12 +92,21 @@ typedef struct
int y_start;
int extra_begin;
int extra_end;
int error_threshold;
///int y_pre_start;
///error小于等于0都要重新算
int error;
CIGAR cigar;
} window_list;
typedef struct
{
uint64_t* buffer;
uint64_t length;
uint64_t size;
}Fake_Cigar;
typedef struct
{
uint64_t x_id;
@@ -113,10 +122,15 @@ typedef struct
uint64_t shared_seed;
uint64_t align_length;
///uint64_t total_errors;
uint8_t is_match;
uint64_t non_homopolymer_errors;
window_list* w_list;
uint64_t w_list_size;
uint64_t w_list_length;
int8_t strong;
Fake_Cigar f_cigar;
} overlap_region;
@@ -125,6 +139,8 @@ typedef struct
overlap_region* list;
uint64_t size;
uint64_t length;
///uint64_t mapped_overlaps_length;
long long mapped_overlaps_length;
} overlap_region_alloc;
typedef struct
@@ -153,7 +169,15 @@ typedef struct
int MaxSize;
} HeapSq;
typedef struct
{
long long* score;
long long* pre;
long long* indels;
long long* self_length;
long long length;
long long size;
} Chain_Data;
typedef struct
{
@@ -163,6 +187,7 @@ typedef struct
long long size;
uint64_t foward_pos;
uint64_t rc_pos;
Chain_Data chainDP;
} Candidates_list;
typedef struct
@@ -206,6 +231,23 @@ inline uint64_t mod_d(uint64_t h_key, uint64_t low_key, uint64_t d)
return result;
}
inline int if_k_mer_available(Hash_code* code, int k)
{
uint64_t h_key, low_key;
///k有可能是64,所以可能会有问题
///low_key = code->x[0] | (code->x[1] << k);
low_key = code->x[0] | (code->x[1] << SAFE_SHIFT(k));
//k不可能为0, 所以这个右移不会有问题
h_key = code->x[1] >> (64 - k);
if(mod_d(h_key, low_key, MODE_VALUE) > 3)
{
return 0;
}
return 1;
}
///inline int get_sub_table(uint64_t* get_sub_ID, uint64_t* get_sub_key, Total_Count_Table* TCB, Hash_code* code, int k)
@@ -458,16 +500,84 @@ void append_overlap_region_alloc(overlap_region_alloc* list, overlap_region* tmp
void calculate_overlap_region(Candidates_list* candidates, overlap_region_alloc* overlap_list,
uint64_t readID, uint64_t readLength, All_reads* R_INF);
void append_window_list(overlap_region* region, uint64_t x_start, uint64_t x_end, int y_start, int y_end, int error,
int extra_begin, int extra_end);
int extra_begin, int extra_end, int error_threshold);
void insert_kv_list_to_candidates(k_v* list, long long occ, long long y_id, long long y_offset, long long y_strand,
Candidates_list* candidates);
void overlap_region_sort_y_id(overlap_region *a, long long n);
void calculate_inexact_overlap_region(Candidates_list* candidates, overlap_region_alloc* overlap_list,
uint64_t readID, uint64_t readLength, All_reads* R_INF);
void calculate_overlap_region_by_chaining(Candidates_list* candidates, overlap_region_alloc* overlap_list,
uint64_t readID, uint64_t readLength, All_reads* R_INF, double band_width_threshold);
static const char LogTable256[256] = {
#define LT(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
-1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
LT(4), LT(5), LT(5), LT(6), LT(6), LT(6), LT(6),
LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7)
};
static inline int ilog2_32(uint32_t v)
{
uint32_t t, tt;
if ((tt = v>>16)) return (t = tt>>8) ? 24 + LogTable256[t] : 16 + LogTable256[tt];
return (t = v>>8) ? 8 + LogTable256[t] : LogTable256[v];
}
void init_fake_cigar(Fake_Cigar* x);
void destory_fake_cigar(Fake_Cigar* x);
void clear_fake_cigar(Fake_Cigar* x);
void add_fake_cigar(Fake_Cigar* x, uint32_t gap_site, int32_t gap_shift);
void resize_fake_cigar(Fake_Cigar* x, long long size);
int get_fake_gap_pos(Fake_Cigar* x, int index);
int get_fake_gap_shift(Fake_Cigar* x, int index);
inline long long y_start_offset(long long x_start, Fake_Cigar* o)
{
if(x_start == get_fake_gap_pos(o, o->length - 1))
{
return get_fake_gap_shift(o, o->length - 1);
}
long long i;
for (i = 0; i < o->length; i++)
{
if(x_start < get_fake_gap_pos(o, i))
{
break;
}
}
if(i == 0 || i == o->length)
{
fprintf(stderr, "ERROR\n");
exit(0);
}
///note here return i - 1
return get_fake_gap_shift(o, i - 1);
}
inline void print_fake_gap(Fake_Cigar* o)
{
long long i;
for (i = 0; i < o->length; i++)
{
fprintf(stderr, "**i: %d, gap_pos_in_x: %d, gap_shift: %d\n",
i, get_fake_gap_pos(o, i),
get_fake_gap_shift(o, i));
}
}
@@ -585,4 +695,10 @@ void debug_mode(uint64_t d, uint64_t thread_ID, uint64_t thread_num);
/********************************for debug***************************************/
void merge_Candidates_list_version(Candidates_list* l, k_mer_pos* n_list, uint64_t n_lengh, uint64_t end_pos, int strand);
void sort_candidates(Candidates_list* candidates, long long readID,
overlap_region_alloc* overlap_list, All_reads* R_INF);
void append_overlap_region_alloc_from_existing(overlap_region_alloc* list, overlap_region* tmp, All_reads* R_INF);
int cmp_by_x_pos_s(const void * a, const void * b);
void resize_Chain_Data(Chain_Data* x, long long size);
#endif
+1 -1
View File
@@ -3,7 +3,7 @@ CC=g++
CFLAGS = -w -c -msse4.2 -mpopcnt -fomit-frame-pointer -Winline -O3 -lz
LDFLAGS = -lm -lz -lpthread -O3 -mpopcnt -msse4.2 -lz -w
SOURCES = main.cpp Output.cpp CommandLines.cpp Process_Read.cpp Assembly.cpp kmer.cpp Hash_Table.cpp POA.cpp Correct.cpp Levenshtein_distance.cpp edlib.cpp
SOURCES = main.cpp Output.cpp CommandLines.cpp Process_Read.cpp Assembly.cpp kmer.cpp Hash_Table.cpp POA.cpp Correct.cpp Levenshtein_distance.cpp edlib.cpp Overlaps.cpp
OBJECTS = $(SOURCES:.c=.o)
EXECUTABLE = ccs_assembly
+7709
View File
File diff suppressed because it is too large Load Diff
+322
View File
@@ -0,0 +1,322 @@
#ifndef __OVERLAPS__
#define __OVERLAPS__
#include <stdint.h>
#include "kvec.h"
#include "kdq.h"
///#include "Hash_Table.h"
///#define MIN_OVERLAP_LEN 2000
///#define MIN_OVERLAP_LEN 500
#define MIN_OVERLAP_LEN 50
#define MIN_OVERLAP_COVERAGE 1
#define MAX_HANG_LEN 1000
#define MAX_HANG_PRE 0.8
#define GAP_FUZZ 1000
#define MAX_SHORT_TIPS 3
#define MAX_BUBBLE_DIST 10000000
#define SMALL_BUBBLE_SIZE (uint32_t)-1
//#define SMALL_BUBBLE_SIZE 1000
#define Get_qn(RECORD) ((uint32_t)((RECORD).qns>>32))
#define Get_qs(RECORD) ((uint32_t)((RECORD).qns))
#define Get_qe(RECORD) ((RECORD).qe)
#define Get_tn(RECORD) ((RECORD).tn)
#define Get_ts(RECORD) ((RECORD).ts)
#define Get_te(RECORD) ((RECORD).te)
#define LONG_TIPS 0
#define TWO_INPUT 1
#define TWO_OUTPUT 2
#define MUL_INPUT 3
#define MUL_OUTPUT 4
#define END_TIPS 5
#define LONG_TIPS_UNDER_MAX_EXT 6
#define LOOP 7
///query is the read itself
typedef struct {
uint64_t qns;
uint32_t qe, tn, ts, te;
uint32_t ml:31, rev:1;
uint32_t bl:31, del:1;
uint8_t el;
} ma_hit_t;
typedef struct {
ma_hit_t* buffer;
uint32_t size;
uint32_t length;
uint8_t is_fully_corrected;
} ma_hit_t_alloc;
void init_ma_hit_t_alloc(ma_hit_t_alloc* x);
void clear_ma_hit_t_alloc(ma_hit_t_alloc* x);
void resize_ma_hit_t_alloc(ma_hit_t_alloc* x, uint64_t size);
void destory_ma_hit_t_alloc(ma_hit_t_alloc* x);
void add_ma_hit_t_alloc(ma_hit_t_alloc* x, ma_hit_t* element);
void ma_hit_sort_tn(ma_hit_t *a, long long n);
void ma_hit_sort_qns(ma_hit_t *a, long long n);
int load_all_data_from_disk(ma_hit_t_alloc **sources, ma_hit_t_alloc **reverse_sources,
char* output_file_name);
typedef struct {
ma_hit_t_alloc overlaps;
} Assembly_Graph;
void init_Assembly_Graph(Assembly_Graph* x);
void destory_Assembly_Graph(Assembly_Graph* x);
void collect_ma_hit_t(ma_hit_t_alloc* dest, ma_hit_t_alloc* sources, long long num_sources);
void normalize_ma_hit_t(ma_hit_t_alloc* sources, long long num_sources);
void debug_normalize_ma_hit_t(ma_hit_t_alloc* sources, long long num_sources);
typedef struct {
uint32_t s:31, del:1, e;
} ma_sub_t;
void ma_hit_sub(int min_dp, ma_hit_t_alloc* sources, long long n_read, uint64_t* readLen,
long long mini_overlap_length, ma_sub_t** coverage_cut);
void ma_hit_cut(int min_dp, ma_hit_t_alloc* sources, long long n_read, uint64_t* readLen,
long long mini_overlap_length, ma_sub_t** coverage_cut);
void ma_hit_flt(ma_hit_t_alloc* sources, long long n_read, const ma_sub_t *coverage_cut,
int max_hang, int min_ovlp);
long long get_specific_overlap(ma_hit_t_alloc* x, uint32_t qn, uint32_t tn);
void debug_cut_ma_hit_t(ma_hit_t_alloc* sources, long long num_sources, ma_sub_t *coverage_cut);
typedef struct {
uint64_t ul;
uint32_t v;
uint32_t ol:31, del:1;
uint8_t strong;
uint8_t el;
} asg_arc_t;
typedef struct {
uint32_t len:31, del:1;
} asg_seq_t;
typedef struct {
uint32_t m_arc, n_arc:31, is_srt:1;
asg_arc_t *arc;
uint32_t m_seq, n_seq:31, is_symm:1;
asg_seq_t *seq;
uint64_t *idx;
uint8_t* seq_vis;
} asg_t;
typedef struct { size_t n, m; uint64_t *a; } asg64_v;
#define MA_HT_INT (-1)
#define MA_HT_QCONT (-2)
#define MA_HT_TCONT (-3)
#define MA_HT_SHORT_OVLP (-4)
///in default, max_hang = 1000, int_frac = 0.05, min_ovlp = 2000
static inline int ma_hit2arc(const ma_hit_t *h, int ql, int tl, int max_hang, float int_frac, int min_ovlp, asg_arc_t *p)
{
int32_t tl5, tl3, ext5, ext3, qs = (int32_t)h->qns;
uint32_t u, v, l; // u: query end; v: target end; l: length from u to v
///if query and target are in different strand
if (h->rev) tl5 = tl - h->te, tl3 = h->ts; // tl5: 5'-end overhang (on the query strand); tl3: similar
else tl5 = h->ts, tl3 = tl - h->te;
///ext5 and ext3 is the hang on left side and right side, respectively
ext5 = qs < tl5? qs : tl5;
ext3 = ql - h->qe < tl3? ql - h->qe : tl3;
/**
if (ext5 > max_hang || ext3 > max_hang || h->qe - qs < (h->qe - qs + ext5 + ext3) * int_frac)
return MA_HT_INT;
**/
if (ext5 > max_hang || ext3 > max_hang
|| h->qe - qs < (h->qe - qs + ext5 + ext3) * int_frac
|| h->te - h->ts < (h->te - h->ts + ext5 + ext3) * int_frac)
{
return MA_HT_INT;
}
/**
********************************query-to-target overlap****************************
case 1: u = 0, rev = 0 in the view of target: direction is 1
query: CCCCCCCCTAATTAAAAT target: TAATTAAAATGGGGGG (use ex-target as query)
|||||||||| <---> ||||||||||
target: TAATTAAAATGGGGGG query: CCCCCCCCTAATTAAAAT (use ex-query as target)
case 2: u = 0, rev = 1 in the view of target: direction is 0
query: CCCCCCCCTAATTAAAAT target: CCCCCCATTTTAATTA (use ex-target as query)
|||||||||| <---> ||||||||||
target: TAATTAAAATGGGGGG query: ATTTTAATTAGGGGGGGG (use ex-query as target)
********************************query-to-target overlap****************************
********************************target-to-query overlap****************************
case 3: u = 1, rev = 0 in the view of target: direction is 0
query: AAATAATATCCCCCCGCG target: GGGCCGGCAAATAATAT (use ex-target as query)
||||||||| <---> |||||||||
target: GGGCCGGCAAATAATAT query: AAATAATATCCCCCCGCG (use ex-query as target)
case 4: u = 1, rev = 1 in the view of target: direction is 1
query: AAATAATATCCCCCCGCG target: ATATTATTTGCCGGCCC (use ex-target as query)
||||||||| <---> |||||||||
target: GGGCCGGCAAATAATAT query: CGCGGGGGATATTATTT (use ex-query as target)
********************************target-to-query overlap****************************
**/
if (qs <= tl5 && ql - h->qe <= tl3) return MA_HT_QCONT; // query contained in target
else if (qs >= tl5 && ql - h->qe >= tl3) return MA_HT_TCONT; // target contained in query
else if (qs > tl5) u = 0, v = !!h->rev, l = qs - tl5; ///u = 0 means query-to-target overlap, l is the length of node in string graph (not the overlap length)
else u = 1, v = !h->rev, l = (ql - h->qe) - tl3; ///u = 1 means target-to-query overlaps, l is the length of node in string graph (not the overlap length)
if (h->qe - qs + ext5 + ext3 < min_ovlp || h->te - h->ts + ext5 + ext3 < min_ovlp) return MA_HT_SHORT_OVLP; // short overlap
///u = 0 / 1 means query-to-target / target-to-query overlaps,
///l is the length of node in string graph (not the overlap length between two reads)
u |= h->qns>>32<<1, v |= h->tn<<1;
/**
p->ul: |____________31__________|__________1___________|______________32_____________|
qn direction of overlap length of this node (not overlap length)
(in the view of query)
p->v : |___________31___________|__________1___________|
tn reverse direction of overlap
(in the view of target)
p->ol: overlap length
**/
p->ul = (uint64_t)u<<32 | l, p->v = v, p->ol = ql - l, p->del = 0;
///l is the length of node in string graph (not the overlap length)
p->strong = h->ml;
p->el = h->el;
return l;
}
void build_string_graph(int min_dp, ma_hit_t_alloc* sources, ma_hit_t_alloc* reverse_sources, long long n_read, uint64_t* readLen,
long long mini_overlap_length, long long max_hang_length,
long long clean_round, float min_ovlp_drop_ratio, float max_ovlp_drop_ratio,
float final_ovlp_drop_ratio, char* output_file_name, long long bubble_dist);
#define asg_arc_len(arc) ((uint32_t)(arc).ul)
#define asg_arc_n(g, v) ((uint32_t)(g)->idx[(v)])
#define asg_arc_a(g, v) (&(g)->arc[(g)->idx[(v)]>>32])
// append an arc
static inline asg_arc_t *asg_arc_pushp(asg_t *g)
{
if (g->n_arc == g->m_arc) {
g->m_arc = g->m_arc? g->m_arc<<1 : 16;
g->arc = (asg_arc_t*)realloc(g->arc, g->m_arc * sizeof(asg_arc_t));
}
return &g->arc[g->n_arc++];
}
// set asg_arc_t::del for v->w
static inline void asg_arc_del(asg_t *g, uint32_t v, uint32_t w, int del)
{
uint32_t i, nv = asg_arc_n(g, v);
asg_arc_t *av = asg_arc_a(g, v);
for (i = 0; i < nv; ++i)
if (av[i].v == w) av[i].del = !!del;
}
// set asg_arc_t::del and asg_seq_t::del to 1 for sequence s and all its associated arcs
static inline void asg_seq_del(asg_t *g, uint32_t s)
{
uint32_t k;
g->seq[s].del = 1;
for (k = 0; k < 2; ++k) {
uint32_t i, v = s<<1 | k;
uint32_t nv = asg_arc_n(g, v);
asg_arc_t *av = asg_arc_a(g, v);
for (i = 0; i < nv; ++i) {
av[i].del = 1;
asg_arc_del(g, av[i].v^1, v^1, 1);
}
}
}
typedef struct {
uint32_t len:31, circ:1; // len: length of the unitig; circ: circular if non-zero
uint32_t start, end; // start: starting vertex in the string graph; end: ending vertex
uint32_t m, n; // number of reads
uint64_t *a; // list of reads
char *s; // unitig sequence is not null
} ma_utg_t;
typedef struct { size_t n, m; ma_utg_t *a; } ma_utg_v;
typedef struct {
ma_utg_v u;
asg_t *g;
} ma_ug_t;
typedef struct {
uint32_t utg:31, ori:1, start, len;
} utg_intv_t;
/******************
* Bubble popping *
******************/
typedef struct {
uint32_t p; // the optimal parent vertex
uint32_t d; // the shortest distance from the initial vertex
uint32_t c; // max count of reads
uint32_t r:31, s:1; // r: the number of remaining incoming arc; s: state
//s: state, s=0, this edge has not been visited, otherwise, s=1
} binfo_t;
typedef struct {
///all information for each node
binfo_t *a;
kvec_t(uint32_t) S; // set of vertices without parents, nodes with all incoming edges visited
kvec_t(uint32_t) T; // set of tips
kvec_t(uint32_t) b; // visited vertices
kvec_t(uint32_t) e; // visited edges/arcs
} buf_t;
// count the number of outgoing arcs, including reduced arcs
static inline int count_out_with_del(const asg_t *g, uint32_t v)
{
uint32_t i, n, nv = asg_arc_n(g, v);
const asg_arc_t *av = asg_arc_a(g, v);
/**
for (i = n = 0; i < nv; ++i)
if (!av[i].del) ++n;
return n;
**/
return nv;
}
// count the number of outgoing arcs, including reduced arcs
static inline int count_out_without_del(const asg_t *g, uint32_t v)
{
uint32_t i, n, nv = asg_arc_n(g, v);
const asg_arc_t *av = asg_arc_a(g, v);
for (i = n = 0; i < nv; ++i)
if (!av[i].del) ++n;
return n;
}
void debug_info_of_specfic_read(char* name, ma_hit_t_alloc* sources,
ma_hit_t_alloc* reverse_sources, int id, char* fun);
void build_string_graph_without_clean(int min_dp, ma_hit_t_alloc* sources, ma_hit_t_alloc* reverse_sources, long long n_read, uint64_t* readLen,
long long mini_overlap_length, long long max_hang_length,
long long clean_round, float min_ovlp_drop_ratio, float max_ovlp_drop_ratio,
float corase_ovlp_drop_ratio, char* output_file_name, long long bubble_dist, int read_graph,
int write);
#endif
+406 -22
View File
@@ -15,11 +15,13 @@ void init_Edge_alloc(Edge_alloc* list)
{
list->size = INIT_EDGE_SIZE;
list->length = 0;
list->delete_length = 0;
list->list = (Edge*)malloc(sizeof(Edge)*list->size);
}
else
{
list->length = 0;
list->delete_length = 0;
}
}
@@ -27,6 +29,7 @@ void init_Edge_alloc(Edge_alloc* list)
void clear_Edge_alloc(Edge_alloc* list)
{
list->length = 0;
list->delete_length = 0;
}
void destory_Edge_alloc(Edge_alloc* list)
@@ -47,17 +50,138 @@ void append_Edge_alloc(Edge_alloc* list, uint64_t in_node, uint64_t out_node, u
list->list[list->length].weight = weight;
list->list[list->length].length = length;
list->list[list->length].num_insertions = 0;
list->list[list->length].self_edge_ID = list->length;
list->length++;
}
int add_and_check_bi_direction_edge(Graph* graph, Node* in_node, Node* out_node, uint64_t weight, uint64_t flag)
{
Edge* e_forward;
Edge* e_backward;
//if there are no edge from in_node to out_node
if(!get_bi_Edge(graph, in_node, out_node, &e_forward, &e_backward))
{
append_Edge_alloc(&(Output_Edges((*in_node))), (*in_node).ID, (*out_node).ID, weight, flag);
append_Edge_alloc(&(Input_Edges((*out_node))), (*in_node).ID, (*out_node).ID, weight, flag);
Output_Edges((*in_node)).list[Output_Edges((*in_node)).length - 1].reverse_edge_ID
= Input_Edges((*out_node)).length - 1;
Input_Edges((*out_node)).list[Input_Edges((*out_node)).length - 1].reverse_edge_ID
= Output_Edges((*in_node)).length - 1;
return 1;
}
else//if there is an edge from in_node to out_node, do nothing
{
return 0;
}
}
void add_bi_direction_edge(Graph* graph, Node* in_node, Node* out_node, uint64_t weight, uint64_t flag)
{
append_Edge_alloc(&(Output_Edges((*in_node))), (*in_node).ID, (*out_node).ID, weight, flag);
append_Edge_alloc(&(Input_Edges((*out_node))), (*in_node).ID, (*out_node).ID, weight, flag);
Output_Edges((*in_node)).list[Output_Edges((*in_node)).length - 1].reverse_edge_ID
= Input_Edges((*out_node)).length - 1;
Input_Edges((*out_node)).list[Input_Edges((*out_node)).length - 1].reverse_edge_ID
= Output_Edges((*in_node)).length - 1;
}
int remove_and_check_bi_direction_edge_from_nodes(Graph* graph, Node* in_node, Node* out_node)
{
Edge* e_forward;
Edge* e_backward;
//if there are no edge from in_node to out_node
//1. remove these two edges
//2. increase the edge_list.delete_length in both in_node and out_node
if(get_bi_Edge(graph, in_node, out_node, &e_forward, &e_backward))
{
e_forward->in_node = (uint64_t)-1;
e_forward->out_node = (uint64_t)-1;
e_forward->weight = (uint64_t)-1;
e_forward->length = (uint64_t)-1;
e_forward->num_insertions = (uint64_t)-1;
e_forward->self_edge_ID = (uint64_t)-1;
e_forward->reverse_edge_ID = (uint64_t)-1;
e_backward->in_node = (uint64_t)-1;
e_backward->out_node = (uint64_t)-1;
e_backward->weight = (uint64_t)-1;
e_backward->length = (uint64_t)-1;
e_backward->num_insertions = (uint64_t)-1;
e_backward->self_edge_ID = (uint64_t)-1;
e_backward->reverse_edge_ID = (uint64_t)-1;
Output_Edges(*in_node).delete_length++;
Input_Edges((*out_node)).delete_length++;
return 1;
}
else//if there is an edge from in_node to out_node, do nothing
{
return 0;
}
}
int remove_and_check_bi_direction_edge_from_edge(Graph* graph, Edge* e)
{
Edge* e_forward;
Edge* e_backward;
if(If_Edge_Exist(*e))
{
get_bi_direction_edges(graph, e, &e_forward, &e_backward);
Output_Edges(G_Node(*graph, e_forward->in_node)).delete_length++;
Input_Edges(G_Node(*graph, e_forward->out_node)).delete_length++;
e_forward->in_node = (uint64_t)-1;
e_forward->out_node = (uint64_t)-1;
e_forward->weight = (uint64_t)-1;
e_forward->length = (uint64_t)-1;
e_forward->num_insertions = (uint64_t)-1;
e_forward->self_edge_ID = (uint64_t)-1;
e_forward->reverse_edge_ID = (uint64_t)-1;
e_backward->in_node = (uint64_t)-1;
e_backward->out_node = (uint64_t)-1;
e_backward->weight = (uint64_t)-1;
e_backward->length = (uint64_t)-1;
e_backward->num_insertions = (uint64_t)-1;
e_backward->self_edge_ID = (uint64_t)-1;
e_backward->reverse_edge_ID = (uint64_t)-1;
return 1;
}
else
{
return 0;
}
}
void init_Node_alloc(Node_alloc* list)
{
list->size = INIT_NODE_SIZE;
list->length = 0;
list->delete_length = 0;
list->list = (Node*)malloc(sizeof(Node)*list->size);
list->sort.size = 0;
list->sort.list = NULL;
@@ -105,6 +229,7 @@ void clear_Node_alloc(Node_alloc* list)
}
list->length = 0;
list->delete_length = 0;
}
@@ -162,11 +287,14 @@ void init_Graph(Graph* g)
g->s_start_nodeID = 0;
g->seq = NULL;
g->seqID = (uint64_t)-1;
init_Queue(&(g->node_q));
}
void destory_Graph(Graph* g)
{
destory_Node_alloc(&g->g_nodes);
destory_Queue(&(g->node_q));
}
void clear_Graph(Graph* g)
@@ -180,6 +308,8 @@ void clear_Graph(Graph* g)
g->s_start_nodeID = 0;
g->seq = NULL;
g->seqID = (uint64_t)-1;
clear_Queue(&(g->node_q));
}
@@ -237,6 +367,282 @@ void addUnmatchedSeqToGraph(Graph* g, char* g_read_seq, long long g_read_length,
inline void add_insertionEdge_weight_print(Graph* g, long long alignNodeID, char* insert, long long insert_length)
{
long long nodeID;
long long edgeID;
Edge_alloc* edge = &(g->g_nodes.list[alignNodeID].insertion_edges);
/******************************for homopolymer*************************/
long long i = 0;
char hom;
if (insert_length > 0)
{
hom = insert[0];
}
for (i = 0; i < insert_length; i++)
{
if(insert[i] != hom)
{
break;
}
}
fprintf(stderr, "###insert_length: %d\n", insert_length);
///if it is a homopolymer
if(i == insert_length)
{
///single base
edgeID = getEdge(g, edge, 1, insert[0]);
if (edgeID != -1)
{
///这条路均只有一个出度
edge->list[edgeID].weight++;
}
else ///不存在这么一条边
{
nodeID = add_Node_Graph(g, insert[0]);
append_Edge_alloc(edge, alignNodeID, nodeID, 1, 1);
///将新加入的节点通过insertion_edges接回backbone上
///应该连回到原节点,而不是原节点的下一个节点
///append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID + 1, 1, 0);
append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID, 1, 0);
}
///multiple bases
for (i = 1; i < insert_length; i++)
{
edgeID = get_insertion_Edges(g, edge, i + 1, insert);
if (edgeID != -1)
{
///这条路均只有一个出度
edge->list[edgeID].weight++;
}
else
{
create_insertion_Edges(g, alignNodeID, i + 1, insert);
}
}
return;
}
/******************************for homopolymer*************************/
fprintf(stderr, "###not homopolymer: %d\n", insert_length);
if (insert_length == 1)
{
edgeID = getEdge(g, edge, 1, insert[0]);
if (edgeID != -1)
{
///这条路均只有一个出度
edge->list[edgeID].weight++;
}
else ///不存在这么一条边
{
nodeID = add_Node_Graph(g, insert[0]);
append_Edge_alloc(edge, alignNodeID, nodeID, 1, 1);
///将新加入的节点通过insertion_edges接回backbone上
///应该连回到原节点,而不是原节点的下一个节点
///append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID + 1, 1, 0);
append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID, 1, 0);
}
}
else if (insert_length == 2)
{
/*******************第0个字符********************* */
edgeID = getEdge(g, edge, 1, insert[0]);
fprintf(stderr, "edgeID[0]: %d, length: %d\n", edgeID, edge->list[edgeID].length);
if (edgeID != -1)
{
///这条路均只有一个出度
edge->list[edgeID].weight++;
}
else ///不存在这么一条边
{
nodeID = add_Node_Graph(g, insert[0]);
append_Edge_alloc(edge, alignNodeID, nodeID, 1, 1);
///将新加入的节点通过insertion_edges接回backbone上
///应该连回到原节点,而不是原节点的下一个节点
///append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID + 1, 1, 0);
append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID, 1, 0);
}
fprintf(stderr, "edge->length: %d\n", edge->length);
/*******************第0个字符********************* */
/*******************第1个字符********************* */
if (insert[1] != insert[0])
{
edgeID = getEdge(g, edge, 1, insert[1]);
fprintf(stderr, "edgeID[1]: %d, length: %d\n", edgeID, edge->list[edgeID].length);
if (edgeID != -1)
{
///这条路均只有一个出度
edge->list[edgeID].weight++;
}
else ///不存在这么一条边
{
nodeID = add_Node_Graph(g, insert[1]);
append_Edge_alloc(edge, alignNodeID, nodeID, 1, 1);
///将新加入的节点通过insertion_edges接回backbone上
///应该连回到原节点,而不是原节点的下一个节点
///append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID + 1, 1, 0);
append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID, 1, 0);
}
fprintf(stderr, "edge->length: %d\n", edge->length);
}
/*******************第1个字符********************* */
/**********************两个字符******************* */
edgeID = get_insertion_Edges(g, edge, 2, insert);
fprintf(stderr, "edgeID[len2]: %d, length: %d\n", edgeID, edge->list[edgeID].length);
if (edgeID != -1)
{
///这条路均只有一个出度
edge->list[edgeID].weight++;
}
else
{
create_insertion_Edges(g, alignNodeID, insert_length, insert);
}
fprintf(stderr, "edge->length: %d\n", edge->length);
for (i = 0; i < edge->length; i++)
{
fprintf(stderr, "edgeID[%d].length: %d\n", i, edge->list[i].length);
}
/**********************两个字符******************* */
}
else if (insert_length > 2)
{
////fprintf(stderr, "too long insertion\n");
/*************************大于2个字符************************** */
edgeID = get_insertion_Edges(g, edge, insert_length, insert);
if (edgeID != -1)
{
///这条路均只有一个出度
edge->list[edgeID].weight++;
}
else
{
create_insertion_Edges(g, alignNodeID, insert_length, insert);
}
}
}
void addmatchedSeqToGraph_print(Graph* backbone, long long currentNodeID, char* x_string, long long x_length,
char* y_string, long long y_length, CIGAR* cigar, long long backbone_start, long long backbone_end)
{
int x_i, y_i, cigar_i;
x_i = 0;
y_i = 0;
cigar_i = 0;
int operation;
int operationLen;
int i;
int last_operation = -1;
fprintf(stderr,"*******\n");
///note that node 0 is the start node
///0 is match, 1 is mismatch, 2 is up, 3 is left
///2是x缺字符(y多字符),而3是y缺字符(x多字符)
while (cigar_i < cigar->length)
{
operation = cigar->C_C[cigar_i];
operationLen = cigar->C_L[cigar_i];
// fprintf(stderr, "operation: %d, operationLen: %d\n",
// operation, operationLen);
///这种情况代表匹配和mismatch
if (operation == 0 || operation == 1)
{
for (i = 0; i < operationLen; i++)
{
//backbone->g_nodes.list[currentNodeID].weight++;
///前面是插入,后面有可能是误配,也有可能是匹配
add_mismatchEdge_weight(backbone, currentNodeID, y_string[y_i], last_operation);
x_i++;
y_i++;
currentNodeID++;
}
}///insertion
else if (operation == 2)
{
///cigar的起始和结尾不可能是2,所以这里-1没问题
///if (operationLen <= CORRECT_INDEL_LENGTH)
{
add_insertionEdge_weight_print(backbone, currentNodeID, y_string + y_i, operationLen);
backbone->g_nodes.list[currentNodeID].num_insertions++;
}
///fprintf(stderr, "y_string: %.*s\n", operationLen, y_string+y_i);
y_i += operationLen;
}
else if (operation == 3)
{
///3是y缺字符(x多字符),也就是backbone多字符
///这个相当于在backbone对应字符处变成了‘——’
///因此可以用mismatch类似的方法处理
///if (operationLen <= CORRECT_INDEL_LENGTH)
{
///add_deletion_to_backbone(backbone, &currentNodeID, operationLen);
///在编辑距离中,前面是个插入,后面是个删除,这种情况是不存在的
///为了保险要不还给他加上吧
///先不加
add_deletionEdge_weight(backbone, currentNodeID, operationLen);
}
currentNodeID += operationLen;
x_i += operationLen;
}
last_operation = operation;
cigar_i++;
}
/**
///cigar的起始和结尾不可能是2
if (cigar->C_C[0] == 2 || cigar->C_C[cigar->length - 1] == 2)
{
fprintf(stderr, "error\n");
}
if (x_i != x_length)
{
fprintf(stderr, "x_i: %d, x_length: %d\n", x_i, x_length);
}
if (y_i != y_length)
{
fprintf(stderr, "y_i: %d, y_length: %d\n", y_i, y_length);
}
**/
}
@@ -311,28 +717,6 @@ void addmatchedSeqToGraph(Graph* backbone, long long currentNodeID, char* x_stri
cigar_i++;
}
/**
///cigar的起始和结尾不可能是2
if (cigar->C_C[0] == 2 || cigar->C_C[cigar->length - 1] == 2)
{
fprintf(stderr, "error\n");
}
if (x_i != x_length)
{
fprintf(stderr, "x_i: %d, x_length: %d\n", x_i, x_length);
}
if (y_i != y_length)
{
fprintf(stderr, "y_i: %d, y_length: %d\n", y_i, y_length);
}
**/
}
+722 -66
View File
@@ -23,6 +23,120 @@
5. 有两个回溯矩阵,一个是graph的,一个是seq的
**/
typedef struct
{
long long beg;
///end is the index of next input data, instead of the index of last data
long long end;
long long length;
long long size;
long long* buffer;
} Queue;
inline void init_Queue(Queue* q)
{
q->beg = 0;
q->end = 0;
q->length = 0;
q->size = 20;
q->buffer = (long long*)malloc(sizeof(long long)*q->size);
}
inline void clear_Queue(Queue* q)
{
q->beg = 0;
q->end = 0;
q->length = 0;
}
inline void destory_Queue(Queue* q)
{
free(q->buffer);
}
inline int is_empty_Queue(Queue* q)
{
///end is the index of next input data, instead of the index of last data
if(q->beg == q->end)
{
return 1;
}
else
{
return 0;
}
}
inline int is_full_Queue(Queue* q)
{
///end is the index of next input data, instead of the index of last data
if(q->end < q->size)
{
return 0;
}
else
{
return 1;
}
}
inline void push_to_Queue(Queue* q, long long nodeID)
{
if(is_full_Queue(q))
{
long long move_length = q->beg;
///end is the index of next input data, instead of the index of last data
long long current_length = q->end - q->beg;
///recalloc directly
if(move_length == 0)
{
q->size = q->size * 2;
q->buffer = (long long*)realloc(q->buffer, q->size*sizeof(long long));
}
else
{
///won't overlap
if(current_length <= move_length)
{
memcpy(q->buffer, q->buffer+q->beg, sizeof(long long)*current_length);
}
else///may overlap
{
memmove(q->buffer, q->buffer+q->beg, sizeof(long long)*current_length);
}
q->beg = 0;
q->end = current_length;
}
}
q->buffer[q->end] = nodeID;
q->end++;
}
inline int pop_from_Queue(Queue* q, long long* nodeID)
{
if(is_empty_Queue(q))
{
(*nodeID) = -1;
return 0;
}
else
{
(*nodeID) = q->buffer[q->beg];
q->beg++;
return 1;
}
}
typedef struct
{
uint64_t in_node;
@@ -32,6 +146,8 @@ typedef struct
uint64_t num_insertions;
///这条路径上到backbone节点之前总共有多少节点
uint64_t length;
uint64_t self_edge_ID;
uint64_t reverse_edge_ID;
} Edge;
typedef struct
@@ -39,8 +155,27 @@ typedef struct
Edge* list;
uint64_t size;
uint64_t length;
uint64_t delete_length;
} Edge_alloc;
#define Real_Length(X) ((X).length - (X).delete_length)
#define Input_Edges(Node) ((Node).insertion_edges)
#define Output_Edges(Node) ((Node).deletion_edges)
#define G_Node(G, Node) ((G).g_nodes.list[(Node)])
#define If_Node_Exist(Node) ((Node).base != 'D')
#define If_Edge_Exist(E) ((E).out_node != (uint64_t)-1)
#define Visit(E) (E).length
typedef struct
{
long long index;
} RSet;
inline void clear_RSet(RSet* set)
{
set->index = 0;
}
typedef struct
{
uint64_t ID;
@@ -73,6 +208,7 @@ typedef struct
topo_Sorting_buffer sort;
uint64_t size;
uint64_t length;
uint64_t delete_length;
} Node_alloc;
typedef struct
@@ -83,13 +219,222 @@ typedef struct
Node_alloc g_nodes;
Queue node_q;
char* seq;
uint64_t seqID;
uint64_t s_start_nodeID;
uint64_t s_end_nodeID;
} Graph;
int add_and_check_bi_direction_edge(Graph* graph, Node* in_node, Node* out_node, uint64_t weight, uint64_t flag);
void add_bi_direction_edge(Graph* graph, Node* in_node, Node* out_node, uint64_t weight, uint64_t flag);
int remove_and_check_bi_direction_edge_from_nodes(Graph* graph, Node* in_node, Node* out_node);
int remove_and_check_bi_direction_edge_from_edge(Graph* graph, Edge* e);
inline int Pop_Node(Graph* DAGCon, Node** node)
{
long long nodeID = 0;
int return_flag = pop_from_Queue(&(DAGCon->node_q), &nodeID);
(*node) = &(G_Node(*DAGCon, nodeID));
return return_flag;
}
inline int Push_Node(Graph* DAGCon, Node** node)
{
push_to_Queue(&(DAGCon->node_q), (**node).ID);
}
inline int getInputNodes(RSet* set, Graph* graph, Node* node, Node** get_Node)
{
if(set->index >= Input_Edges(*node).length)
{
return 0;
}
///skip all deleted edges
while (
set->index < Input_Edges(*node).length
&&
!(If_Edge_Exist(Input_Edges(*node).list[set->index]))
)
{
set->index++;
}
if(
set->index < Input_Edges(*node).length
&&
If_Edge_Exist(Input_Edges(*node).list[set->index])
)
{
(*get_Node) = &(G_Node((*graph), Input_Edges(*node).list[set->index].in_node));
set->index++;
return 1;
}
else
{
return 0;
}
}
inline int getInputEdges(RSet* set, Graph* graph, Node* node, Edge** get_Edge)
{
if(set->index >= Input_Edges(*node).length)
{
return 0;
}
///skip all deleted edges
while (
set->index < Input_Edges(*node).length
&&
!(If_Edge_Exist(Input_Edges(*node).list[set->index]))
)
{
set->index++;
}
if(
set->index < Input_Edges(*node).length
&&
If_Edge_Exist(Input_Edges(*node).list[set->index])
)
{
(*get_Edge) = &(Input_Edges(*node).list[set->index]);
set->index++;
return 1;
}
else
{
return 0;
}
}
inline int getOutputNodes(RSet* set, Graph* graph, Node* node, Node** get_Node)
{
if(set->index >= Output_Edges(*node).length)
{
return 0;
}
///skip all deleted edges
while (
set->index < Output_Edges(*node).length
&&
!(If_Edge_Exist(Output_Edges(*node).list[set->index]))
)
{
set->index++;
}
if(set->index < Output_Edges(*node).length &&
If_Edge_Exist(Output_Edges(*node).list[set->index]))
{
(*get_Node) = &(G_Node((*graph), Output_Edges(*node).list[set->index].out_node));
set->index++;
return 1;
}
else
{
return 0;
}
}
inline int getOutputEdges(RSet* set, Graph* graph, Node* node, Edge** get_Edge)
{
if(set->index >= Output_Edges(*node).length)
{
return 0;
}
///skip all deleted edges
while (
set->index < Output_Edges(*node).length
&&
!(If_Edge_Exist(Output_Edges(*node).list[set->index]))
)
{
set->index++;
}
if(set->index < Output_Edges(*node).length &&
If_Edge_Exist(Output_Edges(*node).list[set->index]))
{
(*get_Edge) = &(Output_Edges(*node).list[set->index]);
set->index++;
return 1;
}
else
{
return 0;
}
}
inline void get_bi_direction_edges(Graph* DAGCon, Edge* edge, Edge** e_forward, Edge** e_backward)
{
long long in_node = edge->in_node;
long long out_node = edge->out_node;
if(
edge->self_edge_ID < Output_Edges(G_Node(*DAGCon, in_node)).length
&&
Output_Edges(G_Node(*DAGCon, in_node)).list[edge->self_edge_ID].in_node == in_node
&&
Output_Edges(G_Node(*DAGCon, in_node)).list[edge->self_edge_ID].out_node == out_node
)
{
(*e_forward) = &(Output_Edges(G_Node(*DAGCon, in_node)).list[edge->self_edge_ID]);
(*e_backward) = &(Input_Edges(G_Node(*DAGCon, out_node)).list[edge->reverse_edge_ID]);
}
else
{
(*e_forward) = &(Output_Edges(G_Node(*DAGCon, in_node)).list[edge->reverse_edge_ID]);
(*e_backward) = &(Input_Edges(G_Node(*DAGCon, out_node)).list[edge->self_edge_ID]);
}
}
inline long long get_bi_Edge(Graph* DAGCon, Node* inNode, Node* outNode, Edge** e_forward, Edge** e_backward)
{
Edge* e;
RSet iter;
clear_RSet(&iter);
if(If_Node_Exist(*inNode) && If_Node_Exist(*outNode))
{
//find in-edge of outNode
while(getInputEdges(&iter, DAGCon, outNode, &e))
{
if(e->in_node == inNode->ID)
{
get_bi_direction_edges(DAGCon, e, e_forward, e_backward);
return 1;
}
}
}
return 0;
}
inline long long get_Edge_Weight(Graph* DAGCon, Node* inNode, Node* outNode)
{
Edge* e_forward;
Edge* e_backward;
get_bi_Edge(DAGCon, inNode, outNode, &e_forward, &e_backward);
return e_forward->weight;
}
void init_Edge_alloc(Edge_alloc* list);
void clear_Edge_alloc(Edge_alloc* list);
@@ -121,6 +466,48 @@ uint64_t inline add_Node_Graph(Graph* g, char base)
return append_Node_alloc(&g->g_nodes, base);
}
inline Node* add_Node_DAGCon(Graph* g, char base)
{
return &(G_Node(*g, append_Node_alloc(&g->g_nodes, base)));
}
///to delete a node
///1. set the corresponding base to be 'D'
///2. remove all related edges
///2. clear all related edges
///3. g_nodes.delete_length++, please do not substract g_nodes.length
uint64_t inline delete_Node_DAGCon(Graph* g, Node* node)
{
g->g_nodes.delete_length++;
g->g_nodes.list[(*node).ID].base = 'D';
g->g_nodes.list[(*node).ID].num_insertions = (uint64_t)-1;
g->g_nodes.list[(*node).ID].weight = (uint64_t)-1;
RSet iter;
Edge* e;
clear_RSet(&iter);
while (getOutputEdges(&iter, g, node, &e))
{
remove_and_check_bi_direction_edge_from_edge(g, e);
}
clear_RSet(&iter);
while (getInputEdges(&iter, g, node, &e))
{
remove_and_check_bi_direction_edge_from_edge(g, e);
}
clear_Edge_alloc(&(g->g_nodes.list[(*node).ID].insertion_edges));
clear_Edge_alloc(&(g->g_nodes.list[(*node).ID].mismatch_edges));
clear_Edge_alloc(&(g->g_nodes.list[(*node).ID].deletion_edges));
}
///仅仅用于误配边
inline void add_mismatchEdge_weight(Graph* g, uint64_t in_node, char base, int last_operation)
@@ -193,6 +580,7 @@ inline void add_single_deletionEdge_weight(Graph* g, long long alignNodeID, long
inline void add_deletionEdge_weight(Graph* g, long long alignNodeID, long long deletion_length)
{
/**
if (deletion_length == 1)
{
add_single_deletionEdge_weight(g, alignNodeID, alignNodeID + 1, 0);
@@ -208,6 +596,13 @@ inline void add_deletionEdge_weight(Graph* g, long long alignNodeID, long long d
///fprintf(stderr, "too long deletion!\n");
add_single_deletionEdge_weight(g, alignNodeID, alignNodeID + deletion_length, 0);
}
**/
long long i;
for (i = 0; i < deletion_length; i++)
{
add_single_deletionEdge_weight(g, alignNodeID + i, alignNodeID + i + 1, 0);
}
}
@@ -266,8 +661,10 @@ inline int get_insertion_Edges(Graph* g, Edge_alloc* edge, uint64_t edge_length,
return -1;
}
}
return edgeID;
/****************************may have bugs********************************/
///return edgeID;
return return_edgeID;
/****************************may have bugs********************************/
}
@@ -305,19 +702,183 @@ inline int create_insertion_Edges(Graph* g, long long alignNodeID, uint64_t edge
}
inline void add_insertionEdge_weight(Graph* g, long long alignNodeID, char* insert, long long insert_length)
inline void extract_path(Graph* backbone, int debug_node_in_backbone, int path_i, char* pre)
{
int step = G_Node(*backbone, debug_node_in_backbone).insertion_edges.list[path_i].length;
int string_i, preNode, j;
if(step != 0)
{
string_i = 0;
preNode = G_Node(*backbone, debug_node_in_backbone).insertion_edges.list[path_i].out_node;
for (j = 0; j < step; j++)
{
pre[string_i++] = G_Node(*backbone, preNode).base;
preNode = G_Node(*backbone, preNode).insertion_edges.list[0].out_node;
}
}
pre[string_i] = '\0';
}
inline void extract_path_debug(Graph* backbone, int debug_node_in_backbone, int path_i, char* pre)
{
int step = G_Node(*backbone, debug_node_in_backbone).insertion_edges.list[path_i].length;
int string_i, preNode, preEdge, j;
if(step != 0)
{
string_i = 0;
preNode = G_Node(*backbone, debug_node_in_backbone).insertion_edges.list[path_i].out_node;
preEdge = G_Node(*backbone, debug_node_in_backbone).insertion_edges.list[path_i].length;
for (j = 0; j < step; j++)
{
///pre[string_i++] = G_Node(*backbone, preNode).base;
fprintf(stderr, "j: %d (%c%d), ", j, G_Node(*backbone, preNode).base, preEdge);
preEdge = G_Node(*backbone, preNode).insertion_edges.list[0].length;
preNode = G_Node(*backbone, preNode).insertion_edges.list[0].out_node;
}
}
fprintf(stderr, "\n");
///pre[string_i] = '\0';
}
inline int getEdge_DEBUG(Graph* g, Edge_alloc* edge, uint64_t edge_length, char base)
{
long long i = 0;
long long nodeID;
for (i = 0; i < edge->length; i++)
{
///fprintf(stderr, "************i:%d, edge->list[i].length: %d, edge_length: %d\n",i, edge->list[i].length, edge_length);
if (edge->list[i].length == edge_length)
{
nodeID = edge->list[i].out_node;
fprintf(stderr, "########i:%d, edge->list[i].length: %d, edge_length: %d, nodeID: %d, list[nodeID].base: %c, base: %c\n",
i, edge->list[i].length, edge_length, nodeID, g->g_nodes.list[nodeID].base, base);
if(g->g_nodes.list[nodeID].base == base)
{
return i;
}
}
}
return -1;
}
inline int get_insertion_Edges_new(Graph* backbone, int debug_node_in_backbone, uint64_t edge_length, char* bases)
{
int path_i, j, step, preNode;
for (path_i = 0; path_i < G_Node(*backbone, debug_node_in_backbone).insertion_edges.length; path_i++)
{
step = G_Node(*backbone, debug_node_in_backbone).insertion_edges.list[path_i].length;
if(step != edge_length)
{
continue;
}
if(step != 0)
{
preNode = G_Node(*backbone, debug_node_in_backbone).insertion_edges.list[path_i].out_node;
for (j = 0; j < step; j++)
{
///pre[string_i++] = G_Node(*backbone, preNode).base;
///fprintf(stderr, "path_i: %d, ID: %d\n", path_i, G_Node(*backbone, preNode).ID);
if(G_Node(*backbone, preNode).base != bases[j])
{
break;
}
preNode = G_Node(*backbone, preNode).insertion_edges.list[0].out_node;
}
if(j == step)
{
return path_i;
}
}
}
return -1;
}
inline int get_insertion_Edges_debug(Graph* g, Edge_alloc* edge, uint64_t edge_length, char* bases)
{
long long i = 0;
long long nodeID;
long long edgeID;
if (edge_length < 1)
{
return -1;
}
///fprintf(stderr, "edge_length: %d, edge: %.*s\n", edge_length, edge_length, bases);
edgeID = getEdge_DEBUG(g, edge, edge_length, bases[0]);
fprintf(stderr, "i: %d, edgeID: %d, edge_length - i: %d\n", i, edgeID, edge_length);
long long return_edgeID = edgeID;
if(edgeID == -1)
{
return -1;
}
Edge_alloc* new_edge = edge;
for (i = 1; i < edge_length; i++)
{
nodeID = new_edge->list[edgeID].out_node;
new_edge = &(g->g_nodes.list[nodeID].insertion_edges);
edgeID = getEdge_DEBUG(g, new_edge, edge_length - i, bases[i]);
fprintf(stderr, "i: %d, edgeID: %d, edge_length - i: %d\n", i, edgeID, edge_length - i);
if(edgeID == -1)
{
return -1;
}
}
/****************************may have bugs********************************/
///return edgeID;
return return_edgeID;
/****************************may have bugs********************************/
}
inline void add_insertionEdge_weight(Graph* g, long long alignNodeID, char* insert, long long insert_length)
{
long long nodeID;
long long edgeID;
Edge_alloc* edge = &(g->g_nodes.list[alignNodeID].insertion_edges);
if (insert_length == 1)
{
edgeID = getEdge(g, edge, 1, insert[0]);
// if(edgeID != get_insertion_Edges_new(g, alignNodeID, insert_length, insert))
// {
// fprintf(stderr, "error\n");
// }
if (edgeID != -1)
{
///这条路均只有一个出度
edge->list[edgeID].weight++;
}
else ///不存在这么一条边
@@ -330,68 +891,10 @@ inline void add_insertionEdge_weight(Graph* g, long long alignNodeID, char* inse
append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID, 1, 0);
}
}
else if (insert_length == 2)
else
{
/*******************第0个字符********************* */
edgeID = getEdge(g, edge, 1, insert[0]);
if (edgeID != -1)
{
///这条路均只有一个出度
edge->list[edgeID].weight++;
}
else ///不存在这么一条边
{
nodeID = add_Node_Graph(g, insert[0]);
append_Edge_alloc(edge, alignNodeID, nodeID, 1, 1);
///将新加入的节点通过insertion_edges接回backbone上
///应该连回到原节点,而不是原节点的下一个节点
///append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID + 1, 1, 0);
append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID, 1, 0);
}
/*******************第0个字符********************* */
/*******************第1个字符********************* */
if (insert[1] != insert[0])
{
edgeID = getEdge(g, edge, 1, insert[1]);
if (edgeID != -1)
{
///这条路均只有一个出度
edge->list[edgeID].weight++;
}
else ///不存在这么一条边
{
nodeID = add_Node_Graph(g, insert[1]);
append_Edge_alloc(edge, alignNodeID, nodeID, 1, 1);
///将新加入的节点通过insertion_edges接回backbone上
///应该连回到原节点,而不是原节点的下一个节点
///append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID + 1, 1, 0);
append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID, 1, 0);
}
}
/*******************第1个字符********************* */
/**********************两个字符******************* */
edgeID = get_insertion_Edges(g, edge, 2, insert);
if (edgeID != -1)
{
///这条路均只有一个出度
edge->list[edgeID].weight++;
}
else
{
create_insertion_Edges(g, alignNodeID, insert_length, insert);
}
/**********************两个字符******************* */
}
else if (insert_length > 2)
{
////fprintf(stderr, "too long insertion\n");
/*************************大于2个字符************************** */
edgeID = get_insertion_Edges(g, edge, insert_length, insert);
///edgeID = get_insertion_Edges(g, edge, insert_length, insert);
edgeID = get_insertion_Edges_new(g, alignNodeID, insert_length, insert);
if (edgeID != -1)
{
///这条路均只有一个出度
@@ -402,10 +905,163 @@ inline void add_insertionEdge_weight(Graph* g, long long alignNodeID, char* inse
create_insertion_Edges(g, alignNodeID, insert_length, insert);
}
}
// /******************************for homopolymer*************************/
// long long i = 0;
// char hom;
// if (insert_length > 0)
// {
// hom = insert[0];
// }
// for (i = 0; i < insert_length; i++)
// {
// if(insert[i] != hom)
// {
// break;
// }
// }
// ///if it is a homopolymer
// if(i == insert_length)
// {
// ///single base
// edgeID = getEdge(g, edge, 1, insert[0]);
// if (edgeID != -1)
// {
// ///这条路均只有一个出度
// edge->list[edgeID].weight++;
// }
// else ///不存在这么一条边
// {
// nodeID = add_Node_Graph(g, insert[0]);
// append_Edge_alloc(edge, alignNodeID, nodeID, 1, 1);
// ///将新加入的节点通过insertion_edges接回backbone上
// ///应该连回到原节点,而不是原节点的下一个节点
// ///append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID + 1, 1, 0);
// append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID, 1, 0);
// }
// ///multiple bases
// for (i = 1; i < insert_length; i++)
// {
// edgeID = get_insertion_Edges(g, edge, i + 1, insert);
// if (edgeID != -1)
// {
// ///这条路均只有一个出度
// edge->list[edgeID].weight++;
// }
// else
// {
// create_insertion_Edges(g, alignNodeID, i + 1, insert);
// }
// }
// return;
// }
// /******************************for homopolymer*************************/
// if (insert_length == 1)
// {
// edgeID = getEdge(g, edge, 1, insert[0]);
// if (edgeID != -1)
// {
// ///这条路均只有一个出度
// edge->list[edgeID].weight++;
// }
// else ///不存在这么一条边
// {
// nodeID = add_Node_Graph(g, insert[0]);
// append_Edge_alloc(edge, alignNodeID, nodeID, 1, 1);
// ///将新加入的节点通过insertion_edges接回backbone上
// ///应该连回到原节点,而不是原节点的下一个节点
// ///append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID + 1, 1, 0);
// append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID, 1, 0);
// }
// }
// else if (insert_length == 2)
// {
// /*******************第0个字符********************* */
// edgeID = getEdge(g, edge, 1, insert[0]);
// if (edgeID != -1)
// {
// ///这条路均只有一个出度
// edge->list[edgeID].weight++;
// }
// else ///不存在这么一条边
// {
// nodeID = add_Node_Graph(g, insert[0]);
// append_Edge_alloc(edge, alignNodeID, nodeID, 1, 1);
// ///将新加入的节点通过insertion_edges接回backbone上
// ///应该连回到原节点,而不是原节点的下一个节点
// ///append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID + 1, 1, 0);
// append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID, 1, 0);
// }
// /*******************第0个字符********************* */
// /*******************第1个字符********************* */
// if (insert[1] != insert[0])
// {
// edgeID = getEdge(g, edge, 1, insert[1]);
// if (edgeID != -1)
// {
// ///这条路均只有一个出度
// edge->list[edgeID].weight++;
// }
// else ///不存在这么一条边
// {
// nodeID = add_Node_Graph(g, insert[1]);
// append_Edge_alloc(edge, alignNodeID, nodeID, 1, 1);
// ///将新加入的节点通过insertion_edges接回backbone上
// ///应该连回到原节点,而不是原节点的下一个节点
// ///append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID + 1, 1, 0);
// append_Edge_alloc(&(g->g_nodes.list[nodeID].insertion_edges), nodeID, alignNodeID, 1, 0);
// }
// }
// /*******************第1个字符********************* */
// /**********************两个字符******************* */
// edgeID = get_insertion_Edges(g, edge, 2, insert);
// if (edgeID != -1)
// {
// ///这条路均只有一个出度
// edge->list[edgeID].weight++;
// }
// else
// {
// create_insertion_Edges(g, alignNodeID, insert_length, insert);
// }
// /**********************两个字符******************* */
// }
// else if (insert_length > 2)
// {
// ////fprintf(stderr, "too long insertion\n");
// /*************************大于2个字符************************** */
// edgeID = get_insertion_Edges(g, edge, insert_length, insert);
// if (edgeID != -1)
// {
// ///这条路均只有一个出度
// edge->list[edgeID].weight++;
// }
// else
// {
// create_insertion_Edges(g, alignNodeID, insert_length, insert);
// }
// }
}
void addmatchedSeqToGraph_print(Graph* backbone, long long currentNodeID, char* x_string, long long x_length,
char* y_string, long long y_length, CIGAR* cigar, long long backbone_start, long long backbone_end);
#endif
+84 -12
View File
@@ -74,9 +74,10 @@ void destory_All_reads(All_reads* r)
void write_All_reads(All_reads* r, char* read_file_name)
{
fprintf(stdout, "Writing reads to disk ...... \n");
char* index_name = (char*)malloc(strlen(read_file_name)+5);
char* index_name = (char*)malloc(strlen(read_file_name)+15);
sprintf(index_name, "%s.bin", read_file_name);
FILE* fp = fopen(index_name, "w");
fwrite(&adapterLen, sizeof(adapterLen), 1, fp);
fwrite(&r->index_size, sizeof(r->index_size), 1, fp);
fwrite(&r->name_index_size, sizeof(r->name_index_size), 1, fp);
fwrite(&r->total_reads, sizeof(r->total_reads), 1, fp);
@@ -127,6 +128,7 @@ void write_All_reads(All_reads* r, char* read_file_name)
free(index_name);
fflush(fp);
fclose(fp);
fprintf(stdout, "Reads has been written.\n");
}
@@ -136,7 +138,7 @@ void write_All_reads(All_reads* r, char* read_file_name)
int load_All_reads(All_reads* r, char* read_file_name)
{
fprintf(stdout, "Loading reads to disk ...... \n");
char* index_name = (char*)malloc(strlen(read_file_name)+5);
char* index_name = (char*)malloc(strlen(read_file_name)+15);
sprintf(index_name, "%s.bin", read_file_name);
FILE* fp = fopen(index_name, "r");
if (!fp)
@@ -144,7 +146,14 @@ int load_All_reads(All_reads* r, char* read_file_name)
return 0;
}
int local_adapterLen;
fread(&local_adapterLen, sizeof(local_adapterLen), 1, fp);
if(local_adapterLen != adapterLen)
{
fprintf(stdout, "the adapterLen of index is: %d, but the adapterLen set by user is: %d\n",
local_adapterLen, adapterLen);
exit(1);
}
fread(&r->index_size, sizeof(r->index_size), 1, fp);
fread(&r->name_index_size, sizeof(r->name_index_size), 1, fp);
fread(&r->total_reads, sizeof(r->total_reads), 1, fp);
@@ -210,6 +219,8 @@ int load_All_reads(All_reads* r, char* read_file_name)
r->cigars = (Compressed_Cigar_record*)malloc(sizeof(Compressed_Cigar_record)*r->total_reads);
r->second_round_cigar = (Compressed_Cigar_record*)malloc(sizeof(Compressed_Cigar_record)*r->total_reads);
r->paf = (ma_hit_t_alloc*)malloc(sizeof(ma_hit_t_alloc)*r->total_reads);
r->reverse_paf = (ma_hit_t_alloc*)malloc(sizeof(ma_hit_t_alloc)*r->total_reads);
for (i = 0; i < r->total_reads; i++)
{
r->second_round_cigar[i].size = r->cigars[i].size = 0;
@@ -219,9 +230,14 @@ int load_All_reads(All_reads* r, char* read_file_name)
r->second_round_cigar[i].lost_base_size = r->cigars[i].lost_base_size = 0;
r->second_round_cigar[i].lost_base_length = r->cigars[i].lost_base_length = 0;
r->second_round_cigar[i].lost_base = r->cigars[i].lost_base = NULL;
init_ma_hit_t_alloc(&(r->paf[i]));
init_ma_hit_t_alloc(&(r->reverse_paf[i]));
}
free(index_name);
fclose(fp);
fprintf(stdout, "Reads has been loaded.\n");
@@ -279,6 +295,8 @@ void malloc_All_reads(All_reads* r)
r->cigars = (Compressed_Cigar_record*)malloc(sizeof(Compressed_Cigar_record)*r->total_reads);
r->second_round_cigar = (Compressed_Cigar_record*)malloc(sizeof(Compressed_Cigar_record)*r->total_reads);
r->paf = (ma_hit_t_alloc*)malloc(sizeof(ma_hit_t_alloc)*r->total_reads);
r->reverse_paf = (ma_hit_t_alloc*)malloc(sizeof(ma_hit_t_alloc)*r->total_reads);
for (i = 0; i < r->total_reads; i++)
{
r->second_round_cigar[i].size = r->cigars[i].size = 0;
@@ -288,9 +306,19 @@ void malloc_All_reads(All_reads* r)
r->second_round_cigar[i].lost_base_size = r->cigars[i].lost_base_size = 0;
r->second_round_cigar[i].lost_base_length = r->cigars[i].lost_base_length = 0;
r->second_round_cigar[i].lost_base = r->cigars[i].lost_base = NULL;
init_ma_hit_t_alloc(&(r->paf[i]));
init_ma_hit_t_alloc(&(r->reverse_paf[i]));
}
r->name = (char*)malloc(sizeof(char)*r->total_name_length);
r->N_site = (uint64_t**)calloc(r->total_reads, sizeof(uint64_t*));
@@ -658,21 +686,47 @@ void compress_base(uint8_t* dest, char* src, uint64_t src_l, uint64_t** N_site_l
while (i + 4 <= src_l)
{
// fprintf(stderr, "0 i: %d, dest_i: %d, src_l: %d\n",
// i, dest_i, src_l);
// fflush(stderr);
tmp = 0;
COMPRESS_BASE;
tmp = tmp | (c<<6);
// fprintf(stderr, "*******1******1 i: %d, tmp: %d, c: %d\n",
// i, tmp, c);
// fflush(stderr);
COMPRESS_BASE;
tmp = tmp | (c<<4);
// fprintf(stderr, "*******2******1 i: %d, tmp: %d, c: %d\n",
// i, tmp, c);
// fflush(stderr);
COMPRESS_BASE;
tmp = tmp | (c<<2);
// fprintf(stderr, "*******3******1 i: %d, tmp: %d, c: %d\n",
// i, tmp, c);
// fflush(stderr);
COMPRESS_BASE;
tmp = tmp | c;
// fprintf(stderr, "*******4******1 i: %d, tmp: %d, c: %d\n",
// i, tmp, c);
// fflush(stderr);
dest[dest_i] = tmp;
// fprintf(stderr, "2 i: %d, dest_i: %d, src_l: %d\n",
// i, dest_i, src_l);
// fflush(stderr);
dest_i++;
}
@@ -716,7 +770,7 @@ inline void exchage_kstring_t(kstring_t* a, kstring_t* b)
*b = tmp;
}
int get_read(kseq_t *s)
int get_read(kseq_t *s, int adapterLen)
{
int l;
@@ -727,6 +781,24 @@ int get_read(kseq_t *s)
exchage_kstring_t(&seq->name, &s->name);
exchage_kstring_t(&seq->qual, &s->qual);
exchage_kstring_t(&seq->seq, &s->seq);
if(adapterLen > 0)
{
if(s->seq.l <= adapterLen*2)
{
s->seq.l = 0;
}
else
{
long long i;
for (i = 0; i < (s->seq.l - adapterLen*2); i++)
{
s->seq.s[i] = s->seq.s[i + adapterLen];
}
s->seq.l -= adapterLen*2;
}
}
return 1;
}
@@ -770,8 +842,8 @@ void init_R_buffer(int thread_num)
void destory_R_buffer_block(R_buffer_block* curr_sub_block)
{
free(curr_sub_block->read);
kseq_destroy(curr_sub_block->read);
///free(curr_sub_block->read);
}
@@ -790,7 +862,7 @@ void destory_R_buffer()
inline void load_read_block(R_buffer_block* read_batch, int batch_read_size,
int* return_file_flag, int is_insert)
int* return_file_flag, int is_insert, int adapterLen)
{
int inner_i = 0;
int file_flag = 1;
@@ -801,18 +873,18 @@ inline void load_read_block(R_buffer_block* read_batch, int batch_read_size,
while (inner_i<batch_read_size)
{
file_flag = get_read(&read_batch->read[inner_i]);
file_flag = get_read(&read_batch->read[inner_i], adapterLen);
if (file_flag == 1)
{
read_batch->read[inner_i].ID = total_reads;
total_reads++;
///fprintf(stderr, "is_insert: %d\n", is_insert);
if (is_insert)
{
insert_read(&R_INF, &read_batch->read[inner_i].seq, &read_batch->read[inner_i].name);
insert_read(&R_INF, &read_batch->read[inner_i].seq,
&read_batch->read[inner_i].name);
}
inner_i++;
@@ -896,7 +968,7 @@ void* input_reads_muti_threads(void* arg)
load_read_block(&tmp_buf, RDB.block_inner_size, &file_flag, is_insert);
load_read_block(&tmp_buf, RDB.block_inner_size, &file_flag, is_insert, adapterLen);
if (file_flag == 0)
{
@@ -1022,7 +1094,7 @@ void Counting_block()
load_read_block(&tmp_buf, RDB.block_inner_size,
&file_flag, 0);
&file_flag, 0, adapterLen);
if (file_flag == 0)
+61 -5
View File
@@ -6,6 +6,9 @@
#include <stdlib.h>
#include <zlib.h>
#include "kseq.h"
#include "Overlaps.h"
#include "CommandLines.h"
///#include "Hash_Table.h"
#define READ_INIT_NUMBER 1000
@@ -15,11 +18,11 @@
#define IS_FULL(buffer) ((buffer.num >= buffer.size)?1:0)
#define IS_EMPTY(buffer) ((buffer.num == 0)?1:0)
///#define Get_READ_LENGTH(R_INF, ID) (R_INF.index[ID+1] - R_INF.index[ID])
#define Get_READ_LENGTH(R_INF, ID) R_INF.read_length[ID]
#define Get_NAME_LENGTH(R_INF, ID) (R_INF.name_index[ID+1] - R_INF.name_index[ID])
#define Get_READ_LENGTH(R_INF, ID) R_INF.read_length[(ID)]
#define Get_NAME_LENGTH(R_INF, ID) (R_INF.name_index[(ID)+1] - R_INF.name_index[(ID)])
///#define Get_READ(R_INF, ID) R_INF.read + (R_INF.index[ID]>>2) + ID
#define Get_READ(R_INF, ID) R_INF.read_sperate[ID]
#define Get_NAME(R_INF, ID) R_INF.name + R_INF.name_index[ID]
#define Get_READ(R_INF, ID) R_INF.read_sperate[(ID)]
#define Get_NAME(R_INF, ID) R_INF.name + R_INF.name_index[(ID)]
@@ -56,7 +59,56 @@ static char rc_Table[5] = {'T', 'G', 'C', 'A', 'N'};
void init_kseq(char* file);
void destory_kseq();
int get_read(kseq_t *s);
int get_read(kseq_t *s, int adapterLen);
typedef struct
{
uint64_t x_id;
uint64_t x_pos_s;
uint64_t x_pos_e;
uint8_t x_pos_strand;
uint64_t y_id;
uint64_t y_pos_s;
uint64_t y_pos_e;
uint8_t y_pos_strand;
uint64_t matchLen;
uint64_t totalLen;
} PAF;
typedef struct
{
PAF* list;
uint64_t size;
uint64_t length;
} PAF_alloc;
inline void init_PAF_alloc(PAF_alloc* list)
{
list->size = 15;
list->length = 0;
list->list = (PAF*)malloc(sizeof(PAF)*list->size);
}
inline void append_PAF_alloc(PAF_alloc* list, PAF* e)
{
if(list->length+1 > list->size)
{
list->size = list->size * 2;
list->list = (PAF*)realloc(list->list, sizeof(PAF)*list->size);
}
list->list[list->length] = (*e);
list->length++;
}
typedef struct
{
@@ -100,6 +152,10 @@ typedef struct
Compressed_Cigar_record* cigars;
Compressed_Cigar_record* second_round_cigar;
ma_hit_t_alloc* paf;
ma_hit_t_alloc* reverse_paf;
ma_sub_t* coverage_cut;
} All_reads;
extern All_reads R_INF;
+128
View File
@@ -0,0 +1,128 @@
#ifndef __AC_KDQ_H
#define __AC_KDQ_H
#include <stdlib.h>
#include <string.h>
#define __KDQ_TYPE(type) \
typedef struct { \
size_t front:58, bits:6, count, mask; \
type *a; \
} kdq_##type##_t;
#define kdq_t(type) kdq_##type##_t
#define kdq_size(q) ((q)->count)
#define kdq_first(q) ((q)->a[(q)->front])
#define kdq_last(q) ((q)->a[((q)->front + (q)->count - 1) & (q)->mask])
#define kdq_at(q, i) ((q)->a[((q)->front + (i)) & (q)->mask])
#define __KDQ_IMPL(type, SCOPE) \
SCOPE kdq_##type##_t *kdq_init_##type() \
{ \
kdq_##type##_t *q; \
q = (kdq_##type##_t*)calloc(1, sizeof(kdq_##type##_t)); \
q->bits = 2, q->mask = (1ULL<<q->bits) - 1; \
q->a = (type*)malloc((1<<q->bits) * sizeof(type)); \
return q; \
} \
SCOPE void kdq_destroy_##type(kdq_##type##_t *q) \
{ \
if (q == 0) return; \
free(q->a); free(q); \
} \
SCOPE int kdq_resize_##type(kdq_##type##_t *q, int new_bits) \
{ \
size_t new_size = 1ULL<<new_bits, old_size = 1ULL<<q->bits; \
if (new_size < q->count) { /* not big enough */ \
int i; \
for (i = 0; i < 64; ++i) \
if (1ULL<<i > q->count) break; \
new_bits = i, new_size = 1ULL<<new_bits; \
} \
if (new_bits == q->bits) return q->bits; /* unchanged */ \
if (new_bits > q->bits) q->a = (type*)realloc(q->a, (1ULL<<new_bits) * sizeof(type)); \
if (q->front + q->count <= old_size) { /* unwrapped */ \
if (q->front + q->count > new_size) /* only happens for shrinking */ \
memmove(q->a, q->a + new_size, (q->front + q->count - new_size) * sizeof(type)); \
} else { /* wrapped */ \
memmove(q->a + (new_size - (old_size - q->front)), q->a + q->front, (old_size - q->front) * sizeof(type)); \
q->front = new_size - (old_size - q->front); \
} \
q->bits = new_bits, q->mask = (1ULL<<q->bits) - 1; \
if (new_bits < q->bits) q->a = (type*)realloc(q->a, (1ULL<<new_bits) * sizeof(type)); \
return q->bits; \
} \
SCOPE type *kdq_pushp_##type(kdq_##type##_t *q) \
{ \
if (q->count == 1ULL<<q->bits) kdq_resize_##type(q, q->bits + 1); \
return &q->a[((q->count++) + q->front) & (q)->mask]; \
} \
SCOPE void kdq_push_##type(kdq_##type##_t *q, type v) \
{ \
if (q->count == 1ULL<<q->bits) kdq_resize_##type(q, q->bits + 1); \
q->a[((q->count++) + q->front) & (q)->mask] = v; \
} \
SCOPE type *kdq_unshiftp_##type(kdq_##type##_t *q) \
{ \
if (q->count == 1ULL<<q->bits) kdq_resize_##type(q, q->bits + 1); \
++q->count; \
q->front = q->front? q->front - 1 : (1ULL<<q->bits) - 1; \
return &q->a[q->front]; \
} \
SCOPE void kdq_unshift_##type(kdq_##type##_t *q, type v) \
{ \
type *p; \
p = kdq_unshiftp_##type(q); \
*p = v; \
} \
SCOPE type *kdq_pop_##type(kdq_##type##_t *q) \
{ \
return q->count? &q->a[((--q->count) + q->front) & q->mask] : 0; \
} \
SCOPE type *kdq_shift_##type(kdq_##type##_t *q) \
{ \
type *d = 0; \
if (q->count == 0) return 0; \
d = &q->a[q->front++]; \
q->front &= q->mask; \
--q->count; \
return d; \
}
#define KDQ_INIT2(type, SCOPE) \
__KDQ_TYPE(type) \
__KDQ_IMPL(type, SCOPE)
#ifndef klib_unused
#if (defined __clang__ && __clang_major__ >= 3) || (defined __GNUC__ && __GNUC__ >= 3)
#define klib_unused __attribute__ ((__unused__))
#else
#define klib_unused
#endif
#endif /* klib_unused */
#define KDQ_INIT(type) KDQ_INIT2(type, static inline klib_unused)
#define KDQ_DECLARE(type) \
__KDQ_TYPE(type) \
kdq_##type##_t *kdq_init_##type(); \
void kdq_destroy_##type(kdq_##type##_t *q); \
int kdq_resize_##type(kdq_##type##_t *q, int new_bits); \
type *kdq_pushp_##type(kdq_##type##_t *q); \
void kdq_push_##type(kdq_##type##_t *q, type v); \
type *kdq_unshiftp_##type(kdq_##type##_t *q); \
void kdq_unshift_##type(kdq_##type##_t *q, type v); \
type *kdq_pop_##type(kdq_##type##_t *q); \
type *kdq_shift_##type(kdq_##type##_t *q);
#define kdq_init(type) kdq_init_##type()
#define kdq_destroy(type, q) kdq_destroy_##type(q)
#define kdq_resize(type, q, new_bits) kdq_resize_##type(q, new_bits)
#define kdq_pushp(type, q) kdq_pushp_##type(q)
#define kdq_push(type, q, v) kdq_push_##type(q, v)
#define kdq_pop(type, q) kdq_pop_##type(q)
#define kdq_unshiftp(type, q) kdq_unshiftp_##type(q)
#define kdq_unshift(type, q, v) kdq_unshift_##type(q, v)
#define kdq_shift(type, q) kdq_shift_##type(q)
#endif
+2 -2
View File
@@ -209,8 +209,8 @@ static const double __ac_HASH_UPPER = 0.77;
extern int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \
extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \
extern void kh_del_##name(kh_##name##_t *h, khint_t x);\
extern void kh_write_##name(kh_##name##_t *h, FILE* fp)\
extern void kh_load_##name(kh_##name##_t *h, FILE* fp)
extern void kh_write_##name(kh_##name##_t *h, FILE* fp);\
extern void kh_load_##name(kh_##name##_t *h, FILE* fp);
#define __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
SCOPE kh_##name##_t *kh_init_##name(void) { \
+179 -1
View File
@@ -14,4 +14,182 @@ void init_Hash_code(Hash_code* code)
{
code->x[0] = 0;
code->x[1] = 0;
}
}
void init_small_hash_table(small_hash_table* x)
{
x->size = 0;
x->buffer = NULL;
x->length = 0;
}
void clear_small_hash_table(small_hash_table* x)
{
x->length = 0;
}
void resize_small_hash_table(small_hash_table* x, uint64_t size)
{
if(size > x->size)
{
x->size = size;
x->buffer = (k_v*)realloc(x->buffer, x->size*sizeof(k_v));
}
}
void destory_small_hash_table(small_hash_table* x)
{
free(x->buffer);
}
void add_small_hash_table(small_hash_table* x, k_v* element)
{
if(x->length + 1 > x->size)
{
x->size = (x->length + 1) * 2;
x->buffer = (k_v*)realloc(x->buffer, x->size*sizeof(k_v));
}
x->buffer[x->length] = (*element);
x->length++;
}
//x > y, return 1; x < y, return -1, x == y, return 0
int compare_k_mer(k_v* x, k_v* y)
{
if(x->key.x[1] != y->key.x[1])
{
return x->key.x[1] > y->key.x[1] ? 1: -1;
}
else
{
if(x->key.x[0] != y->key.x[0])
{
return x->key.x[0] > y->key.x[0] ? 1: -1;
}
else
{
return 0;
}
}
}
int cmp_k_mer_kv(const void * a, const void * b)
{
int flag = compare_k_mer((k_v*)a, (k_v*)b);
if(flag == 0)
{
if ((*(k_v*)a).value != (*(k_v*)b).value)
{
return (*(k_v*)a).value > (*(k_v*)b).value ? 1: -1;
}
else
{
return 0;
}
}
else
{
return flag;
}
}
void sort_small_hash_table(small_hash_table* x)
{
qsort(x->buffer, x->length, sizeof(k_v), cmp_k_mer_kv);
}
inline long long firstEqual(k_v* arr, long long arrLen, k_v* key)
{
long long L = 0, R = arrLen - 1; //[L, R]
long long mid;
int flag;
while( L <= R)
{
mid = L + (R - L)/2;
flag = compare_k_mer(&(arr[mid]), key);
///arr[mid] >= key
if(flag >= 0)
{
R = mid - 1;
}
else
{
L = mid + 1;
}
}
if(L < arrLen && (flag = compare_k_mer(&(arr[L]), key) == 0))
{
return L;
}
return -1;
}
inline long long lastEqual(k_v* arr, long long arrLen, k_v* key)
{
long long L = 0, R = arrLen - 1; //[L, R]
long long mid;
int flag;
while( L <= R)
{
mid = L + (R - L)/2;
flag = compare_k_mer(&(arr[mid]), key);
///arr[mid] <= key
if(flag <= 0)
{
L = mid + 1;
}
else
{
R = mid - 1;
}
}
if(R >= 0 && ((flag = compare_k_mer(&(arr[R]), key)) == 0))
{
return R;
}
return -1;
}
int query_small_hash_table(small_hash_table* target, k_v* query, long long* l_end, long long* r_end)
{
(*l_end) = -1;
(*r_end) = -1;
long long left_end;
long long right_end;
left_end = firstEqual(target->buffer, target->length, query);
if(left_end != -1)
{
right_end = lastEqual(target->buffer + left_end, target->length - left_end, query) + left_end;
(*l_end) = left_end;
(*r_end) = right_end;
if(right_end == -1)
{
fprintf(stderr, "error\n");
}
return right_end - left_end + 1;
}
return 0;
}
+19
View File
@@ -21,6 +21,25 @@ typedef struct
} Hash_code;
typedef struct {
Hash_code key; ///k-mer itself
uint64_t value; ///offset
} k_v;
typedef struct {
k_v* buffer;
uint32_t size;
uint32_t length;
} small_hash_table;
void init_small_hash_table(small_hash_table* x);
void clear_small_hash_table(small_hash_table* x);
void resize_small_hash_table(small_hash_table* x, uint64_t size);
void destory_small_hash_table(small_hash_table* x);
void add_small_hash_table(small_hash_table* x, k_v* element);
void sort_small_hash_table(small_hash_table* x);
int compare_k_mer(k_v* x, k_v* y);
int query_small_hash_table(small_hash_table* target, k_v* query, long long* l_end, long long* r_end);
typedef struct
+187
View File
@@ -0,0 +1,187 @@
/* The MIT License
Copyright (c) 2008, 2011 Attractive Chaos <attractor@live.co.uk>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
// This is a simplified version of ksort.h
#ifndef AC_KSORT_H
#define AC_KSORT_H
#include <stdlib.h>
#include <string.h>
typedef struct {
void *left, *right;
int depth;
} ks_isort_stack_t;
#define member_size(type, member) sizeof(((type *)0)->member)
#define KSORT_SWAP(type_t, a, b) { register type_t t=(a); (a)=(b); (b)=t; }
#define KSORT_INIT(name, type_t, __sort_lt) \
static inline void __ks_insertsort_##name(type_t *s, type_t *t) \
{ \
type_t *i, *j, swap_tmp; \
for (i = s + 1; i < t; ++i) \
for (j = i; j > s && __sort_lt(*j, *(j-1)); --j) { \
swap_tmp = *j; *j = *(j-1); *(j-1) = swap_tmp; \
} \
} \
void ks_combsort_##name(size_t n, type_t a[]) \
{ \
const double shrink_factor = 1.2473309501039786540366528676643; \
int do_swap; \
size_t gap = n; \
type_t tmp, *i, *j; \
do { \
if (gap > 2) { \
gap = (size_t)(gap / shrink_factor); \
if (gap == 9 || gap == 10) gap = 11; \
} \
do_swap = 0; \
for (i = a; i < a + n - gap; ++i) { \
j = i + gap; \
if (__sort_lt(*j, *i)) { \
tmp = *i; *i = *j; *j = tmp; \
do_swap = 1; \
} \
} \
} while (do_swap || gap > 2); \
if (gap != 1) __ks_insertsort_##name(a, a + n); \
} \
void ks_introsort_##name(size_t n, type_t a[]) \
{ \
int d; \
ks_isort_stack_t *top, *stack; \
type_t rp, swap_tmp; \
type_t *s, *t, *i, *j, *k; \
\
if (n < 1) return; \
else if (n == 2) { \
if (__sort_lt(a[1], a[0])) { swap_tmp = a[0]; a[0] = a[1]; a[1] = swap_tmp; } \
return; \
} \
for (d = 2; 1ul<<d < n; ++d); \
stack = (ks_isort_stack_t*)malloc(sizeof(ks_isort_stack_t) * ((sizeof(size_t)*d)+2)); \
top = stack; s = a; t = a + (n-1); d <<= 1; \
while (1) { \
if (s < t) { \
if (--d == 0) { \
ks_combsort_##name(t - s + 1, s); \
t = s; \
continue; \
} \
i = s; j = t; k = i + ((j-i)>>1) + 1; \
if (__sort_lt(*k, *i)) { \
if (__sort_lt(*k, *j)) k = j; \
} else k = __sort_lt(*j, *i)? i : j; \
rp = *k; \
if (k != t) { swap_tmp = *k; *k = *t; *t = swap_tmp; } \
for (;;) { \
do ++i; while (__sort_lt(*i, rp)); \
do --j; while (i <= j && __sort_lt(rp, *j)); \
if (j <= i) break; \
swap_tmp = *i; *i = *j; *j = swap_tmp; \
} \
swap_tmp = *i; *i = *t; *t = swap_tmp; \
if (i-s > t-i) { \
if (i-s > 16) { top->left = s; top->right = i-1; top->depth = d; ++top; } \
s = t-i > 16? i+1 : t; \
} else { \
if (t-i > 16) { top->left = i+1; top->right = t; top->depth = d; ++top; } \
t = i-s > 16? i-1 : s; \
} \
} else { \
if (top == stack) { \
free(stack); \
__ks_insertsort_##name(a, a+n); \
return; \
} else { --top; s = (type_t*)top->left; t = (type_t*)top->right; d = top->depth; } \
} \
} \
}
#define ks_lt_generic(a, b) ((a) < (b))
#define ks_lt_str(a, b) (strcmp((a), (b)) < 0)
typedef const char *ksstr_t;
#define KSORT_INIT_GENERIC(type_t) KSORT_INIT(type_t, type_t, ks_lt_generic)
#define KSORT_INIT_STR KSORT_INIT(str, ksstr_t, ks_lt_str)
#define RS_MIN_SIZE 64
#define KRADIX_SORT_INIT(name, rstype_t, rskey, sizeof_key) \
typedef struct { \
rstype_t *b, *e; \
} rsbucket_##name##_t; \
void rs_insertsort_##name(rstype_t *beg, rstype_t *end) \
{ \
rstype_t *i; \
for (i = beg + 1; i < end; ++i) \
if (rskey(*i) < rskey(*(i - 1))) { \
rstype_t *j, tmp = *i; \
for (j = i; j > beg && rskey(tmp) < rskey(*(j-1)); --j) \
*j = *(j - 1); \
*j = tmp; \
} \
} \
void rs_sort_##name(rstype_t *beg, rstype_t *end, int n_bits, int s) \
{ \
rstype_t *i; \
int size = 1<<n_bits, m = size - 1; \
rsbucket_##name##_t *k, b[size], *be = b + size; \
for (k = b; k != be; ++k) k->b = k->e = beg; \
for (i = beg; i != end; ++i) ++b[rskey(*i)>>s&m].e; \
for (k = b + 1; k != be; ++k) \
k->e += (k-1)->e - beg, k->b = (k-1)->e; \
for (k = b; k != be;) { \
if (k->b != k->e) { \
rsbucket_##name##_t *l; \
if ((l = b + (rskey(*k->b)>>s&m)) != k) { \
rstype_t tmp = *k->b, swap; \
do { \
swap = tmp; tmp = *l->b; *l->b++ = swap; \
l = b + (rskey(tmp)>>s&m); \
} while (l != k); \
*k->b++ = tmp; \
} else ++k->b; \
} else ++k; \
} \
for (b->b = beg, k = b + 1; k != be; ++k) k->b = (k-1)->e; \
if (s) { \
s = s > n_bits? s - n_bits : 0; \
for (k = b; k != be; ++k) \
if (k->e - k->b > RS_MIN_SIZE) rs_sort_##name(k->b, k->e, n_bits, s); \
else if (k->e - k->b > 1) rs_insertsort_##name(k->b, k->e); \
} \
} \
void radix_sort_##name(rstype_t *beg, rstype_t *end) \
{ \
if (end - beg <= RS_MIN_SIZE) rs_insertsort_##name(beg, end); \
else rs_sort_##name(beg, end, 8, sizeof_key * 8 - 8); \
}
#endif
+110
View File
@@ -0,0 +1,110 @@
/* The MIT License
Copyright (c) 2008, by Attractive Chaos <attractor@live.co.uk>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/*
An example:
#include "kvec.h"
int main() {
kvec_t(int) array;
kv_init(array);
kv_push(int, array, 10); // append
kv_a(int, array, 20) = 5; // dynamic
kv_A(array, 20) = 4; // static
kv_destroy(array);
return 0;
}
*/
/*
2008-09-22 (0.1.0):
* The initial version.
*/
#ifndef AC_KVEC_H
#define AC_KVEC_H
#include <stdlib.h>
#define kv_roundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
#define kvec_t(type) struct { size_t n, m; type *a; }
#define kv_init(v) ((v).n = (v).m = 0, (v).a = 0)
#define kv_destroy(v) free((v).a)
#define kv_A(v, i) ((v).a[(i)])
#define kv_pop(v) ((v).a[--(v).n])
#define kv_size(v) ((v).n)
#define kv_max(v) ((v).m)
#define kv_resize(type, v, s) do { \
if ((v).m < (s)) { \
(v).m = (s); \
kv_roundup32((v).m); \
(v).a = (type*)realloc((v).a, sizeof(type) * (v).m); \
} \
} while (0)
#define kv_copy(type, v1, v0) do { \
if ((v1).m < (v0).n) kv_resize(type, v1, (v0).n); \
(v1).n = (v0).n; \
memcpy((v1).a, (v0).a, sizeof(type) * (v0).n); \
} while (0) \
#define kv_push(type, v, x) do { \
if ((v).n == (v).m) { \
(v).m = (v).m? (v).m<<1 : 2; \
(v).a = (type*)realloc((v).a, sizeof(type) * (v).m); \
} \
(v).a[(v).n++] = (x); \
} while (0)
#define kv_pushp(type, v, p) do { \
if ((v).n == (v).m) { \
(v).m = (v).m? (v).m<<1 : 2; \
(v).a = (type*)realloc((v).a, sizeof(type) * (v).m); \
} \
*(p) = &(v).a[(v).n++]; \
} while (0)
#define kv_a(type, v, i) ((v).m <= (size_t)(i)? \
((v).m = (v).n = (i) + 1, kv_roundup32((v).m), \
(v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0) \
: (v).n <= (size_t)(i)? (v).n = (i) \
: 0), (v).a[(i)]
#define kv_reverse(type, v, start) do { \
if ((v).m > 0 && (v).n > (start)) { \
size_t __i, __end = (v).n - (start); \
type *__a = (v).a + (start); \
for (__i = 0; __i < __end>>1; ++__i) { \
type __t = __a[__end - 1 - __i]; \
__a[__end - 1 - __i] = __a[__i]; __a[__i] = __t; \
} \
} \
} while (0)
#endif
+13 -8
View File
@@ -200,12 +200,6 @@ int main(int argc, char *argv[])
if (!CommandLine_process(argc, argv))
return 1;
/**
debug_edit_distance();
return 1;
**/
fprintf(stdout, "Will perform %d round of error correction...\n", number_of_round);
fprintf(stdout, "defined k_mer_min_freq by user: %d\n", k_mer_min_freq);
@@ -213,10 +207,21 @@ int main(int argc, char *argv[])
fprintf(stdout, "k-mer length: %d\n",k_mer_length);
fprintf(stdout, "coverage: %d\n",coverage);
fprintf(stdout, "read_graph: %d\n", read_graph);
fprintf(stdout, "adapterLen: %d\n", adapterLen);
fflush(stdout);
if(required_read_name)
{
fprintf(stdout, "required_read_name: %s\n", required_read_name);
}
Correct_Reads(number_of_round);
return 1;
}