Repository navigation
Expand file tree
/
Copy pathl2bit.h
More file actions
109 lines (91 loc) · 4 KB
/
Copy pathl2bit.h
File metadata and controls
109 lines (91 loc) · 4 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
#ifndef L2BIT_H
#define L2BIT_H
#include <stdint.h>
#include <stddef.h>
#define L2B_MAGIC "L2B\1"
typedef enum { L2B_METH_NONE=0, L2B_METH_C2T, L2B_METH_G2A } l2b_meth_t;
/* One aligned block from the .alt CIGAR (one M/=/X run).
* Maps ALT positions [alt_st, alt_en) to primary positions [pri_st, pri_st+len)
* (forward) or [pri_en-len, pri_en) traversed in reverse (rev). */
typedef struct {
uint64_t alt_st, alt_en; /* half-open interval on ALT contig */
int64_t pri_tid; /* primary contig index */
uint64_t pri_st, pri_en; /* half-open interval on primary contig */
uint8_t rev; /* 1 = ALT is RC-aligned to primary */
} l2b_lift_t;
typedef struct {
char *name, *comm;
uint64_t len, off;
uint8_t is_alt; /* 1 if this contig appears as QNAME in the .alt file */
uint32_t n_lift; /* number of lift blocks */
l2b_lift_t *lift; /* sorted by alt_st; NULL when n_lift==0 */
} l2b_ctg_t;
typedef struct {
uint64_t st, en;
} l2b_intv_t;
typedef struct {
uint64_t tot_len;
uint64_t n_ctg, m_ctg;
uint32_t n_alt_ctg; /* contigs with is_alt set; 0 when no .alt was loaded */
l2b_ctg_t *ctg;
uint64_t n_pac, m_pac;
uint64_t n_ambi, m_ambi;
uint64_t n_mask, m_mask;
l2b_intv_t *ambi, *mask;
uint64_t *pac;
char *cat_name, *cat_comm;
void *mmap; // mmap pointer
size_t mmap_len; // mmap length (for munmap)
} l2b_t;
#ifdef __cplusplus
extern "C" {
#endif
l2b_t *l2b_load(const char *fn);
l2b_t *l2b_load_mmap(const char *fn, int preload);
void l2b_destroy(l2b_t *l2b);
int64_t l2b_intv2cid(const l2b_t *l2b, uint64_t st, uint64_t en, int64_t *cst, int *rev);
int64_t l2b_intv2cid_meth(const l2b_t *l2b, uint64_t st, uint64_t en, l2b_meth_t *mt, int64_t *cst, int *rev);
int64_t l2b_getseq(const l2b_t *l2b, int64_t tid, int64_t st, int64_t en, uint8_t *seq);
int64_t l2b_getambi(const l2b_t *l2b, int64_t tid, int64_t st, int64_t en, int32_t *n_ambi);
void l2b_meth_convert(l2b_meth_t mt, int64_t len, uint8_t *seq);
/* Load an ALT file (SAM), set l2b_ctg_t.is_alt and populate lift[] blocks for each
* ALT contig. Safe to call multiple times (re-entrant: frees old lift[] first).
* Returns the number of ALT records parsed (a contig may carry several; the
* contig count is l2b->n_alt_ctg), or -1 on file error. */
int l2b_set_alt(l2b_t *l2b, const char *fn);
/* Map (alt_tid, alt_pos) to (pri_tid, pri_pos). alt_pos is 0-based.
* Returns 1 if liftable (fills *pri_tid, *pri_pos, *rev),
* 0 if in a hole (ALT-only insertion; pri_tid, pri_pos, rev left unchanged). */
int l2b_lift(const l2b_t *l2b, int64_t alt_tid, uint64_t alt_pos,
int64_t *pri_tid, uint64_t *pri_pos, uint8_t *rev);
l2b_t *l2b_import(const char *fn, uint64_t seed);
int l2b_save(const char *fn, const l2b_t *l2b);
int l2b_save_pac(const char *fn, const l2b_t *l2b, int both_strand);
int l2b_save_pac_meth(const char *fn, const l2b_t *l2b, int both_strand);
#ifdef MB_HAVE_B2
/* Phase-2: build an in-memory l2b_t equivalent to <prefix>.l2b directly from
* bwa-mem3's bns + packed 2-bit reference, so the cp_occ backend does not
* need minibwa's own .l2b file. `bns` is the opaque bntseq_t* produced by
* mb_b2_load_bns (b2idx.h); `pac`/`l_pac` are its packed-reference buffer and
* base count. Deep-copies everything into freshly allocated buffers, so the
* caller may free bns/pac (e.g. via mb_b2_free_bns) immediately afterwards.
* Returns a heap-allocated, non-mmap l2b_t (destroy with l2b_destroy). */
l2b_t *l2b_from_bns(const void *bns, const uint8_t *pac, int64_t l_pac);
#endif
static inline int l2b_get0(const l2b_t *l2b, uint64_t i)
{
return l2b->pac[i>>5] >> ((i&31)<<1) & 3;
}
static inline void l2b_seq_prefetch(const l2b_t *l2b, int64_t tid, int64_t st)
{
if (tid >= 0 && tid < l2b->n_ctg && st >= 0 && st < l2b->ctg[tid].len)
__builtin_prefetch(&l2b->pac[(st + l2b->ctg[tid].off) >> 5]);
}
static inline l2b_meth_t l2b_meth_rev(l2b_meth_t mt)
{
return mt == L2B_METH_NONE? L2B_METH_NONE : mt == L2B_METH_C2T? L2B_METH_G2A : L2B_METH_C2T;
}
#ifdef __cplusplus
}
#endif
#endif