Files
hifiasm/Hash_Table.cpp
2019-11-13 20:18:11 -05:00

3378 lines
99 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "Hash_Table.h"
#include "Process_Read.h"
#include "Correct.h"
#include "CommandLines.h"
#include "kmer.h"
#include <pthread.h>
#include "ksort.h"
pthread_mutex_t output_mutex;
#define overlap_region_key(a) ((a).y_id)
KRADIX_SORT_INIT(overlap_region_sort, overlap_region, overlap_region_key, member_size(overlap_region, y_id))
void overlap_region_sort_y_id(overlap_region *a, long long n)
{
radix_sort_overlap_region_sort(a, a + n);
}
void Init_Heap(HeapSq* HBT)
{
HBT->MaxSize = 1000;
HBT->heap = (ElemType*)malloc(HBT->MaxSize*sizeof(ElemType));
HBT->index_i = (uint64_t*)malloc(HBT->MaxSize*sizeof(uint64_t));
HBT->len = 0;
}
void destory_Heap(HeapSq* HBT)
{
free(HBT->heap);
free(HBT->index_i);
}
void clear_Heap(HeapSq* HBT)
{
HBT->len = 0;
}
inline int cmp_ElemType_back_back(ElemType* x, ElemType* y)
{
long long r_pos_x, r_pos_y;
if (x->node.strand < y->node.strand)
{
return 1;
}
else if (x->node.strand > y->node.strand)
{
return 2;
}
else
{
if (x->node.readID < y->node.readID)
{
return 1;
}
else if (x->node.readID > y->node.readID)
{
return 2;
}
else
{
r_pos_x = x->node.offset - x->node.self_offset;
r_pos_y = y->node.offset - y->node.self_offset;
///if (x->node.offset < y->node.offset)
if (r_pos_x < r_pos_y)
{
return 1;
}
///else if (x->node.offset > y->node.offset)
else if (r_pos_x > r_pos_y)
{
return 2;
}
else
{
if (x->node.self_offset < y->node.self_offset)
{
return 1;
}
else if (x->node.self_offset > y->node.self_offset)
{
return 2;
}
else ///如果r_pos_x和self_offset都相等那么offset肯定也相等也没必要再比了
{
return 0;
}
}
}
}
}
inline int cmp_ElemType_back(ElemType* x, ElemType* y)
{
long long r_pos_x, r_pos_y;
if (x->node.readID < y->node.readID)
{
return 1;
}
else if (x->node.readID > y->node.readID)
{
return 2;
}
else
{ if (x->node.strand < y->node.strand)
{
return 1;
}
else if (x->node.strand > y->node.strand)
{
return 2;
}
else
{
r_pos_x = x->node.offset - x->node.self_offset;
r_pos_y = y->node.offset - y->node.self_offset;
///if (x->node.offset < y->node.offset)
if (r_pos_x < r_pos_y)
{
return 1;
}
///else if (x->node.offset > y->node.offset)
else if (r_pos_x > r_pos_y)
{
return 2;
}
else
{
if (x->node.self_offset < y->node.self_offset)
{
return 1;
}
else if (x->node.self_offset > y->node.self_offset)
{
return 2;
}
else ///如果r_pos_x和self_offset都相等那么offset肯定也相等也没必要再比了
{
return 0;
}
}
}
}
}
inline int cmp_ElemType(ElemType* x, ElemType* y)
{
if (x->node.readID < y->node.readID)
{
return 1;
}
else if (x->node.readID > y->node.readID)
{
return 2;
}
else
{ if (x->node.strand < y->node.strand)
{
return 1;
}
else if (x->node.strand > y->node.strand)
{
return 2;
}
else
{
if(x->node.offset < y->node.offset)
{
return 1;
}
else if(x->node.offset > y->node.offset)
{
return 2;
}
else
{
if (x->node.self_offset < y->node.self_offset)
{
return 1;
}
else if (x->node.self_offset > y->node.self_offset)
{
return 2;
}
else ///如果r_pos_x和self_offset都相等那么offset肯定也相等也没必要再比了
{
return 0;
}
}
}
}
}
inline void Insert_Heap(HeapSq* HBT, ElemType* x)
{
long long i, j;
if (HBT->len == HBT->MaxSize) //若堆满将数组空间扩展为原来的2倍
{
HBT->MaxSize = 2*HBT->MaxSize;
HBT->heap = (ElemType*)realloc(HBT->heap, HBT->MaxSize*sizeof(ElemType));
HBT->index_i = (uint64_t*)realloc(HBT->index_i,HBT->MaxSize*sizeof(uint64_t));
}
HBT->heap[HBT->len] = *x; //向堆尾添加新元素
HBT->len++; //堆长度加1
i = HBT->len - 1; //i指向待调整元素的位置即其数组下标初始指向新元素所在的堆尾位置
while (i != 0)
{
j = (i - 1) / 2; //j指向下标为i的元素的双亲
///if (x >= HBT->heap[j]) //若新元素大于待调整元素的双亲,则比较调整结束,退出循环
///1: x<y
if (cmp_ElemType(x, &HBT->heap[j])!=1)
break;
HBT->heap[i] = HBT->heap[j]; //将双亲元素下移到待调整元素的位置
i = j; //使待调整位置变为其双亲位置,进行下一次循环
}
HBT->heap[i] = *x;//把新元素调整到最终位置
}
inline int DeleteHeap(HeapSq* HBT, ElemType* get)
{
ElemType temp, x;
int i, j;
if (HBT->len == 0)
{
return 0;
}
temp = HBT->heap[0]; //暂存堆顶元素
HBT->len--;
if (HBT->len == 0) //若删除操作后堆为空则返回
{
*get = temp;
return 2;
}
x = HBT->heap[HBT->len]; //将待调整的原堆尾元素暂存x中以便放入最终位置
i = 0; //用i指向待调整元素的位置初始指向堆顶位置
j = 2 * i + 1;//用j指向i的左孩子位置初始指向下标为1的位置
while (j <= HBT->len - 1)//寻找待调整元素的最终位置,每次使孩子元素上移一层,调整到孩子为空时止
{
///if (j < HBT->len - 1 && HBT->heap[j] > HBT->heap[j+1])//若存在右孩子且较小使j指向右孩子
if (j < HBT->len - 1 && cmp_ElemType(&HBT->heap[j], &HBT->heap[j + 1]) == 2)
j++;
///if (x <= HBT->heap[j]) //若x比其较小的孩子还小则调整结束退出循环
if (cmp_ElemType(&x, &HBT->heap[j])!=2)
break;
HBT->heap[i] = HBT->heap[j];//否则,将孩子元素移到双亲位置
i = j; //将待调整位置变为其较小的孩子位置
j = 2 * i + 1;//将j变为新的待调整位置的左孩子位置继续下一次循环
}
HBT->heap[i] = x; //把x放到最终位置
//返回原堆顶元素
*get = temp;
return 1;
}
void init_overlap_region_alloc(overlap_region_alloc* list)
{
list->size = 1000;
list->length = 0;
///list->list = (overlap_region*)malloc(sizeof(overlap_region)*list->size);
list->list = (overlap_region*)calloc(list->size, sizeof(overlap_region));
long long i;
for (i = 0; i < list->size; i++)
{
init_fake_cigar(&(list->list[i].f_cigar));
}
}
void clear_overlap_region_alloc(overlap_region_alloc* list)
{
list->length = 0;
list->mapped_overlaps_length = 0;
int i = 0;
for (i = 0; i < list->size; i++)
{
list->list[i].w_list_length = 0;
clear_fake_cigar(&(list->list[i].f_cigar));
}
}
void destory_overlap_region_alloc(overlap_region_alloc* list)
{
int i = 0;
for (i = 0; i < list->size; i++)
{
if (list->list[i].w_list_size != 0)
{
free(list->list[i].w_list);
}
destory_fake_cigar(&(list->list[i].f_cigar));
}
free(list->list);
}
int get_fake_gap_pos(Fake_Cigar* x, int index)
{
return (x->buffer[index]>>32);
}
int get_fake_gap_shift(Fake_Cigar* x, int index)
{
uint32_t tmp = ((uint32_t)(x->buffer[index]));
int result;
if(tmp & ((uint32_t)1))
{
tmp = tmp >> 1;
result = tmp;
result = result * -1;
}
else
{
tmp = tmp >> 1;
result = tmp;
}
return result;
}
///r->length = Get_READ_LENGTH((*R_INF), ID);
void append_overlap_region_alloc(overlap_region_alloc* list, overlap_region* tmp, All_reads* R_INF)
{
if (list->length + 1 > list->size)
{
list->size = list->size * 2;
list->list = (overlap_region*)realloc(list->list, sizeof(overlap_region)*list->size);
///新分配空间要初始化
memset(list->list + (list->size/2), 0, sizeof(overlap_region)*(list->size/2));
}
if (list->length!=0 &&
list->list[list->length - 1].y_id==tmp->y_id
)
{
if(list->list[list->length - 1].shared_seed >= tmp->shared_seed)
{
return;
}
else
{
list->length--;
}
}
if(tmp->x_pos_s <= tmp->y_pos_s)
{
tmp->y_pos_s = tmp->y_pos_s - tmp->x_pos_s;
tmp->x_pos_s = 0;
}
else
{
tmp->x_pos_s = tmp->x_pos_s - tmp->y_pos_s;
tmp->y_pos_s = 0;
}
tmp->x_pos_e = Get_READ_LENGTH((*R_INF), tmp->x_id) - tmp->x_pos_s - 1;
tmp->y_pos_e = Get_READ_LENGTH((*R_INF), tmp->y_id) - tmp->y_pos_s - 1;
if(tmp->x_pos_e <= tmp->y_pos_e)
{
tmp->y_pos_e = tmp->y_pos_s + tmp->x_pos_e;
tmp->x_pos_e = tmp->x_pos_s + tmp->x_pos_e;
}
else
{
tmp->x_pos_e = tmp->x_pos_s + tmp->y_pos_e;
tmp->y_pos_e = tmp->y_pos_s + tmp->y_pos_e;
}
///y的区间方向永远是0
///x有可能是1
///如果x是1那我们把它逆过来
if (tmp->x_pos_strand == 1)
{
list->list[list->length].x_id = tmp->x_id;
list->list[list->length].x_pos_e = Get_READ_LENGTH((*R_INF), tmp->x_id) - tmp->x_pos_s - 1;
list->list[list->length].x_pos_s = Get_READ_LENGTH((*R_INF), tmp->x_id) - tmp->x_pos_e - 1;
list->list[list->length].x_pos_strand = 0;
list->list[list->length].y_id = tmp->y_id;
list->list[list->length].y_pos_e = Get_READ_LENGTH((*R_INF), tmp->y_id) - tmp->y_pos_s - 1;
list->list[list->length].y_pos_s = Get_READ_LENGTH((*R_INF), tmp->y_id) - tmp->y_pos_e - 1;
list->list[list->length].y_pos_strand = 1;
// resize_fake_cigar(&(list->list[list->length].f_cigar), (tmp->f_cigar.length + 2));
// add_fake_cigar(&(list->list[list->length].f_cigar), list->list[list->length].x_pos_s, 0);
// long long distance_gap;
// long long pre_distance_gap = 0;
// long long i = 0;
// for (i = 0; i < tmp->f_cigar.length; i++)
// {
// distance_gap = get_fake_gap_shift(&(tmp->f_cigar), i);
// if(distance_gap != pre_distance_gap)
// {
// pre_distance_gap = distance_gap;
// add_fake_cigar(&(list->list[list->length].f_cigar),
// Get_READ_LENGTH((*R_INF), tmp->x_id) - get_fake_gap_pos(&(tmp->f_cigar), i) - 1,
// pre_distance_gap);
// }
// }
// if(get_fake_gap_pos(&(list->list[list->length].f_cigar),
// list->list[list->length].f_cigar.length - 1) != list->list[list->length].x_pos_e)
// {
// add_fake_cigar(&(list->list[list->length].f_cigar),
// list->list[list->length].x_pos_e,
// get_fake_gap_shift(&(list->list[list->length].f_cigar),
// list->list[list->length].f_cigar.length - 1));
// }
}
else
{
list->list[list->length].x_id = tmp->x_id;
list->list[list->length].x_pos_e = tmp->x_pos_e;
list->list[list->length].x_pos_s = tmp->x_pos_s;
list->list[list->length].x_pos_strand = tmp->x_pos_strand;
list->list[list->length].y_id = tmp->y_id;
list->list[list->length].y_pos_e = tmp->y_pos_e;
list->list[list->length].y_pos_s = tmp->y_pos_s;
list->list[list->length].y_pos_strand = tmp->y_pos_strand;
// resize_fake_cigar(&(list->list[list->length].f_cigar), (tmp->f_cigar.length + 2));
// add_fake_cigar(&(list->list[list->length].f_cigar), list->list[list->length].x_pos_s, 0);
// long long distance_self_pos = tmp->x_pos_e - tmp->x_pos_s;
// long long distance_pos = tmp->y_pos_e - tmp->y_pos_s;
// long long init_distance_gap = distance_pos - distance_self_pos;
// long long pre_distance_gap = init_distance_gap;
// long long distance_gap;
// long long i = 0;
// for (i = tmp->f_cigar.length - 1; i >= 0; i--)
// {
// distance_gap = get_fake_gap_shift(&(tmp->f_cigar), i);
// if(distance_gap != pre_distance_gap)
// {
// pre_distance_gap = distance_gap;
// add_fake_cigar(&(list->list[list->length].f_cigar),
// get_fake_gap_pos(&(tmp->f_cigar), i), init_distance_gap - pre_distance_gap);
// }
// }
// if(get_fake_gap_pos(&(list->list[list->length].f_cigar),
// list->list[list->length].f_cigar.length - 1) != list->list[list->length].x_pos_e)
// {
// add_fake_cigar(&(list->list[list->length].f_cigar),
// list->list[list->length].x_pos_e,
// get_fake_gap_shift(&(list->list[list->length].f_cigar),
// list->list[list->length].f_cigar.length - 1));
// }
/******************************for debug********************************/
// distance_self_pos = tmp->x_pos_e - tmp->x_pos_s;
// distance_pos = tmp->y_pos_e - tmp->y_pos_s;
// distance_gap = distance_pos - distance_self_pos;
// fprintf(stderr, "\nx_s: %d, x_e: %d, y_s: %d, y_e: %d, distance_gap: %d\n",
// list->list[list->length].x_pos_s, list->list[list->length].x_pos_e,
// list->list[list->length].y_pos_s, list->list[list->length].y_pos_e, distance_gap);
// for (i = 0; i < list->list[list->length].f_cigar.length; i++)
// {
// fprintf(stderr, "##i: %d, gap_pos_in_x: %d, gap_shift: %d\n",
// i, get_fake_gap_pos(&(list->list[list->length].f_cigar), i),
// get_fake_gap_shift(&(list->list[list->length].f_cigar), i));
// }
// for (i = 0; i < tmp->f_cigar.length; i++)
// {
// fprintf(stderr, "**i: %d, gap_pos_in_x: %d, gap_shift: %d\n",
// i, get_fake_gap_pos(&(tmp->f_cigar), i),
// get_fake_gap_shift(&(tmp->f_cigar), i));
// }
/******************************for debug********************************/
}
list->list[list->length].shared_seed = tmp->shared_seed;
list->list[list->length].align_length = 0;
list->list[list->length].is_match = 0;
list->list[list->length].non_homopolymer_errors = 0;
list->length++;
}
void append_overlap_region_alloc_from_existing(overlap_region_alloc* list, overlap_region* tmp, All_reads* R_INF)
{
if (list->length + 1 > list->size)
{
list->size = list->size * 2;
list->list = (overlap_region*)realloc(list->list, sizeof(overlap_region)*list->size);
///新分配空间要初始化
memset(list->list + (list->size/2), 0, sizeof(overlap_region)*(list->size/2));
}
if (list->length!=0 &&
list->list[list->length - 1].y_id==tmp->y_id
)
{
if(list->list[list->length - 1].shared_seed >= tmp->shared_seed)
{
return;
}
else
{
list->length--;
}
}
if(tmp->x_pos_s <= tmp->y_pos_s)
{
tmp->y_pos_s = tmp->y_pos_s - tmp->x_pos_s;
tmp->x_pos_s = 0;
}
else
{
tmp->x_pos_s = tmp->x_pos_s - tmp->y_pos_s;
tmp->y_pos_s = 0;
}
tmp->x_pos_e = Get_READ_LENGTH((*R_INF), tmp->x_id) - tmp->x_pos_s - 1;
tmp->y_pos_e = Get_READ_LENGTH((*R_INF), tmp->y_id) - tmp->y_pos_s - 1;
if(tmp->x_pos_e <= tmp->y_pos_e)
{
tmp->y_pos_e = tmp->y_pos_s + tmp->x_pos_e;
tmp->x_pos_e = tmp->x_pos_s + tmp->x_pos_e;
}
else
{
tmp->x_pos_e = tmp->x_pos_s + tmp->y_pos_e;
tmp->y_pos_e = tmp->y_pos_s + tmp->y_pos_e;
}
// if(tmp->x_pos_strand != 0)
// {
// fprintf(stderr, "error\n");
// }
list->list[list->length].x_id = tmp->x_id;
list->list[list->length].x_pos_e = tmp->x_pos_e;
list->list[list->length].x_pos_s = tmp->x_pos_s;
list->list[list->length].x_pos_strand = tmp->x_pos_strand;
list->list[list->length].y_id = tmp->y_id;
list->list[list->length].y_pos_e = tmp->y_pos_e;
list->list[list->length].y_pos_s = tmp->y_pos_s;
list->list[list->length].y_pos_strand = tmp->y_pos_strand;
list->list[list->length].shared_seed = tmp->shared_seed;
list->list[list->length].align_length = 0;
list->list[list->length].is_match = 0;
list->list[list->length].non_homopolymer_errors = 0;
list->length++;
// fprintf(stderr, "shared_seed: %d, x_pos_s: %d, x_pos_e: %d, y_pos_s: %d, y_pos_e: %d, list->length: %d\n",
// tmp->shared_seed, tmp->x_pos_s, tmp->x_pos_e, tmp->y_pos_s, tmp->y_pos_e, list->length);
// fprintf(stderr, "*****x_pos_s: %d, x_pos_e: %d, y_pos_s: %d, y_pos_e: %d, list->length: %d\n",
// list->list[list->length - 1].x_pos_s, list->list[list->length - 1].x_pos_e,
// list->list[list->length - 1].y_pos_s, list->list[list->length - 1].y_pos_e,
// list->length);
}
int append_inexact_overlap_region_alloc(overlap_region_alloc* list, overlap_region* tmp, All_reads* R_INF)
{
if (list->length + 1 > list->size)
{
list->size = list->size * 2;
list->list = (overlap_region*)realloc(list->list, sizeof(overlap_region)*list->size);
///新分配空间要初始化
memset(list->list + (list->size/2), 0, sizeof(overlap_region)*(list->size/2));
}
if (list->length!=0 &&
list->list[list->length - 1].y_id==tmp->y_id
)
{
if(list->list[list->length - 1].shared_seed >= tmp->shared_seed)
{
return 0;
}
else
{
list->length--;
}
}
if(tmp->x_pos_s <= tmp->y_pos_s)
{
tmp->y_pos_s = tmp->y_pos_s - tmp->x_pos_s;
tmp->x_pos_s = 0;
}
else
{
tmp->x_pos_s = tmp->x_pos_s - tmp->y_pos_s;
tmp->y_pos_s = 0;
}
long long x_right_length = Get_READ_LENGTH((*R_INF), tmp->x_id) - tmp->x_pos_e - 1;
long long y_right_length = Get_READ_LENGTH((*R_INF), tmp->y_id) - tmp->y_pos_e - 1;
if(x_right_length <= y_right_length)
{
tmp->x_pos_e = Get_READ_LENGTH((*R_INF), tmp->x_id) - 1;
tmp->y_pos_e = tmp->y_pos_e + x_right_length;
}
else
{
tmp->x_pos_e = tmp->x_pos_e + y_right_length;
tmp->y_pos_e = Get_READ_LENGTH((*R_INF), tmp->y_id) - 1;
}
if (tmp->x_pos_strand == 1)
{
list->list[list->length].x_id = tmp->x_id;
list->list[list->length].x_pos_e = Get_READ_LENGTH((*R_INF), tmp->x_id) - tmp->x_pos_s - 1;
list->list[list->length].x_pos_s = Get_READ_LENGTH((*R_INF), tmp->x_id) - tmp->x_pos_e - 1;
list->list[list->length].x_pos_strand = 0;
list->list[list->length].y_id = tmp->y_id;
list->list[list->length].y_pos_e = Get_READ_LENGTH((*R_INF), tmp->y_id) - tmp->y_pos_s - 1;
list->list[list->length].y_pos_s = Get_READ_LENGTH((*R_INF), tmp->y_id) - tmp->y_pos_e - 1;
list->list[list->length].y_pos_strand = 1;
resize_fake_cigar(&(list->list[list->length].f_cigar), (tmp->f_cigar.length + 2));
add_fake_cigar(&(list->list[list->length].f_cigar), list->list[list->length].x_pos_s, 0);
long long distance_gap;
long long pre_distance_gap = 0;
long long i = 0;
for (i = 0; i < tmp->f_cigar.length; i++)
{
distance_gap = get_fake_gap_shift(&(tmp->f_cigar), i);
if(distance_gap != pre_distance_gap)
{
pre_distance_gap = distance_gap;
add_fake_cigar(&(list->list[list->length].f_cigar),
Get_READ_LENGTH((*R_INF), tmp->x_id) - get_fake_gap_pos(&(tmp->f_cigar), i) - 1,
pre_distance_gap);
}
}
if(get_fake_gap_pos(&(list->list[list->length].f_cigar),
list->list[list->length].f_cigar.length - 1) != list->list[list->length].x_pos_e)
{
add_fake_cigar(&(list->list[list->length].f_cigar),
list->list[list->length].x_pos_e,
get_fake_gap_shift(&(list->list[list->length].f_cigar),
list->list[list->length].f_cigar.length - 1));
}
/******************************for debug********************************/
// long long distance_self_pos = tmp->x_pos_e - tmp->x_pos_s;
// long long distance_pos = tmp->y_pos_e - tmp->y_pos_s;
// distance_gap = distance_pos - distance_self_pos;
// if(distance_gap !=
// get_fake_gap_shift(&(list->list[list->length].f_cigar),
// list->list[list->length].f_cigar.length - 1))
// {
// fprintf(stderr, "error\n");
// }
// long long distance_self_pos = tmp->x_pos_e - tmp->x_pos_s;
// long long distance_pos = tmp->y_pos_e - tmp->y_pos_s;
// distance_gap = distance_pos - distance_self_pos;
// fprintf(stderr, "\nx_s: %d, x_e: %d, y_s: %d, y_e: %d, distance_gap: %d, xLen: %d\n",
// list->list[list->length].x_pos_s, list->list[list->length].x_pos_e,
// list->list[list->length].y_pos_s, list->list[list->length].y_pos_e, distance_gap,
// Get_READ_LENGTH((*R_INF), tmp->x_id));
// for (i = 0; i < list->list[list->length].f_cigar.length; i++)
// {
// fprintf(stderr, "##i: %d, gap_pos_in_x: %d, gap_shift: %d\n",
// i, get_fake_gap_pos(&(list->list[list->length].f_cigar), i),
// get_fake_gap_shift(&(list->list[list->length].f_cigar), i));
// }
// for (i = 0; i < tmp->f_cigar.length; i++)
// {
// fprintf(stderr, "**i: %d, gap_pos_in_x: %d, gap_shift: %d\n",
// i, get_fake_gap_pos(&(tmp->f_cigar), i),
// get_fake_gap_shift(&(tmp->f_cigar), i));
// }
/******************************for debug********************************/
}
else
{
list->list[list->length].x_id = tmp->x_id;
list->list[list->length].x_pos_e = tmp->x_pos_e;
list->list[list->length].x_pos_s = tmp->x_pos_s;
list->list[list->length].x_pos_strand = tmp->x_pos_strand;
list->list[list->length].y_id = tmp->y_id;
list->list[list->length].y_pos_e = tmp->y_pos_e;
list->list[list->length].y_pos_s = tmp->y_pos_s;
list->list[list->length].y_pos_strand = tmp->y_pos_strand;
resize_fake_cigar(&(list->list[list->length].f_cigar), (tmp->f_cigar.length + 2));
add_fake_cigar(&(list->list[list->length].f_cigar), list->list[list->length].x_pos_s, 0);
long long distance_self_pos = tmp->x_pos_e - tmp->x_pos_s;
long long distance_pos = tmp->y_pos_e - tmp->y_pos_s;
long long init_distance_gap = distance_pos - distance_self_pos;
long long pre_distance_gap = init_distance_gap;
long long distance_gap;
long long i = 0;
for (i = tmp->f_cigar.length - 1; i >= 0; i--)
{
distance_gap = get_fake_gap_shift(&(tmp->f_cigar), i);
if(distance_gap != pre_distance_gap)
{
pre_distance_gap = distance_gap;
add_fake_cigar(&(list->list[list->length].f_cigar),
get_fake_gap_pos(&(tmp->f_cigar), i), init_distance_gap - pre_distance_gap);
}
}
if(get_fake_gap_pos(&(list->list[list->length].f_cigar),
list->list[list->length].f_cigar.length - 1) != list->list[list->length].x_pos_e)
{
add_fake_cigar(&(list->list[list->length].f_cigar),
list->list[list->length].x_pos_e,
get_fake_gap_shift(&(list->list[list->length].f_cigar),
list->list[list->length].f_cigar.length - 1));
}
/******************************for debug********************************/
// distance_self_pos = tmp->x_pos_e - tmp->x_pos_s;
// distance_pos = tmp->y_pos_e - tmp->y_pos_s;
// distance_gap = distance_pos - distance_self_pos;
// if(distance_gap !=
// get_fake_gap_shift(&(list->list[list->length].f_cigar),
// list->list[list->length].f_cigar.length - 1))
// {
// fprintf(stderr, "error\n");
// }
// distance_self_pos = tmp->x_pos_e - tmp->x_pos_s;
// distance_pos = tmp->y_pos_e - tmp->y_pos_s;
// distance_gap = distance_pos - distance_self_pos;
// fprintf(stderr, "\nx_s: %d, x_e: %d, y_s: %d, y_e: %d, distance_gap: %d\n",
// list->list[list->length].x_pos_s, list->list[list->length].x_pos_e,
// list->list[list->length].y_pos_s, list->list[list->length].y_pos_e, distance_gap);
// for (i = 0; i < list->list[list->length].f_cigar.length; i++)
// {
// fprintf(stderr, "##i: %d, gap_pos_in_x: %d, gap_shift: %d\n",
// i, get_fake_gap_pos(&(list->list[list->length].f_cigar), i),
// get_fake_gap_shift(&(list->list[list->length].f_cigar), i));
// }
// for (i = 0; i < tmp->f_cigar.length; i++)
// {
// fprintf(stderr, "**i: %d, gap_pos_in_x: %d, gap_shift: %d\n",
// i, get_fake_gap_pos(&(tmp->f_cigar), i),
// get_fake_gap_shift(&(tmp->f_cigar), i));
// }
/******************************for debug********************************/
}
list->list[list->length].shared_seed = tmp->shared_seed;
list->list[list->length].align_length = 0;
list->list[list->length].is_match = 0;
list->list[list->length].non_homopolymer_errors = 0;
list->list[list->length].strong = 0;
list->length++;
return 1;
}
void append_overlap_region_alloc_debug(overlap_region_alloc* list, overlap_region* tmp)
{
if (list->length + 1 > list->size)
{
list->size = list->size * 2;
list->list = (overlap_region*)realloc(list->list, sizeof(overlap_region)*list->size);
}
list->list[list->length].x_id = tmp->x_id;
list->list[list->length].x_pos_e = tmp->x_pos_e;
list->list[list->length].x_pos_s = tmp->x_pos_s;
list->list[list->length].x_pos_strand = tmp->x_pos_strand;
list->list[list->length].y_id = tmp->y_id;
list->list[list->length].y_pos_e = tmp->y_pos_e;
list->list[list->length].y_pos_s = tmp->y_pos_s;
list->list[list->length].y_pos_strand = tmp->y_pos_strand;
list->list[list->length].shared_seed = tmp->shared_seed;
list->length++;
}
void debug_overlap_region(Candidates_list* candidates, overlap_region_alloc* overlap_list, uint64_t readID)
{
uint64_t i = 0;
uint64_t total_length = 0;
uint64_t pre_total_length = 0;
uint64_t current_ID;
uint64_t current_stand;
long long current_pos_diff;
long long current_self_pos;
long long tmp_pos_distance;
long long tmp_self_pos_distance;
long long constant_distance = 5;
double error_rate = 0.05;
for ( i = 0; i < overlap_list->length; i++)
{
pre_total_length = total_length;
total_length = total_length + overlap_list->list[i].shared_seed;
uint64_t j = 0;
current_ID = candidates->list[pre_total_length].readID;
current_stand = candidates->list[pre_total_length].strand;
current_pos_diff = candidates->list[pre_total_length].offset - candidates->list[pre_total_length].self_offset;
current_self_pos = candidates->list[pre_total_length].self_offset;
for (j = pre_total_length; j < total_length; j++)
{
if(current_ID != candidates->list[j].readID ||
current_stand != candidates->list[j].strand)
{
fprintf(stderr, "ERROR Overlap 1!\n");
}
///这个一定是正值
tmp_pos_distance = candidates->list[j].offset - candidates->list[j].self_offset - current_pos_diff;
///这个不一定是正值
tmp_self_pos_distance = candidates->list[j].self_offset - current_self_pos;
if (tmp_self_pos_distance < 0)
{
fprintf(stderr, "ERROR Overlap 3!\n");
}
if (tmp_self_pos_distance >= 0)
{
tmp_self_pos_distance = tmp_self_pos_distance * error_rate + constant_distance;
if (tmp_pos_distance >= tmp_self_pos_distance)
{
fprintf(stderr, "ERROR Overlap 4!\n");
}
}
}
if (total_length < candidates->length)
{
j = total_length;
if (current_ID == candidates->list[j].readID &&
current_stand == candidates->list[j].strand)
{
///这个一定是正值
tmp_pos_distance = candidates->list[j].offset - candidates->list[j].self_offset - current_pos_diff;
///这个不一定是正值
tmp_self_pos_distance = candidates->list[j].self_offset - current_self_pos;
if (tmp_self_pos_distance >= 0)
{
tmp_self_pos_distance = tmp_self_pos_distance * error_rate + constant_distance;
if (tmp_pos_distance < tmp_self_pos_distance)
{
fprintf(stderr, "ERROR Overlap 5!\n");
}
}
}
}
}
if (total_length != candidates->length)
{
fprintf(stderr, "ERROR Overlap 2!\n");
fprintf(stderr, "total_length: %llu\n", total_length);
fprintf(stderr, "candidates->length: %llu\n", candidates->length);
}
}
void print_overlap_region(Candidates_list* candidates, overlap_region_alloc* overlap_list, All_reads* R_INF)
{
pthread_mutex_lock(&output_mutex);
uint64_t i = 0;
for ( i = 0; i < overlap_list->length; i++)
{
fprintf(stderr, "************i: %llu***********\n", i);
fprintf(stderr, "x: %llu, %llu, %llu, %llu, %llu\n",
overlap_list->list[i].x_id,overlap_list->list[i].x_pos_s,
overlap_list->list[i].x_pos_e, overlap_list->list[i].x_pos_strand,
Get_READ_LENGTH((*R_INF), overlap_list->list[i].x_id)
);
fprintf(stderr, "y: %llu, %llu, %llu, %llu, %llu\n",
overlap_list->list[i].y_id,overlap_list->list[i].y_pos_s,
overlap_list->list[i].y_pos_e, overlap_list->list[i].y_pos_strand,
Get_READ_LENGTH((*R_INF), overlap_list->list[i].y_id)
);
}
fprintf(stderr, "#######################\nLength: %llu\n", candidates->length);
for (i = 0; i < candidates->length; i++)
{
fprintf(stderr, "\ni: %llu\n", i);
fprintf(stderr, "strand: %llu\n", candidates->list[i].strand);
fprintf(stderr, "readID: %llu\n", candidates->list[i].readID);
fprintf(stderr, "diff: %lld\n", candidates->list[i].offset - candidates->list[i].self_offset);
fprintf(stderr, "offset: %lld\n", candidates->list[i].offset);
fprintf(stderr, "self_offset: %lld\n", candidates->list[i].self_offset);
}
pthread_mutex_unlock(&output_mutex);
}
int cmp_by_x_pos_s(const void * a, const void * b)
{
if ((*(overlap_region*)a).x_pos_s > (*(overlap_region*)b).x_pos_s)
{
return 1;
}
else if ((*(overlap_region*)a).x_pos_s < (*(overlap_region*)b).x_pos_s)
{
return -1;
}
else
{
if ((*(overlap_region*)a).x_pos_e > (*(overlap_region*)b).x_pos_e)
{
return 1;
}
else if ((*(overlap_region*)a).x_pos_e < (*(overlap_region*)b).x_pos_e)
{
return -1;
}
else
{
return 0;
}
}
}
int cmp_by_x_pos_e(const void * a, const void * b)
{
if ((*(overlap_region*)a).x_pos_e > (*(overlap_region*)b).x_pos_e)
{
return 1;
}
else if ((*(overlap_region*)a).x_pos_e < (*(overlap_region*)b).x_pos_e)
{
return -1;
}
else
{
if ((*(overlap_region*)a).x_pos_s > (*(overlap_region*)b).x_pos_s)
{
return 1;
}
else if ((*(overlap_region*)a).x_pos_s < (*(overlap_region*)b).x_pos_s)
{
return -1;
}
else
{
return 0;
}
}
}
///r->length = Get_READ_LENGTH((*R_INF), ID);
void calculate_overlap_region(Candidates_list* candidates, overlap_region_alloc* overlap_list,
uint64_t readID, uint64_t readLength, All_reads* R_INF)
{
overlap_region tmp_region;
uint64_t i = 0;
long long current_pos_diff;
long long current_self_pos;
uint64_t current_ID;
uint64_t current_stand;
long long tmp_pos_distance;
long long tmp_self_pos_distance;
long long constant_distance = 5;
double error_rate = 0.05;
if (candidates->length == 0)
{
return;
}
i = 0;
while (i < candidates->length)
{
current_pos_diff = candidates->list[i].offset - candidates->list[i].self_offset;
current_self_pos = candidates->list[i].self_offset;
current_ID = candidates->list[i].readID;
current_stand = candidates->list[i].strand;
tmp_region.shared_seed = 1;
///这个是查询read的信息
tmp_region.x_id = readID;
tmp_region.x_pos_s = candidates->list[i].self_offset;
tmp_region.x_pos_e = candidates->list[i].self_offset;
tmp_region.x_pos_strand = current_stand;
///这个是被查询的read的信息
tmp_region.y_id = current_ID;
tmp_region.y_pos_s = candidates->list[i].offset;
tmp_region.y_pos_e = candidates->list[i].offset;
tmp_region.y_pos_strand = 0; ///永远是0
i++;
while (i < candidates->length)
{
if (current_ID == candidates->list[i].readID &&
current_stand == candidates->list[i].strand)
{
///这个一定是正值
tmp_pos_distance = candidates->list[i].offset - candidates->list[i].self_offset - current_pos_diff;
///这个不一定是正值
tmp_self_pos_distance = candidates->list[i].self_offset - current_self_pos;
if(tmp_self_pos_distance < 0)
{
///fprintf(stderr, "tmp_self_pos_distance: %d\n", tmp_self_pos_distance);
tmp_self_pos_distance = tmp_self_pos_distance * -1;
///fprintf(stderr, "tmp_self_pos_distance: %d\n", tmp_self_pos_distance);
}
///if (tmp_self_pos_distance >= 0)
{
tmp_self_pos_distance = tmp_self_pos_distance * error_rate + constant_distance;
if (tmp_pos_distance < tmp_self_pos_distance)
{
/****************************may have bugs********************************/
///i++;
// tmp_region.x_pos_e = candidates->list[i].self_offset;
// tmp_region.y_pos_e = candidates->list[i].offset;
/****************************may have bugs********************************/
tmp_region.shared_seed++;
if(candidates->list[i].self_offset < tmp_region.x_pos_s)
{
tmp_region.x_pos_s = candidates->list[i].self_offset;
}
if(candidates->list[i].self_offset > tmp_region.x_pos_e)
{
tmp_region.x_pos_e = candidates->list[i].self_offset;
}
if(candidates->list[i].offset < tmp_region.y_pos_s)
{
tmp_region.y_pos_s = candidates->list[i].offset;
}
if(candidates->list[i].offset > tmp_region.y_pos_e)
{
tmp_region.y_pos_e = candidates->list[i].offset;
}
/****************************may have bugs********************************/
i++;
/****************************may have bugs********************************/
continue;
}
}
}
break;
}
///自己和自己重叠的要排除
///if (tmp_region.x_id != tmp_region.y_id && tmp_region.shared_seed > 1)
if (tmp_region.x_id != tmp_region.y_id)
{
append_overlap_region_alloc(overlap_list, &tmp_region, R_INF);
}
}
///以x_pos_e即结束位置为主元排序
///qsort(overlap_list->list, overlap_list->length, sizeof(overlap_region), cmp_by_x_pos_e);
qsort(overlap_list->list, overlap_list->length, sizeof(overlap_region), cmp_by_x_pos_s);
///debug_overlap_region(candidates, overlap_list, readID);
///print_overlap_region(candidates, overlap_list, R_INF);
}
void debug_chain(k_mer_hit* a, long long a_n, Chain_Data* dp)
{
long long i, j, current_j;
long long selfLen, indels;
long long distance_self_pos, distance_pos, distance_gap;
for (i = 0; i < a_n; ++i)
{
selfLen = indels = 0;
j = i;
while (j >= 0)
{
current_j = j;
j = dp->pre[j];
if(j != -1)
{
distance_self_pos = a[current_j].self_offset - a[j].self_offset;
distance_pos = a[current_j].offset - a[j].offset;
distance_gap = distance_pos > distance_self_pos? distance_pos - distance_self_pos : distance_self_pos - distance_pos;
indels += distance_gap;
selfLen += distance_self_pos;
}
}
if(indels != dp->indels[i])
{
fprintf(stderr, "indels: %d, dp->indels[i]: %d\n",
indels, dp->indels[i]);
}
if(selfLen != dp->self_length[i])
{
fprintf(stderr, "selfLen: %d, dp->self_length[i]: %d\n",
selfLen, dp->self_length[i]);
}
}
}
///double band_width_threshold = 0.05;
void chain_DP(k_mer_hit* a, long long a_n, Chain_Data* dp, overlap_region* result,
double band_width_threshold)
{
long long i, j;
long long self_pos, pos, max_j, max_i, max_score, score, n_skip;
long long distance_pos, distance_self_pos, distance_gap, log_distance_gap, distance_min;
///double band_width_threshold = 0.05;
double band_width_penalty = 1 / band_width_threshold;
long long min_score = k_mer_length;
long long max_indels, max_self_length;
double gap_rate;
long long total_indels, total_self_length;
resize_Chain_Data(dp, a_n);
// fill the score and backtrack arrays
for (i = 0; i < a_n; ++i)
{
pos = a[i].offset;
self_pos = a[i].self_offset;
max_j = -1;
max_score = min_score;
n_skip = 0;
max_indels = 0;
max_self_length = 0;
///may have a pre-cut condition for j
for (j = i - 1; j >= 0; --j)
{
distance_pos = pos - a[j].offset;
distance_self_pos = self_pos - a[j].self_offset;
///a has been sorted by a[].offset
///note for a, we do not have any two elements that have both equal offsets and self_offsets
///but there maybe two elements that have equal offsets or equal self_offsets
if(distance_pos == 0 || distance_self_pos <= 0)
{
continue;
}
distance_gap = distance_pos > distance_self_pos? distance_pos - distance_self_pos : distance_self_pos - distance_pos;
total_indels = dp->indels[j] + distance_gap;
total_self_length = dp->self_length[j] + distance_self_pos;
if(total_indels > band_width_threshold * total_self_length)
{
continue;
}
distance_min = distance_pos < distance_self_pos? distance_pos:distance_self_pos;
score = distance_min < min_score? distance_min : min_score;
/**
log_distance_gap = distance_gap? ilog2_32(distance_gap) : 0;
score -= (long long)(distance_gap * 0.01 * min_score) + (log_distance_gap/2);
**/
gap_rate = (double)((double)(total_indels)/(double)(total_self_length));
///if the gap rate > 0.05, score will be negative
score -= (long long)(gap_rate * score * band_width_penalty);
score += dp->score[j];
if(score > max_score)
{
max_score = score;
max_j = j;
max_indels = total_indels;
max_self_length = total_self_length;
if (n_skip > 0)
{
n_skip--;
}
}
}
dp->score[i] = max_score;
dp->pre[i] = max_j;
dp->indels[i] = max_indels;
dp->self_length[i] = max_self_length;
}
///debug_chain(a, a_n, dp);
max_score = -1;
max_i = -1;
for (i = 0; i < a_n; ++i)
{
if(dp->score[i] > max_score)
{
max_score = dp->score[i];
max_i = i;
}
}
clear_fake_cigar(&(result->f_cigar));
i = max_i;
result->x_pos_e = a[i].self_offset;
result->y_pos_e = a[i].offset;
result->shared_seed = max_score;
distance_self_pos = result->x_pos_e - a[i].self_offset;
distance_pos = result->y_pos_e - a[i].offset;
long long pre_distance_gap = distance_pos - distance_self_pos;
///record first site
///the length of f_cigar should be at least 1
add_fake_cigar(&(result->f_cigar), a[i].self_offset, pre_distance_gap);
long long chainLen = 0;
if(result->x_pos_strand == 1)
{
while (i >= 0)
{
distance_self_pos = result->x_pos_e - a[i].self_offset;
distance_pos = result->y_pos_e - a[i].offset;
distance_gap = distance_pos - distance_self_pos;
if(distance_gap != pre_distance_gap)
{
pre_distance_gap = distance_gap;
///record this site
add_fake_cigar(&(result->f_cigar), a[i].self_offset, pre_distance_gap);
}
chainLen++;
result->x_pos_s = a[i].self_offset;
result->y_pos_s = a[i].offset;
i = dp->pre[i];
}
}
else
{
while (i >= 0)
{
distance_self_pos = result->x_pos_e - a[i].self_offset;
distance_pos = result->y_pos_e - a[i].offset;
distance_gap = distance_pos - distance_self_pos;
if(distance_gap == pre_distance_gap)
{
result->f_cigar.length--;
add_fake_cigar(&(result->f_cigar), a[i].self_offset, pre_distance_gap);
}
else
{
pre_distance_gap = distance_gap;
add_fake_cigar(&(result->f_cigar), a[i].self_offset, pre_distance_gap);
}
chainLen++;
result->x_pos_s = a[i].self_offset;
result->y_pos_s = a[i].offset;
i = dp->pre[i];
}
}
}
void debug_seed_offset(k_mer_hit* a, long long a_n, Chain_Data* dp, overlap_region* result,
All_reads* R_INF)
{
long long i;
long long max_score = -1;
long long max_i = -1;
for (i = 0; i < a_n; i++)
{
if(max_score < dp->score[i])
{
max_score = dp->score[i];
max_i = i;
}
}
if(max_score != result->shared_seed)
{
fprintf(stderr, "max_score: %d, result->shared_seed: %d, a_n: %d, dp->length: %d\n",
max_score, result->shared_seed, a_n, dp->length);
}
long long chainLen = 0;
i = max_i;
while (i >= 0)
{
chainLen++;
i = dp->pre[i];
}
long long* chain_x_pos = (long long*)malloc(sizeof(long long)*chainLen);
long long* chain_y_pos = (long long*)malloc(sizeof(long long)*chainLen);
long long chain_i;
i = max_i;
if(result->y_pos_strand == 0)
{
chain_i = chainLen - 1;
while (i >= 0)
{
chain_x_pos[chain_i] = a[i].self_offset;
chain_y_pos[chain_i] = a[i].offset;
chain_i--;
i = dp->pre[i];
}
}
else
{
chain_i = 0;
while (i >= 0)
{
chain_x_pos[chain_i] =
Get_READ_LENGTH((*R_INF), result->x_id) - a[i].self_offset - 1;
chain_y_pos[chain_i] =
Get_READ_LENGTH((*R_INF), result->y_id) - a[i].offset - 1;
chain_i++;
i = dp->pre[i];
}
}
chain_i = 0;
long long distance_self_pos;
long long distance_pos;
long long distance_gap;
for (i = 0; i < chainLen; i++)
{
distance_self_pos = chain_x_pos[i] - result->x_pos_s;
distance_pos = chain_y_pos[i] - result->y_pos_s;
distance_gap = distance_pos - distance_self_pos;
if(distance_gap != y_start_offset(chain_x_pos[i], &(result->f_cigar)))
{
fprintf(stderr, "distance_gap: %d, y_offset: %d\n", distance_gap,
y_start_offset(chain_x_pos[i], &(result->f_cigar)));
}
}
free(chain_x_pos);
free(chain_y_pos);
}
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)
{
overlap_region tmp_region;
uint64_t i = 0;
long long current_pos_diff;
long long current_self_pos;
uint64_t current_ID;
uint64_t current_stand;
long long tmp_pos_distance;
long long tmp_self_pos_distance;
long long constant_distance = 5;
double error_rate = 0.05;
if (candidates->length == 0)
{
return;
}
long long sub_region_beg;
long long sub_region_end;
init_fake_cigar(&(tmp_region.f_cigar));
i = 0;
while (i < candidates->length)
{
current_ID = candidates->list[i].readID;
current_stand = candidates->list[i].strand;
///这个是查询read的信息
tmp_region.x_id = readID;
tmp_region.x_pos_strand = current_stand;
///这个是被查询的read的信息
tmp_region.y_id = current_ID;
tmp_region.y_pos_strand = 0; ///永远是0
sub_region_beg = i;
sub_region_end = i;
i++;
while (i < candidates->length
&&
current_ID == candidates->list[i].readID
&&
current_stand == candidates->list[i].strand)
{
sub_region_end = i;
i++;
}
if (tmp_region.x_id == tmp_region.y_id)
{
continue;
}
chain_DP(candidates->list + sub_region_beg,
sub_region_end - sub_region_beg + 1, &(candidates->chainDP), &tmp_region, band_width_threshold);
///自己和自己重叠的要排除
///if (tmp_region.x_id != tmp_region.y_id && tmp_region.shared_seed > 1)
if (tmp_region.x_id != tmp_region.y_id)
{
///append_overlap_region_alloc(overlap_list, &tmp_region, R_INF);
/**
if(append_inexact_overlap_region_alloc(overlap_list, &tmp_region, R_INF))
{
debug_seed_offset(candidates->list + sub_region_beg,
sub_region_end - sub_region_beg + 1,
&(candidates->chainDP), &(overlap_list->list[overlap_list->length - 1]), R_INF);
}
**/
append_inexact_overlap_region_alloc(overlap_list, &tmp_region, R_INF);
}
}
destory_fake_cigar(&(tmp_region.f_cigar));
qsort(overlap_list->list, overlap_list->length, sizeof(overlap_region), cmp_by_x_pos_s);
}
void calculate_inexact_overlap_region(Candidates_list* candidates, overlap_region_alloc* overlap_list,
uint64_t readID, uint64_t readLength, All_reads* R_INF)
{
overlap_region tmp_region;
uint64_t i = 0;
long long current_pos_diff;
long long current_self_pos;
uint64_t current_ID;
uint64_t current_stand;
long long tmp_pos_distance;
long long tmp_self_pos_distance;
long long constant_distance = 5;
double error_rate = 0.05;
if (candidates->length == 0)
{
return;
}
i = 0;
while (i < candidates->length)
{
current_pos_diff = candidates->list[i].offset - candidates->list[i].self_offset;
current_self_pos = candidates->list[i].self_offset;
current_ID = candidates->list[i].readID;
current_stand = candidates->list[i].strand;
tmp_region.shared_seed = 1;
///这个是查询read的信息
tmp_region.x_id = readID;
tmp_region.x_pos_s = candidates->list[i].self_offset;
tmp_region.x_pos_e = candidates->list[i].self_offset;
tmp_region.x_pos_strand = current_stand;
///这个是被查询的read的信息
tmp_region.y_id = current_ID;
tmp_region.y_pos_s = candidates->list[i].offset;
tmp_region.y_pos_e = candidates->list[i].offset;
tmp_region.y_pos_strand = 0; ///永远是0
// if(memcmp("m64013_190412_043951/159056664/ccs", Get_NAME((*R_INF), readID),
// Get_NAME_LENGTH((*R_INF), readID)) == 0
// &&
// memcmp("m64013_190322_203854/42402522/ccs", Get_NAME((*R_INF), current_ID),
// Get_NAME_LENGTH((*R_INF), current_ID)) == 0)
// {
// fprintf(stderr, "***********i: %d, x_pos_s: %d, x_pos_e: %d, y_pos_s: %d, y_pos_e: %d\n",
// i, tmp_region.x_pos_s, tmp_region.x_pos_e, tmp_region.y_pos_s, tmp_region.y_pos_e);
// fprintf(stderr, "***********i: %d, self_offset: %d, offset: %d\n",
// i, candidates->list[i].self_offset, candidates->list[i].offset);
// }
i++;
while (i < candidates->length)
{
if (current_ID == candidates->list[i].readID &&
current_stand == candidates->list[i].strand)
{
///这个一定是正值
tmp_pos_distance = candidates->list[i].offset - candidates->list[i].self_offset - current_pos_diff;
///这个不一定是正值
tmp_self_pos_distance = candidates->list[i].self_offset - current_self_pos;
if(tmp_self_pos_distance < 0)
{
///fprintf(stderr, "tmp_self_pos_distance: %d\n", tmp_self_pos_distance);
tmp_self_pos_distance = tmp_self_pos_distance * -1;
///fprintf(stderr, "tmp_self_pos_distance: %d\n", tmp_self_pos_distance);
}
///if (tmp_self_pos_distance >= 0)
{
tmp_self_pos_distance = tmp_self_pos_distance * error_rate + constant_distance;
if (tmp_pos_distance < tmp_self_pos_distance)
{
/****************************may have bugs********************************/
///i++;
// tmp_region.x_pos_e = candidates->list[i].self_offset;
// tmp_region.y_pos_e = candidates->list[i].offset;
/****************************may have bugs********************************/
tmp_region.shared_seed++;
if(candidates->list[i].self_offset < tmp_region.x_pos_s)
{
tmp_region.x_pos_s = candidates->list[i].self_offset;
}
if(candidates->list[i].self_offset > tmp_region.x_pos_e)
{
tmp_region.x_pos_e = candidates->list[i].self_offset;
}
if(candidates->list[i].offset < tmp_region.y_pos_s)
{
tmp_region.y_pos_s = candidates->list[i].offset;
}
if(candidates->list[i].offset > tmp_region.y_pos_e)
{
tmp_region.y_pos_e = candidates->list[i].offset;
}
// if(memcmp("m64013_190412_043951/159056664/ccs", Get_NAME((*R_INF), readID),
// Get_NAME_LENGTH((*R_INF), readID)) == 0
// &&
// memcmp("m64013_190322_203854/42402522/ccs", Get_NAME((*R_INF), current_ID),
// Get_NAME_LENGTH((*R_INF), current_ID)) == 0)
// {
// fprintf(stderr, "i: %d, x_pos_s: %d, x_pos_e: %d, y_pos_s: %d, y_pos_e: %d\n",
// i, tmp_region.x_pos_s, tmp_region.x_pos_e, tmp_region.y_pos_s, tmp_region.y_pos_e);
// fprintf(stderr, "i: %d, self_offset: %d, offset: %d, tmp_pos_distance: %d, tmp_self_pos_distance: %d\n",
// i, candidates->list[i].self_offset, candidates->list[i].offset, tmp_pos_distance,
// tmp_self_pos_distance);
// }
/****************************may have bugs********************************/
i++;
/****************************may have bugs********************************/
continue;
}
}
}
break;
}
///自己和自己重叠的要排除
///if (tmp_region.x_id != tmp_region.y_id && tmp_region.shared_seed > 1)
if (tmp_region.x_id != tmp_region.y_id)
{
append_inexact_overlap_region_alloc(overlap_list, &tmp_region, 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 error_threshold)
{
long long length = region->x_pos_e - region->x_pos_s + 1;
///the length of window may large or small than WINDOW
/****************************may have bugs********************************/
long long num_windows = length / WINDOW + 4;
/****************************may have bugs********************************/
///w_list_length会在clear_overlap_region_alloc中定时清空
if (num_windows > region->w_list_size)
{
region->w_list_size = num_windows;
region->w_list = (window_list*)realloc(region->w_list, region->w_list_size*sizeof(window_list));
}
region->w_list[region->w_list_length].x_start = x_start;
region->w_list[region->w_list_length].x_end = x_end;
region->w_list[region->w_list_length].y_start = y_start;
region->w_list[region->w_list_length].y_end = y_end;
region->w_list[region->w_list_length].error = error;
region->w_list[region->w_list_length].cigar.length = -1;
region->w_list[region->w_list_length].extra_begin = extra_begin;
region->w_list[region->w_list_length].extra_end = extra_end;
region->w_list[region->w_list_length].error_threshold = error_threshold;
region->w_list_length++;
}
void init_k_mer_pos_list_alloc(k_mer_pos_list_alloc* list)
{
list->size = 1000;
list->length = 0;
//list->list = (k_mer_pos_list*)malloc(sizeof(k_mer_pos_list)*list->size);
list->list = (k_mer_pos_list*)calloc(list->size, sizeof(k_mer_pos_list));
}
void clear_k_mer_pos_list_alloc(k_mer_pos_list_alloc* list)
{
list->length = 0;
}
void destory_k_mer_pos_list_alloc(k_mer_pos_list_alloc* list)
{
free(list->list);
}
void append_k_mer_pos_list_alloc(k_mer_pos_list_alloc* list, k_mer_pos* n_list, uint64_t n_length,
uint64_t n_end_pos, uint8_t n_direction)
{
if (list->length + 1 > list->size)
{
list->size = list->size * 2;
list->list = (k_mer_pos_list*)realloc(list->list, sizeof(k_mer_pos_list)*list->size);
}
list->list[list->length].list = n_list;
list->list[list->length].length = n_length;
list->list[list->length].direction = n_direction;
list->list[list->length].end_pos = n_end_pos;
list->length++;
}
int cmp_k_mer_pos_list(const void * a, const void * b)
{
if ((*(k_mer_pos_list*)a).length > (*(k_mer_pos_list*)b).length)
{
return 1;
}
else if ((*(k_mer_pos_list*)a).length < (*(k_mer_pos_list*)b).length)
{
return -1;
}
else
{
return 0;
}
}
inline void append_pos_to_Candidates_list(Candidates_list* candidates, ElemType* x)
{
candidates->list[candidates->length] = x->node;
candidates->length++;
}
void test_single_list(Candidates_list* candidates, k_mer_pos* n_list, uint64_t n_lengh, uint64_t end_pos, uint64_t strand)
{
uint64_t i;
int j = 0;
for (i = 0; i < n_lengh; i++)
{
for (; j < candidates->length; j++)
{
if (
n_list[i].offset == candidates->list[j].offset
&&
n_list[i].readID == candidates->list[j].readID
&&
end_pos == candidates->list[j].self_offset
&&
strand == candidates->list[j].strand
)
{
break;
}
}
if (j == candidates->length)
{
fprintf(stderr, "ERROR 4\n");
}
}
}
void verify_merge_result(k_mer_pos_list_alloc* list, Candidates_list* candidates)
{
uint64_t total_length = 0;
uint64_t i = 0;
long long r_dis_x, r_dis_y;
for (i = 0; i < list->length; i++)
{
total_length = total_length + list->list[i].length;
}
if (total_length!=candidates->length)
{
fprintf(stderr, "ERROR length & size.\n");
}
for (i = 1; i < candidates->length; i++)
{
if (candidates->list[i].strand < candidates->list[i-1].strand)
{
fprintf(stderr, "ERROR -1\n");
}
else if (candidates->list[i].strand == candidates->list[i-1].strand)
{
if (candidates->list[i].readID < candidates->list[i-1].readID)
{
fprintf(stderr, "ERROR 0\n");
}
else if (candidates->list[i].readID == candidates->list[i-1].readID)
{
r_dis_x = candidates->list[i].offset - candidates->list[i].self_offset;
r_dis_y = candidates->list[i-1].offset - candidates->list[i-1].self_offset;
///if (candidates->list[i].offset < candidates->list[i-1].offset)
if (r_dis_x < r_dis_y)
{
fprintf(stderr, "ERROR 1\n");
}
///else if (candidates->list[i].offset == candidates->list[i-1].offset)
else if (r_dis_x == r_dis_y)
{
if (candidates->list[i].self_offset < candidates->list[i-1].self_offset)
{
fprintf(stderr, "ERROR 2\n");
}
}
}
}
}
uint64_t j = 0;
for (i = 0; i < list->length; i++)
{
test_single_list(candidates, list->list[i].list, list->list[i].length, list->list[i].end_pos, list->list[i].direction);
}
}
void output_to_stderr(Candidates_list* candidates)
{
uint64_t i = 0;
pthread_mutex_lock(&output_mutex);
fprintf(stderr, "************************\nLength: %llu\n", candidates->length);
for (i = 0; i < candidates->length; i++)
{
fprintf(stderr, "\ni: %llu\n", i);
fprintf(stderr, "strand: %llu\n", candidates->list[i].strand);
fprintf(stderr, "readID: %llu\n", candidates->list[i].readID);
fprintf(stderr, "diff: %lld\n", candidates->list[i].offset - candidates->list[i].self_offset);
fprintf(stderr, "offset: %lld\n", candidates->list[i].offset);
fprintf(stderr, "self_offset: %lld\n", candidates->list[i].self_offset);
}
pthread_mutex_unlock(&output_mutex);
}
void merge_k_mer_pos_list_alloc_heap_sort_back(k_mer_pos_list_alloc* list, Candidates_list* candidates, HeapSq* HBT)
{
clear_Heap(HBT);
uint64_t total_length = 0;
uint64_t i;
ElemType x, y;
///所有list的长度都不是0
///把各个表第一个元素加入到堆中
for (i = 0; i < list->length; i++)
{
x.ID = i;
x.node.offset = list->list[i].list[0].offset;
x.node.readID = list->list[i].list[0].readID;
x.node.self_offset = list->list[i].end_pos;
x.node.strand = list->list[i].direction;
Insert_Heap(HBT, &x);
HBT->index_i[i] = 1;
total_length = total_length + list->list[i].length;
}
candidates->length = 0;
if(total_length > candidates->size)
{
candidates->size = total_length;
candidates->list = (k_mer_hit*)realloc(candidates->list, sizeof(k_mer_hit)*candidates->size);
candidates->tmp = (k_mer_hit*)realloc(candidates->tmp, sizeof(k_mer_hit)*candidates->size);
}
uint64_t ID;
while (DeleteHeap(HBT, &x))
{
append_pos_to_Candidates_list(candidates, &x);
///x.ID说明是从第x.ID个列表中的这个节点已经从堆里出来了
///HBT->index_i[x.ID]是第x.ID个列表的当前元素的下标
i = HBT->index_i[x.ID];
ID = x.ID;
///fprintf(stderr, "x.ID: %llu, i: %llu, length: %llu\n", x.ID, i, list->list[x.ID].length);
if (i < list->list[x.ID].length)
{
y.ID = ID;
y.node.offset = list->list[x.ID].list[i].offset;
y.node.readID = list->list[x.ID].list[i].readID;
y.node.self_offset = list->list[x.ID].end_pos;
y.node.strand = list->list[x.ID].direction;
Insert_Heap(HBT, &y);
HBT->index_i[ID]++;
}
}
///verify_merge_result(list, candidates);
}
void merge_k_mer_pos_list_alloc_heap_sort(k_mer_pos_list_alloc* list, Candidates_list* candidates, HeapSq* HBT)
{
clear_Heap(HBT);
uint64_t total_length = 0;
uint64_t i;
ElemType x, y;
///所有list的长度都不是0
///把各个表第一个元素加入到堆中
for (i = 0; i < list->length; i++)
{
x.ID = i;
x.node.offset = list->list[i].list[0].offset;
x.node.readID = list->list[i].list[0].readID;
x.node.self_offset = list->list[i].end_pos;
x.node.strand = list->list[i].direction;
Insert_Heap(HBT, &x);
HBT->index_i[i] = 1;
total_length = total_length + list->list[i].length;
}
candidates->length = 0;
if(total_length > candidates->size)
{
candidates->size = total_length;
candidates->list = (k_mer_hit*)realloc(candidates->list, sizeof(k_mer_hit)*candidates->size);
candidates->tmp = (k_mer_hit*)realloc(candidates->tmp, sizeof(k_mer_hit)*candidates->size);
}
uint64_t ID;
int flag;
while (flag = DeleteHeap(HBT, &x))
{
append_pos_to_Candidates_list(candidates, &x);
///x.ID说明是从第x.ID个列表中的这个节点已经从堆里出来了
///HBT->index_i[x.ID]是第x.ID个列表的当前元素的下标
i = HBT->index_i[x.ID];
ID = x.ID;
if (flag == 2)
{
for (; i < list->list[x.ID].length; i++)
{
y.ID = ID;
y.node.offset = list->list[x.ID].list[i].offset;
y.node.readID = list->list[x.ID].list[i].readID;
y.node.self_offset = list->list[x.ID].end_pos;
y.node.strand = list->list[x.ID].direction;
append_pos_to_Candidates_list(candidates, &y);
}
break;
}
if (i < list->list[x.ID].length)
{
y.ID = ID;
y.node.offset = list->list[x.ID].list[i].offset;
y.node.readID = list->list[x.ID].list[i].readID;
y.node.self_offset = list->list[x.ID].end_pos;
y.node.strand = list->list[x.ID].direction;
Insert_Heap(HBT, &y);
HBT->index_i[ID]++;
}
}
///verify_merge_result(list, candidates);
///output_to_stderr(candidates);
}
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)
{
if(candidates->length + occ > candidates->size)
{
candidates->size = (candidates->length + occ) * 2;
candidates->list = (k_mer_hit*)realloc(candidates->list, sizeof(k_mer_hit)*candidates->size);
candidates->tmp = (k_mer_hit*)realloc(candidates->tmp, sizeof(k_mer_hit)*candidates->size);
}
long long i;
ElemType x;
for (i = 0; i < occ; i++)
{
x.node.offset = y_offset;
x.node.readID = y_id;
x.node.self_offset = list[i].value;
x.node.strand = y_strand;
append_pos_to_Candidates_list(candidates, &x);
}
}
///有bug找时间排一下
void merge_k_mer_pos_list_alloc_heap_sort_advance(k_mer_pos_list_alloc* list, Candidates_list* candidates, HeapSq* HBT)
{
uint64_t total_length = 0;
uint64_t i;
ElemType x, y;
/************************************forward*************************************************/
clear_Heap(HBT);
///所有list的长度都不是0
///把各个表第一个元素加入到堆中
for (i = 0; i < list->length; i++)
{
if (list->list[i].direction == 0)
{
x.ID = i;
x.node.offset = list->list[i].list[0].offset;
x.node.readID = list->list[i].list[0].readID;
x.node.self_offset = list->list[i].end_pos;
x.node.strand = list->list[i].direction;
Insert_Heap(HBT, &x);
HBT->index_i[i] = 1;
total_length = total_length + list->list[i].length;
}
}
candidates->length = 0;
if(total_length > candidates->size)
{
candidates->size = total_length;
candidates->list = (k_mer_hit*)realloc(candidates->list, sizeof(k_mer_hit)*candidates->size);
candidates->tmp = (k_mer_hit*)realloc(candidates->tmp, sizeof(k_mer_hit)*candidates->size);
}
uint64_t ID;
int flag;
while (flag = DeleteHeap(HBT, &x))
{
append_pos_to_Candidates_list(candidates, &x);
///x.ID说明是从第x.ID个列表中的这个节点已经从堆里出来了
///HBT->index_i[x.ID]是第x.ID个列表的当前元素的下标
i = HBT->index_i[x.ID];
ID = x.ID;
///fprintf(stderr, "x.ID: %llu, i: %llu, length: %llu\n", x.ID, i, list->list[x.ID].length);
/**
if (flag == 2)
{
for (; i < list->list[x.ID].length; i++)
{
y.ID = ID;
y.node.offset = list->list[x.ID].list[i].offset;
y.node.readID = list->list[x.ID].list[i].readID;
y.node.self_offset = list->list[x.ID].end_pos;
y.node.strand = list->list[x.ID].direction;
append_pos_to_Candidates_list(candidates, &y);
}
break;
}
**/
if (i < list->list[x.ID].length)
{
y.ID = ID;
y.node.offset = list->list[x.ID].list[i].offset;
y.node.readID = list->list[x.ID].list[i].readID;
y.node.self_offset = list->list[x.ID].end_pos;
y.node.strand = list->list[x.ID].direction;
Insert_Heap(HBT, &y);
HBT->index_i[ID]++;
}
}
/************************************reverse complement*************************************************/
clear_Heap(HBT);
///所有list的长度都不是0
///把各个表第一个元素加入到堆中
for (i = 0; i < list->length; i++)
{
if (list->list[i].direction == 1)
{
x.ID = i;
x.node.offset = list->list[i].list[0].offset;
x.node.readID = list->list[i].list[0].readID;
x.node.self_offset = list->list[i].end_pos;
x.node.strand = list->list[i].direction;
Insert_Heap(HBT, &x);
HBT->index_i[i] = 1;
total_length = total_length + list->list[i].length;
}
}
if(total_length > candidates->size)
{
candidates->size = total_length;
candidates->list = (k_mer_hit*)realloc(candidates->list, sizeof(k_mer_hit)*candidates->size);
candidates->tmp = (k_mer_hit*)realloc(candidates->tmp, sizeof(k_mer_hit)*candidates->size);
}
while (flag = DeleteHeap(HBT, &x))
{
append_pos_to_Candidates_list(candidates, &x);
///x.ID说明是从第x.ID个列表中的这个节点已经从堆里出来了
///HBT->index_i[x.ID]是第x.ID个列表的当前元素的下标
i = HBT->index_i[x.ID];
ID = x.ID;
///fprintf(stderr, "x.ID: %llu, i: %llu, length: %llu\n", x.ID, i, list->list[x.ID].length);
/**
if (flag == 2)
{
for (; i < list->list[x.ID].length; i++)
{
y.ID = ID;
y.node.offset = list->list[x.ID].list[i].offset;
y.node.readID = list->list[x.ID].list[i].readID;
y.node.self_offset = list->list[x.ID].end_pos;
y.node.strand = list->list[x.ID].direction;
append_pos_to_Candidates_list(candidates, &y);
}
break;
}
**/
if (i < list->list[x.ID].length)
{
y.ID = ID;
y.node.offset = list->list[x.ID].list[i].offset;
y.node.readID = list->list[x.ID].list[i].readID;
y.node.self_offset = list->list[x.ID].end_pos;
y.node.strand = list->list[x.ID].direction;
Insert_Heap(HBT, &y);
HBT->index_i[ID]++;
}
}
}
void merge_k_mer_pos_list_alloc(k_mer_pos_list_alloc* list, Candidates_list* candidates)
{
qsort(list->list, list->length, sizeof(k_mer_pos_list), cmp_k_mer_pos_list);
uint64_t i;
for (i = 0; i < list->length; i++)
{
/**
if (i > 0 && (list->list[i].length < list->list[i-1].length || list->list[i].length == 0 || list->list[i-1].length == 0))
{
fprintf(stderr, "ERROR\n");
}
**/
merge_Candidates_list(candidates, list->list[i].list, list->list[i].length,
list->list[i].end_pos, list->list[i].direction);
}
}
void init_Count_Table(Count_Table** table)
{
*table = kh_init(COUNT64);
}
void init_Pos_Table(Pos_Table** table)
{
*table = kh_init(POS64);
}
void init_Total_Count_Table(int k, Total_Count_Table* TCB)
{
if(k>64)
{
fprintf(stdout, "k-mer is too long. The length of k-mer must <= 64.");
fflush(stdout);
exit(0);
}
int total_bits = k * 2;
TCB->prefix_bits = PREFIX_BITS;
TCB->suffix_bits = total_bits - TCB->prefix_bits;
if (TCB->suffix_bits > MAX_SUFFIX_BITS)
{
TCB->suffix_bits = MAX_SUFFIX_BITS;
TCB->prefix_bits = total_bits - TCB->suffix_bits;
}
///TCB->suffix_mode = (1ULL<<TCB->suffix_bits) - 1;
///这个右移是安全的因为TCB->suffix_bits不可能是0
TCB->suffix_mode = ALL >> (64 - TCB->suffix_bits);
///number of small hash table
TCB->size = (1ULL<<TCB->prefix_bits);
TCB->sub_h = (Count_Table**)malloc(sizeof(Count_Table*)*TCB->size);
TCB->sub_h_lock = (Hash_table_spin_lock*)malloc(sizeof(Hash_table_spin_lock)*TCB->size);
memset(TCB->sub_h_lock, 0, sizeof(Hash_table_spin_lock)*TCB->size);
int i = 0;
for (i = 0; i < TCB->size; i++)
{
init_Count_Table(&(TCB->sub_h[i]));
TCB->sub_h_lock[i].lock = 0;
}
TCB->non_unique_k_mer = 0;
}
void init_Total_Pos_Table(Total_Pos_Table* TCB, Total_Count_Table* pre_TCB)
{
TCB->prefix_bits = pre_TCB->prefix_bits;
TCB->suffix_bits = pre_TCB->suffix_bits;
TCB->suffix_mode = pre_TCB->suffix_mode;
TCB->size = pre_TCB->size;
TCB->useful_k_mer = 0;
TCB->total_occ = 0;
TCB->k_mer_index = NULL;
TCB->sub_h_lock = (Hash_table_spin_lock*)malloc(sizeof(Hash_table_spin_lock)*TCB->size);
memset(TCB->sub_h_lock, 0, sizeof(Hash_table_spin_lock)*TCB->size);
TCB->sub_h = (Pos_Table**)malloc(sizeof(Pos_Table*)*TCB->size);
TCB->pos = NULL;
int i = 0;
for (i = 0; i < TCB->size; i++)
{
init_Pos_Table(&(TCB->sub_h[i]));
TCB->sub_h_lock[i].lock = 0;
}
}
void destory_Total_Count_Table(Total_Count_Table* TCB)
{
int i;
for (i = 0; i < TCB->size; i++)
{
kh_destroy(COUNT64, TCB->sub_h[i]);
}
free(TCB->sub_h);
free(TCB->sub_h_lock);
}
void destory_Total_Pos_Table(Total_Pos_Table* TCB)
{
free(TCB->k_mer_index);
free(TCB->sub_h_lock);
free(TCB->pos);
int i;
for (i = 0; i < TCB->size; i++)
{
kh_destroy(POS64, TCB->sub_h[i]);
}
free(TCB->sub_h);
}
void write_Total_Pos_Table(Total_Pos_Table* TCB, char* read_file_name)
{
fprintf(stdout, "Writing index to disk ...... \n");
char* index_name = (char*)malloc(strlen(read_file_name)+5);
sprintf(index_name, "%s.idx", read_file_name);
FILE* fp = fopen(index_name, "w");
fwrite(&adapterLen, sizeof(adapterLen), 1, fp);
fwrite(&k_mer_min_freq, sizeof(k_mer_min_freq), 1, fp);
fwrite(&k_mer_max_freq, sizeof(k_mer_max_freq), 1, fp);
fwrite(&TCB->prefix_bits, sizeof(TCB->prefix_bits), 1, fp);
fwrite(&TCB->suffix_bits, sizeof(TCB->suffix_bits), 1, fp);
fwrite(&TCB->suffix_mode, sizeof(TCB->suffix_mode), 1, fp);
fwrite(&TCB->size, sizeof(TCB->size), 1, fp);
fwrite(&TCB->useful_k_mer, sizeof(TCB->useful_k_mer), 1, fp);
fwrite(&TCB->total_occ, sizeof(TCB->total_occ), 1, fp);
fwrite(TCB->k_mer_index, sizeof(uint64_t), TCB->useful_k_mer+1, fp);
fwrite(TCB->pos, sizeof(k_mer_pos), TCB->total_occ, fp);
int i;
for (i = 0; i < TCB->size; i++)
{
kh_write(POS64, TCB->sub_h[i], fp);
}
free(index_name);
fclose(fp);
fprintf(stdout, "Index has been written.\n");
}
int load_Total_Pos_Table(Total_Pos_Table* TCB, char* read_file_name)
{
fprintf(stdout, "Loading index to disk ...... \n");
char* index_name = (char*)malloc(strlen(read_file_name)+5);
sprintf(index_name, "%s.idx", read_file_name);
FILE* fp = fopen(index_name, "r");
if (!fp)
{
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(&k_mer_min_freq, sizeof(k_mer_min_freq), 1, fp);
fread(&k_mer_max_freq, sizeof(k_mer_max_freq), 1, fp);
fread(&TCB->prefix_bits, sizeof(TCB->prefix_bits), 1, fp);
fread(&TCB->suffix_bits, sizeof(TCB->suffix_bits), 1, fp);
fread(&TCB->suffix_mode, sizeof(TCB->suffix_mode), 1, fp);
fread(&TCB->size, sizeof(TCB->size), 1, fp);
fread(&TCB->useful_k_mer, sizeof(TCB->useful_k_mer), 1, fp);
fread(&TCB->total_occ, sizeof(TCB->total_occ), 1, fp);
if (TCB->useful_k_mer+1)
{
TCB->k_mer_index = (uint64_t*)malloc(sizeof(uint64_t)*(TCB->useful_k_mer+1));
fread(TCB->k_mer_index, sizeof(uint64_t), TCB->useful_k_mer+1, fp);
}
else
{
TCB->k_mer_index = NULL;
}
if (TCB->total_occ)
{
TCB->pos = (k_mer_pos*)malloc(sizeof(k_mer_pos)*TCB->total_occ);
fread(TCB->pos, sizeof(k_mer_pos), TCB->total_occ, fp);
}
else
{
TCB->pos = NULL;
}
TCB->sub_h_lock = (Hash_table_spin_lock*)malloc(sizeof(Hash_table_spin_lock)*TCB->size);
memset(TCB->sub_h_lock, 0, sizeof(Hash_table_spin_lock)*TCB->size);
TCB->sub_h = (Pos_Table**)malloc(sizeof(Pos_Table*)*TCB->size);
int i;
for (i = 0; i < TCB->size; i++)
{
init_Pos_Table(&(TCB->sub_h[i]));
TCB->sub_h_lock[i].lock = 0;
kh_load(POS64, TCB->sub_h[i], fp);
}
free(index_name);
fclose(fp);
fprintf(stdout, "Index has been loaded.\n");
return 1;
}
void Traverse_Counting_Table(Total_Count_Table* TCB, Total_Pos_Table* PCB, int k_mer_min_freq, int k_mer_max_freq)
{
int i;
Count_Table* h;
khint_t k;
uint64_t sub_key;
uint64_t sub_ID;
PCB->useful_k_mer = 0;
PCB->total_occ = 0;
///init_Total_Pos_Table(PCB, TCB);
khint_t t; ///这就是个迭代器
int absent;
/********************************************
hash_table(key) ----> PCB->k_mer_index ------> PCB->pos
********************************************/
for (i = 0; i < TCB->size; i++)
{
h = TCB->sub_h[i];
for (k = kh_begin(h); k != kh_end(h); ++k)
{
if (kh_exist(h, k)) // test if a bucket contains data
{
///只有符合频率范围要求的k-mer才会被加入到pos table中
if (kh_value(h, k)>=k_mer_min_freq && kh_value(h, k)<=k_mer_max_freq)
{
sub_ID = i;
sub_key = kh_key(h, k);
t = kh_put(POS64, PCB->sub_h[sub_ID], sub_key, &absent);
if (absent)
{
///kh_value(PCB->sub_h[sub_ID], t) = useful_k_mer + total_occ;
kh_value(PCB->sub_h[sub_ID], t) = PCB->useful_k_mer;
}
else ///哈希表中已有的元素
{
///kh_value(PCB->sub_h[sub_ID], t)++;
fprintf(stderr, "ERROR\n");
}
PCB->useful_k_mer++;
PCB->total_occ = PCB->total_occ + kh_value(h, k);
}
}
}
}
fprintf(stdout, "useful_k_mer: %lld\n",PCB->useful_k_mer);
fprintf(stdout, "total_occ: %lld\n",PCB->total_occ);
PCB->k_mer_index = (uint64_t*)malloc(sizeof(uint64_t)*(PCB->useful_k_mer+1));
PCB->k_mer_index[0] = 0;
PCB->total_occ = 0;
PCB->useful_k_mer = 0;
for (i = 0; i < TCB->size; i++)
{
h = TCB->sub_h[i];
for (k = kh_begin(h); k != kh_end(h); ++k)
{
if (kh_exist(h, k)) // test if a bucket contains data
{
if (kh_value(h, k)>=k_mer_min_freq && kh_value(h, k)<=k_mer_max_freq)
{
PCB->useful_k_mer++;
PCB->total_occ = PCB->total_occ + kh_value(h, k);
PCB->k_mer_index[PCB->useful_k_mer] = PCB->total_occ;
}
}
}
}
PCB->pos = (k_mer_pos*)malloc(sizeof(k_mer_pos)*PCB->total_occ);
memset(PCB->pos, 0, sizeof(k_mer_pos)*PCB->total_occ);
}
int cmp_k_mer_pos(const void * a, const void * b)
{
if ((*(k_mer_pos*)a).readID != (*(k_mer_pos*)b).readID)
{
return (*(k_mer_pos*)a).readID > (*(k_mer_pos*)b).readID ? 1 : -1;
}
else
{
if ((*(k_mer_pos*)a).offset != (*(k_mer_pos*)b).offset)
{
return (*(k_mer_pos*)a).offset > (*(k_mer_pos*)b).offset ? 1 : -1;
}
else
{
return 0;
}
}
}
void init_Chain_Data(Chain_Data* x)
{
x->length = 0;
x->size = 0;
x->score = NULL;
x->pre = NULL;
x->indels = NULL;
x->self_length = NULL;
}
void clear_Chain_Data(Chain_Data* x)
{
x->length = 0;
}
void destory_Chain_Data(Chain_Data* x)
{
free(x->score);
free(x->pre);
free(x->indels);
free(x->self_length);
}
void resize_Chain_Data(Chain_Data* x, long long size)
{
if(size > x->size)
{
x->size = size;
x->score = (long long*)realloc(x->score, x->size*sizeof(long long));
x->pre = (long long*)realloc(x->pre, x->size*sizeof(long long));
x->indels = (long long*)realloc(x->indels, x->size*sizeof(long long));
x->self_length = (long long*)realloc(x->self_length, x->size*sizeof(long long));
}
}
void init_Candidates_list(Candidates_list* l)
{
l->length = 0;
l->size = 0;
l->list = NULL;
l->tmp = NULL;
l->foward_pos = 0;
l->rc_pos = 0;
init_Chain_Data(&(l->chainDP));
}
void clear_Candidates_list(Candidates_list* l)
{
l->length = 0;
l->foward_pos = 0;
l->rc_pos = 0;
clear_Chain_Data(&(l->chainDP));
}
void destory_Candidates_list(Candidates_list* l)
{
free(l->list);
free(l->tmp);
destory_Chain_Data(&(l->chainDP));
}
///1是x小2是y小0是相等
inline int cmp_pos(k_mer_hit* x, k_mer_pos* y, uint64_t y_pos, uint8_t strand)
{
if (x->strand < strand)
{
return 1;
}
else if (x->strand > strand)
{
return 2;
}
else
{
if (x->readID < y->readID)
{
return 1;
}
else if (x->readID > y->readID)
{
return 2;
}
else
{
if (x->offset < y->offset)
{
return 1;
}
else if (x->offset > y->offset)
{
return 2;
}
else
{
if (x->self_offset < y_pos)
{
return 1;
}
else if (x->self_offset > y_pos)
{
return 2;
}
else
{
return 0;
}
}
}
}
}
void debug_merge_Candidates_list(Candidates_list* l, k_mer_pos* n_list, uint64_t n_lengh, uint64_t end_pos, uint64_t i,
uint64_t i_1, uint64_t i_2, uint64_t len1, uint64_t len2, uint64_t strand)
{
if (i != l->length)
{
fprintf(stderr, "ERROR\n");
fprintf(stderr, "i: %llu, l->length: %llu\n", i , l->length);
fprintf(stderr, "i_1: %llu, len1: %llu\n", i_1 , len1);
fprintf(stderr, "i_2: %llu, len2: %llu\n", i_2 , len2);
fprintf(stderr, "strand: %llu\n", strand);
}
for (i = 1; i < l->length; i++)
{
if (l->list[i].strand < l->list[i-1].strand)
{
fprintf(stderr, "ERROR -1\n");
}
else if (l->list[i].strand == l->list[i-1].strand)
{
if (l->list[i].readID < l->list[i-1].readID)
{
fprintf(stderr, "ERROR 0\n");
}
else if (l->list[i].readID == l->list[i-1].readID)
{
if (l->list[i].offset < l->list[i-1].offset)
{
fprintf(stderr, "ERROR 1\n");
}
else if (l->list[i].offset == l->list[i-1].offset)
{
if (l->list[i].self_offset < l->list[i-1].self_offset)
{
fprintf(stderr, "ERROR 2\n");
}
}
}
}
}
for (i = 0; i < n_lengh; i++)
{
int j = 0;
for (j = 0; j < l->length; j++)
{
if (
n_list[i].offset == l->list[j].offset
&&
n_list[i].readID == l->list[j].readID
&&
end_pos == l->list[j].self_offset
&&
strand == l->list[j].strand
)
{
break;
}
}
if (j == l->length)
{
fprintf(stderr, "ERROR 4\n");
}
}
for (i = 0; i < l->length - n_lengh; i++)
{
int j = 0;
for (j = 0; j < l->length; j++)
{
if (
l->tmp[i].offset == l->list[j].offset
&&
l->tmp[i].readID == l->list[j].readID
&&
l->tmp[i].self_offset == l->list[j].self_offset
&&
l->tmp[i].strand == l->list[j].strand
)
{
break;
}
}
if (j == l->length)
{
fprintf(stderr, "ERROR 5\n");
}
}
}
void merge_Candidates_list(Candidates_list* l, k_mer_pos* n_list, uint64_t n_lengh, uint64_t end_pos, int strand)
{
if (n_lengh == 0) ///不加这个就会巨慢
{
return;
}
if(l->length + n_lengh > l->size)
{
l->size = l->length + n_lengh;
l->list = (k_mer_hit*)realloc(l->list, sizeof(k_mer_hit)*l->size);
l->tmp = (k_mer_hit*)realloc(l->tmp, sizeof(k_mer_hit)*l->size);
}
int flag;
uint64_t len1, len2, i_1, i_2, i;
k_mer_hit *l_1;
k_mer_pos *l_2;
l_1 = l->list;
if (strand == 0)
{
///由于标号全是0则标号为1的位置不受影响(数组后半部分),可以直接复制过去
///需要从l_1 + l->rc_pos开始复制l->length-l->rc_pos个元素到l->tmp + l->rc_pos + n_lengh处
memcpy(l->tmp + l->rc_pos + n_lengh, l_1 + l->rc_pos, sizeof(k_mer_hit)*(l->length-l->rc_pos));
///l_1只需要从0扫描到l->rc_pos就好了
len1 = l->rc_pos;
i_1 = 0;
///此时目标数组没数据,
i = 0;
///更新l->rc_pos
l->rc_pos = l->rc_pos + n_lengh;
}
else
{
///如果strand==1则标号为0的位置不受影响(数组前半部分),可以直接复制过去
///从l_1开始复制l->rc_pos个元素到l->tmp
memcpy(l->tmp, l_1, sizeof(k_mer_hit)*l->rc_pos);
///l_1只需要从l->rc_pos扫描到末尾就好了
i_1 = l->rc_pos;
len1 = l->length;
///此时目标数组已经有了l->rc_pos
i = i_1;
///l->rc_pos不用更新
}
l_2 = n_list;
len2 = n_lengh;
i_2 = 0;
while (i_1<len1 && i_2<len2)
{
flag = cmp_pos(&l_1[i_1], &l_2[i_2], end_pos, strand);
///l_1小
if (flag == 1)
{
l->tmp[i].readID = l_1[i_1].readID;
l->tmp[i].offset = l_1[i_1].offset;
l->tmp[i].self_offset = l_1[i_1].self_offset;
l->tmp[i].strand = l_1[i_1].strand;
i_1++;
i++;
}
else ///l_2小或者l_1 == l_2
{
l->tmp[i].readID = l_2[i_2].readID;
l->tmp[i].offset = l_2[i_2].offset;
l->tmp[i].self_offset = end_pos;
l->tmp[i].strand = strand;
i_2++;
i++;
}
}
while (i_1<len1)
{
memcpy(l->tmp + i, l_1 + i_1, sizeof(k_mer_hit)*(len1-i_1));
i = i + len1-i_1;
i_1 = len1;
}
while (i_2<len2)
{
l->tmp[i].readID = l_2[i_2].readID;
l->tmp[i].offset = l_2[i_2].offset;
l->tmp[i].self_offset = end_pos;
l->tmp[i].strand = strand;
i_2++;
i++;
}
k_mer_hit* k;
k = l->list;
l->list = l->tmp;
l->tmp = k;
l->length = l->length + n_lengh;
/**
if (strand == 0)
{
i = l->length;
len1 = l->length - n_lengh;
}
debug_merge_Candidates_list(l, n_list, n_lengh, end_pos, i, i_1, i_2, len1, len2, strand);
**/
}
/********************************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)
{
if (n_lengh == 0) ///不加这个就会巨慢
{
return;
}
if(l->length + n_lengh > l->size)
{
l->size = l->length + n_lengh;
l->list = (k_mer_hit*)realloc(l->list, sizeof(k_mer_hit)*l->size);
l->tmp = (k_mer_hit*)realloc(l->tmp, sizeof(k_mer_hit)*l->size);
}
int flag;
uint64_t len1, len2, i_1, i_2, i;
k_mer_hit *l_1;
k_mer_pos *l_2;
l_1 = l->list;
len1 = l->length;
i_1 = 0;
l_2 = n_list;
len2 = n_lengh;
i_2 = 0;
i = 0;
while (i_1<len1 && i_2<len2)
{
flag = cmp_pos(&l_1[i_1], &l_2[i_2], end_pos, strand);
///l_1小
if (flag == 1)
{
l->tmp[i].readID = l_1[i_1].readID;
l->tmp[i].offset = l_1[i_1].offset;
l->tmp[i].self_offset = l_1[i_1].self_offset;
l->tmp[i].strand = l_1[i_1].strand;
i_1++;
i++;
}
else ///l_2小或者l_1 == l_2
{
l->tmp[i].readID = l_2[i_2].readID;
l->tmp[i].offset = l_2[i_2].offset;
l->tmp[i].self_offset = end_pos;
l->tmp[i].strand = strand;
i_2++;
i++;
}
}
while (i_1<len1)
{
l->tmp[i].readID = l_1[i_1].readID;
l->tmp[i].offset = l_1[i_1].offset;
l->tmp[i].self_offset = l_1[i_1].self_offset;
l->tmp[i].strand = l_1[i_1].strand;
i_1++;
i++;
}
while (i_2<len2)
{
l->tmp[i].readID = l_2[i_2].readID;
l->tmp[i].offset = l_2[i_2].offset;
l->tmp[i].self_offset = end_pos;
l->tmp[i].strand = strand;
i_2++;
i++;
}
k_mer_hit* k;
k = l->list;
l->list = l->tmp;
l->tmp = k;
l->length = l->length + n_lengh;
///debug_merge_Candidates_list(l, n_list, n_lengh, end_pos, i, i_1, i_2, len1, len2, strand);
}
/********************************for debug***************************************/
void debug_mode(uint64_t d, uint64_t thread_ID, uint64_t thread_num)
{
fprintf(stderr, "#%llu: Start debug_mode...\n", thread_ID);
uint64_t i;
for (i = thread_ID; i < 4,294,967,296; i = i + thread_num)
{
if(i%d != mod_d(0, i, d))
{
fprintf(stderr, "ERROR mode, i: %llu\n", i);
fprintf(stderr, "i mod d: %llu\n", i%d);
fprintf(stderr, "mod_d(0, i, d): %llu\n", mod_d(0, i, d));
}
}
fprintf(stderr, "#%llu: Finish debug_mode\n", thread_ID);
}
/********************************for debug***************************************/
void test_COUNT64()
{
uint64_t sb[7] = {5000000000, 6000000000, 7000000000, 8000000000, 9000000000, 10000000000 ,5000000000};
Count_Table* h;
///构建哈希表
init_Count_Table(&h);
int i;
khint_t k; ///这就是个迭代器
int absent;
for (i = 0; i < 7; i++)
{
///将5作为key插入到哈希表COUNT64中
///absent为0代表哈希表里面已经有这个key了
k = kh_put(COUNT64, h, sb[i], &absent);
///代表插入了一个哈希表中没有的元素
///则直接插入
if (absent)
{
kh_value(h, k) = i;
}
else ///哈希表中已有的元素
{
kh_value(h, k) = i;
}
}
for (i = 0; i < 7; i++)
{
///查询哈希表key为k
k = kh_get(COUNT64, h, sb[i]);
if (k != kh_end(h))
{
fprintf(stderr, "value: %d\n", kh_value(h, k));
}
else
{
fprintf(stderr, "not found!\n");
}
}
kh_destroy(COUNT64, h);
}
int cmp_candidates_list(const void * a, const void * b)
{
long long r_pos_a, r_pos_b;
if((*((k_mer_hit*)a)).strand != (*((k_mer_hit*)b)).strand)
{
return (*((k_mer_hit*)a)).strand > (*((k_mer_hit*)b)).strand ? 1: -1;
}
else
{
if((*((k_mer_hit*)a)).readID != (*((k_mer_hit*)b)).readID)
{
return (*((k_mer_hit*)a)).readID > (*((k_mer_hit*)b)).readID ? 1: -1;
}
else
{
r_pos_a = (*((k_mer_hit*)a)).offset - (*((k_mer_hit*)a)).self_offset;
r_pos_b = (*((k_mer_hit*)b)).offset - (*((k_mer_hit*)b)).self_offset;
if(r_pos_a != r_pos_b)
{
return r_pos_a > r_pos_b ? 1: -1;
}
else
{
if((*((k_mer_hit*)a)).self_offset != (*((k_mer_hit*)b)).self_offset)
{
return (*((k_mer_hit*)a)).self_offset > (*((k_mer_hit*)b)).self_offset ? 1: -1;
}
else
{
return 0;
}
}
}
}
}
void sort_candidates(Candidates_list* candidates, long long readID,
overlap_region_alloc* overlap_list, All_reads* R_INF)
{
qsort(candidates->list, candidates->length, sizeof(k_mer_hit), cmp_candidates_list);
overlap_region tmp_region;
uint64_t i = 0;
long long current_pos_diff;
long long current_self_pos;
uint64_t current_ID;
uint64_t current_stand;
long long tmp_pos_distance;
long long tmp_self_pos_distance;
long long constant_distance = 5;
double error_rate = 0.05;
if (candidates->length == 0)
{
return;
}
// i = 0;
// for (i = 0; i < candidates->length; i++)
// {
// fprintf(stderr, "i: %d, ada_offset: %d, offset: %d, self_offset: %d, strand: %d\n",
// i, candidates->list[i].offset - candidates->list[i].self_offset,
// candidates->list[i].offset, candidates->list[i].self_offset,
// candidates->list[i].strand);
// }
i = 0;
while (i < candidates->length)
{
current_pos_diff = candidates->list[i].offset - candidates->list[i].self_offset;
current_self_pos = candidates->list[i].self_offset;
current_ID = candidates->list[i].readID;
current_stand = candidates->list[i].strand;
tmp_region.shared_seed = 1;
///这个是查询read的信息
tmp_region.x_id = readID;
tmp_region.x_pos_s = candidates->list[i].self_offset;
tmp_region.x_pos_e = candidates->list[i].self_offset;
tmp_region.x_pos_strand = 0; ///永远是0
///这个是被查询的read的信息
tmp_region.y_id = current_ID;
tmp_region.y_pos_s = candidates->list[i].offset;
tmp_region.y_pos_e = candidates->list[i].offset;
tmp_region.y_pos_strand = candidates->list[i].strand;
i++;
while (i < candidates->length)
{
if (current_ID == candidates->list[i].readID &&
current_stand == candidates->list[i].strand)
{
///这个一定是正值
tmp_pos_distance = candidates->list[i].offset - candidates->list[i].self_offset - current_pos_diff;
///这个不一定是正值
tmp_self_pos_distance = candidates->list[i].self_offset - current_self_pos;
if(tmp_self_pos_distance < 0)
{
///fprintf(stderr, "tmp_self_pos_distance: %d\n", tmp_self_pos_distance);
tmp_self_pos_distance = tmp_self_pos_distance * -1;
///fprintf(stderr, "tmp_self_pos_distance: %d\n", tmp_self_pos_distance);
}
///if (tmp_self_pos_distance >= 0)
{
tmp_self_pos_distance = tmp_self_pos_distance * error_rate + constant_distance;
if (tmp_pos_distance < tmp_self_pos_distance)
{
/****************************may have bugs********************************/
///i++;
// tmp_region.x_pos_e = candidates->list[i].self_offset;
// tmp_region.y_pos_e = candidates->list[i].offset;
/****************************may have bugs********************************/
tmp_region.shared_seed++;
if(candidates->list[i].self_offset < tmp_region.x_pos_s)
{
tmp_region.x_pos_s = candidates->list[i].self_offset;
}
if(candidates->list[i].self_offset > tmp_region.x_pos_e)
{
tmp_region.x_pos_e = candidates->list[i].self_offset;
}
if(candidates->list[i].offset < tmp_region.y_pos_s)
{
tmp_region.y_pos_s = candidates->list[i].offset;
}
if(candidates->list[i].offset > tmp_region.y_pos_e)
{
tmp_region.y_pos_e = candidates->list[i].offset;
}
/****************************may have bugs********************************/
i++;
/****************************may have bugs********************************/
continue;
}
}
}
break;
}
///自己和自己重叠的要排除
///if (tmp_region.x_id != tmp_region.y_id && tmp_region.shared_seed > 1)
if (tmp_region.x_id != tmp_region.y_id)
{
// fprintf(stderr, "i: %lld, candidates->length: %lld, tmp_region->shared_seed: %lld, x_pos_s: %lld, x_pos_e: %lld, y_pos_s: %lld, y_pos_e: %lld\n",
// i, candidates->length, tmp_region.shared_seed, tmp_region.x_pos_s, tmp_region.x_pos_e, tmp_region.y_pos_s, tmp_region.y_pos_e);
// fprintf(stderr, "\n");
// fprintf(stderr, "shared_seed: %d, x_pos_s: %d, x_pos_e: %d, y_pos_s: %d, y_pos_e: %d\n",
// tmp_region.shared_seed, tmp_region.x_pos_s, tmp_region.x_pos_e, tmp_region.y_pos_s, tmp_region.y_pos_e);
///append_overlap_region_alloc(overlap_list, &tmp_region, R_INF);
append_overlap_region_alloc_from_existing(overlap_list, &tmp_region, R_INF);
}
}
///以x_pos_e即结束位置为主元排序
///qsort(overlap_list->list, overlap_list->length, sizeof(overlap_region), cmp_by_x_pos_e);
///qsort(overlap_list->list, overlap_list->length, sizeof(overlap_region), cmp_by_x_pos_s);
clear_Candidates_list(candidates);
}
void init_fake_cigar(Fake_Cigar* x)
{
x->buffer = NULL;
x->length = 0;
x->size = 0;
}
void destory_fake_cigar(Fake_Cigar* x)
{
if(x->size > 0)
{
free(x->buffer);
}
}
void clear_fake_cigar(Fake_Cigar* x)
{
x->length = 0;
}
void add_fake_cigar(Fake_Cigar* x, uint32_t gap_site, int32_t gap_shift)
{
if(x->length + 1 > x->size)
{
x->size = (x->length + 1) * 2;
x->buffer = (uint64_t*)realloc(x->buffer, sizeof(uint64_t) * x->size);
}
x->buffer[x->length] = gap_site;
x->buffer[x->length] = x->buffer[x->length] << 32;
if(gap_shift < 0)
{
gap_shift = gap_shift * -1;
gap_site = gap_shift;
gap_site = gap_site << 1;
gap_site = gap_site | ((uint32_t)1);
}
else
{
gap_site = gap_shift;
gap_site = gap_site << 1;
}
x->buffer[x->length] = x->buffer[x->length] | ((uint32_t)gap_site);
x->length++;
}
void resize_fake_cigar(Fake_Cigar* x, long long size)
{
if(size > x->size)
{
x->size = size;
x->buffer = (uint64_t*)realloc(x->buffer, sizeof(uint64_t) * x->size);
}
x->length = 0;
}