forked from lh3/bwa
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathproovbin.c
More file actions
149 lines (125 loc) · 3.74 KB
/
proovbin.c
File metadata and controls
149 lines (125 loc) · 3.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <malloc.h>
#include <stdio.h>
#include "queue.h"
#include "proovbin.h"
void bns_bins_init (bntseq_t *bns) {
int i, j;
bns->bin_size = global_bin_size;
// basically what I want:
// bns->binseqs[n_seqs].bins[n_bins]
bns->binseqs = (binseq_t*) calloc(bns->n_seqs, sizeof(binseq_t));
for(i=0;i<bns->n_seqs;i++){
int n_bins = bns->anns[i].len / bns->bin_size + 1;
bin_t *bins;
bins = (bin_t*) calloc(n_bins, sizeof(bin_t));
for(j=0;j<n_bins;j++){
TAILQ_INIT(&bins[j].que);
pthread_mutex_init(&(bins[j].mutex), NULL);
bins[j].length = 0;
}
bns->binseqs[i].n_bins = n_bins;
bns->binseqs[i].bins = bins;
}
}
void bns_bins_destroy (bntseq_t *bns) {
struct aln_t *ai;
int n,b;
// clean up
for(n=0; n<bns->n_seqs; n++){ // loop seqs
for(b=0; b<bns->binseqs[n].n_bins; b++){ // loop bins
while ( (ai = TAILQ_FIRST(&bns->binseqs[n].bins[b].que)) != NULL) {
TAILQ_REMOVE(&bns->binseqs[n].bins[b].que, ai, alns);
free(ai);
}
}
free(bns->binseqs[n].bins);
}
free(bns->binseqs);
}
void bns_bins_print (bntseq_t *bns) {
struct aln_t *ai;
int n,b,len;
printf("#seq bin len alignments\n");
for(n=0; n<bns->n_seqs; n++){ // loop seqs
printf(">%d\n", n);
for(b=0; b<bns->binseqs[n].n_bins; b++){ // loop bins
len = bns->binseqs[n].bins[b].length;
printf(" #%-4d %4d ------------\n", b, len);
TAILQ_FOREACH(ai, &bns->binseqs[n].bins[b].que, alns)
printf(" | %4d %4d\n", ai->score, ai->length);
}
}
}
int bins_pos2idx (int bin_size, int length, int pos) {
int b = ( pos + length/2 ) / bin_size;
return b;
}
int bins_assess_aln_by_score (bin_t *bin, int bin_length, int length, int score) {
//printf("%5d %5d\n", length, score);
pthread_mutex_lock(&(bin->mutex));
struct aln_t *a;
struct aln_t *ai;
struct aln_t *ar;
a = malloc(sizeof(struct aln_t));
a->length = length;
a->score = score;
if (TAILQ_EMPTY(&bin->que))
{ // empty bin
bin->length = length; // first item => total length == item length
TAILQ_INSERT_HEAD(&bin->que, a, alns);
}
else if (bin->length < bin_length)
{ // partially filled bin
if (a->score <= TAILQ_FIRST(&bin->que)->score)
{ // new min score aln
TAILQ_INSERT_HEAD(&bin->que, a, alns);
bin->length = bin->length + a->length;
}
else if (a->score >= TAILQ_LAST(&bin->que, que_t)->score)
{ // new max score
TAILQ_INSERT_TAIL(&bin->que, a, alns);
bin->length += a->length;
}
else
{ // non-min score aln
TAILQ_FOREACH(ai, &bin->que, alns){
if (a->score < ai->score)
break;
}
TAILQ_INSERT_BEFORE(ai, a, alns);
bin->length += a->length;
}
}
else
{ // full bin
if (a->score <= TAILQ_FIRST(&bin->que)->score)
{ // new min score aln
free(a);
pthread_mutex_unlock(&(bin->mutex));
return 0;
}
if (a->score >= TAILQ_LAST(&bin->que, que_t)->score)
{ // new max score
TAILQ_INSERT_TAIL(&bin->que, a, alns);
bin->length += a->length;
}
else
{ // non-min score aln - find pos
TAILQ_FOREACH(ai, &bin->que, alns){
if (a->score < ai->score)
break;
}
TAILQ_INSERT_BEFORE(ai, a, alns);
bin->length += a->length;
}
while (bin->length - TAILQ_FIRST(&bin->que)->length > bin_length)
{ // remove overflow
ar = TAILQ_FIRST(&bin->que);
TAILQ_REMOVE(&bin->que, ar, alns);
bin->length -= ar->length;
free(ar);
}
}
pthread_mutex_unlock(&(bin->mutex));
return 1;
}