bio-bigwig 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,296 @@
1
+ #ifndef NOCURL
2
+ #include <curl/curl.h>
3
+ #endif
4
+ #include <stdio.h>
5
+ #include <stdlib.h>
6
+ #include <string.h>
7
+ #include <unistd.h>
8
+ #include "bigWigIO.h"
9
+ #include <inttypes.h>
10
+ #include <errno.h>
11
+
12
+ size_t GLOBAL_DEFAULTBUFFERSIZE;
13
+
14
+ #ifndef NOCURL
15
+ uint64_t getContentLength(URL_t *URL) {
16
+ double size;
17
+ if(curl_easy_getinfo(URL->x.curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &size) != CURLE_OK) {
18
+ return 0;
19
+ }
20
+ if(size== -1.0) return 0;
21
+ return (uint64_t) size;
22
+ }
23
+
24
+ //Fill the buffer, note that URL may be left in an unusable state on error!
25
+ CURLcode urlFetchData(URL_t *URL, unsigned long bufSize) {
26
+ CURLcode rv;
27
+ char range[1024];
28
+
29
+ if(URL->filePos != (size_t) -1) URL->filePos += URL->bufLen;
30
+ else URL->filePos = 0;
31
+
32
+ URL->bufPos = URL->bufLen = 0; //Otherwise, we can't copy anything into the buffer!
33
+ sprintf(range,"%lu-%lu", URL->filePos, URL->filePos+bufSize-1);
34
+ rv = curl_easy_setopt(URL->x.curl, CURLOPT_RANGE, range);
35
+ if(rv != CURLE_OK) {
36
+ fprintf(stderr, "[urlFetchData] Couldn't set the range (%s)\n", range);
37
+ return rv;
38
+ }
39
+
40
+ rv = curl_easy_perform(URL->x.curl);
41
+ errno = 0; //Sometimes curl_easy_perform leaves a random errno remnant
42
+ return rv;
43
+ }
44
+
45
+ //Read data into a buffer, ideally from a buffer already in memory
46
+ //The loop is likely no longer needed.
47
+ size_t url_fread(void *obuf, size_t obufSize, URL_t *URL) {
48
+ size_t remaining = obufSize, fetchSize;
49
+ void *p = obuf;
50
+ CURLcode rv;
51
+
52
+ while(remaining) {
53
+ if(!URL->bufLen) {
54
+ rv = urlFetchData(URL, URL->bufSize);
55
+ if(rv != CURLE_OK) {
56
+ fprintf(stderr, "[url_fread] urlFetchData (A) returned %s\n", curl_easy_strerror(rv));
57
+ return 0;
58
+ }
59
+ } else if(URL->bufLen < URL->bufPos + remaining) { //Copy the remaining buffer and reload the buffer as needed
60
+ p = memcpy(p, URL->memBuf+URL->bufPos, URL->bufLen - URL->bufPos);
61
+ if(!p) return 0;
62
+ p += URL->bufLen - URL->bufPos;
63
+ remaining -= URL->bufLen - URL->bufPos;
64
+ if(remaining) {
65
+ if(!URL->isCompressed) {
66
+ fetchSize = URL->bufSize;
67
+ } else {
68
+ fetchSize = (remaining<URL->bufSize)?remaining:URL->bufSize;
69
+ }
70
+ rv = urlFetchData(URL, fetchSize);
71
+ if(rv != CURLE_OK) {
72
+ fprintf(stderr, "[url_fread] urlFetchData (B) returned %s\n", curl_easy_strerror(rv));
73
+ return 0;
74
+ }
75
+ }
76
+ } else {
77
+ p = memcpy(p, URL->memBuf+URL->bufPos, remaining);
78
+ if(!p) return 0;
79
+ URL->bufPos += remaining;
80
+ remaining = 0;
81
+ }
82
+ }
83
+ return obufSize;
84
+ }
85
+ #endif
86
+
87
+ //Returns the number of bytes requested or a smaller number on error
88
+ //Note that in the case of remote files, the actual amount read may be less than the return value!
89
+ size_t urlRead(URL_t *URL, void *buf, size_t bufSize) {
90
+ #ifndef NOCURL
91
+ if(URL->type==0) {
92
+ return fread(buf, bufSize, 1, URL->x.fp)*bufSize;
93
+ } else {
94
+ return url_fread(buf, bufSize, URL);
95
+ }
96
+ #else
97
+ return fread(buf, bufSize, 1, URL->x.fp)*bufSize;
98
+ #endif
99
+ }
100
+
101
+ size_t bwFillBuffer(void *inBuf, size_t l, size_t nmemb, void *pURL) {
102
+ URL_t *URL = (URL_t*) pURL;
103
+ void *p = URL->memBuf;
104
+ size_t copied = l*nmemb;
105
+ if(!p) return 0;
106
+
107
+ p += URL->bufLen;
108
+ if(l*nmemb > URL->bufSize - URL->bufPos) { //We received more than we can store!
109
+ copied = URL->bufSize - URL->bufLen;
110
+ }
111
+ memcpy(p, inBuf, copied);
112
+ URL->bufLen += copied;
113
+
114
+ if(!URL->memBuf) return 0; //signal error
115
+ return copied;
116
+ }
117
+
118
+ //Seek to an arbitrary location, returning a CURLcode
119
+ //Note that a local file returns CURLE_OK on success or CURLE_FAILED_INIT on any error;
120
+ CURLcode urlSeek(URL_t *URL, size_t pos) {
121
+ #ifndef NOCURL
122
+ char range[1024];
123
+ CURLcode rv;
124
+
125
+ if(URL->type == BWG_FILE) {
126
+ #endif
127
+ if(fseek(URL->x.fp, pos, SEEK_SET) == 0) {
128
+ errno = 0;
129
+ return CURLE_OK;
130
+ } else {
131
+ return CURLE_FAILED_INIT; //This is arbitrary
132
+ }
133
+ #ifndef NOCURL
134
+ } else {
135
+ //If the location is covered by the buffer then don't seek!
136
+ if(pos < URL->filePos || pos >= URL->filePos+URL->bufLen) {
137
+ URL->filePos = pos;
138
+ URL->bufLen = 0; //Otherwise, filePos will get incremented on the next read!
139
+ URL->bufPos = 0;
140
+ //Maybe this works for FTP?
141
+ sprintf(range,"%lu-%lu", pos, pos+URL->bufSize-1);
142
+ rv = curl_easy_setopt(URL->x.curl, CURLOPT_RANGE, range);
143
+ if(rv != CURLE_OK) {
144
+ fprintf(stderr, "[urlSeek] Couldn't set the range (%s)\n", range);
145
+ return rv;
146
+ }
147
+ rv = curl_easy_perform(URL->x.curl);
148
+ if(rv != CURLE_OK) {
149
+ fprintf(stderr, "[urlSeek] curl_easy_perform received an error!\n");
150
+ }
151
+ errno = 0; //Don't propogate remnant resolved libCurl errors
152
+ return rv;
153
+ } else {
154
+ URL->bufPos = pos-URL->filePos;
155
+ return CURLE_OK;
156
+ }
157
+ }
158
+ #endif
159
+ }
160
+
161
+ URL_t *urlOpen(char *fname, CURLcode (*callBack)(CURL*), const char *mode) {
162
+ URL_t *URL = calloc(1, sizeof(URL_t));
163
+ if(!URL) return NULL;
164
+ char *url = NULL, *req = NULL;
165
+ #ifndef NOCURL
166
+ CURLcode code;
167
+ char range[1024];
168
+ #endif
169
+
170
+ URL->fname = fname;
171
+
172
+ if((!mode) || (strchr(mode, 'w') == 0)) {
173
+ //Set the protocol
174
+ #ifndef NOCURL
175
+ if(strncmp(fname, "http://", 7) == 0) URL->type = BWG_HTTP;
176
+ else if(strncmp(fname, "https://", 8) == 0) URL->type = BWG_HTTPS;
177
+ else if(strncmp(fname, "ftp://", 6) == 0) URL->type = BWG_FTP;
178
+ else URL->type = BWG_FILE;
179
+ #else
180
+ URL->type = BWG_FILE;
181
+ #endif
182
+
183
+ //local file?
184
+ if(URL->type == BWG_FILE) {
185
+ URL->filePos = -1; //This signals that nothing has been read
186
+ URL->x.fp = fopen(fname, "rb");
187
+ if(!(URL->x.fp)) {
188
+ free(URL);
189
+ fprintf(stderr, "[urlOpen] Couldn't open %s for reading\n", fname);
190
+ return NULL;
191
+ }
192
+ #ifndef NOCURL
193
+ } else {
194
+ //Remote file, set up the memory buffer and get CURL ready
195
+ URL->memBuf = malloc(GLOBAL_DEFAULTBUFFERSIZE);
196
+ if(!(URL->memBuf)) {
197
+ free(URL);
198
+ fprintf(stderr, "[urlOpen] Couldn't allocate enough space for the file buffer!\n");
199
+ return NULL;
200
+ }
201
+ URL->bufSize = GLOBAL_DEFAULTBUFFERSIZE;
202
+ URL->x.curl = curl_easy_init();
203
+ if(!(URL->x.curl)) {
204
+ fprintf(stderr, "[urlOpen] curl_easy_init() failed!\n");
205
+ goto error;
206
+ }
207
+ //Negotiate a reasonable HTTP authentication method
208
+ if(curl_easy_setopt(URL->x.curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY) != CURLE_OK) {
209
+ fprintf(stderr, "[urlOpen] Failed instructing curl to use any HTTP authentication it finds to be suitable!\n");
210
+ goto error;
211
+ }
212
+ //Follow redirects
213
+ if(curl_easy_setopt(URL->x.curl, CURLOPT_FOLLOWLOCATION, 1L) != CURLE_OK) {
214
+ fprintf(stderr, "[urlOpen] Failed instructing curl to follow redirects!\n");
215
+ goto error;
216
+ }
217
+ //Set the URL
218
+ if(curl_easy_setopt(URL->x.curl, CURLOPT_URL, fname) != CURLE_OK) {
219
+ fprintf(stderr, "[urlOpen] Couldn't set CURLOPT_URL!\n");
220
+ goto error;
221
+ }
222
+ //Set the range, which doesn't do anything for HTTP
223
+ sprintf(range, "0-%lu", URL->bufSize-1);
224
+ if(curl_easy_setopt(URL->x.curl, CURLOPT_RANGE, range) != CURLE_OK) {
225
+ fprintf(stderr, "[urlOpen] Couldn't set CURLOPT_RANGE (%s)!\n", range);
226
+ goto error;
227
+ }
228
+ //Set the callback info, which means we no longer need to directly deal with sockets and header!
229
+ if(curl_easy_setopt(URL->x.curl, CURLOPT_WRITEFUNCTION, bwFillBuffer) != CURLE_OK) {
230
+ fprintf(stderr, "[urlOpen] Couldn't set CURLOPT_WRITEFUNCTION!\n");
231
+ goto error;
232
+ }
233
+ if(curl_easy_setopt(URL->x.curl, CURLOPT_WRITEDATA, (void*)URL) != CURLE_OK) {
234
+ fprintf(stderr, "[urlOpen] Couldn't set CURLOPT_WRITEDATA!\n");
235
+ goto error;
236
+ }
237
+ //Ignore certificate errors with https, libcurl just isn't reliable enough with conda
238
+ if(curl_easy_setopt(URL->x.curl, CURLOPT_SSL_VERIFYPEER, 0) != CURLE_OK) {
239
+ fprintf(stderr, "[urlOpen] Couldn't set CURLOPT_SSL_VERIFYPEER to 0!\n");
240
+ goto error;
241
+ }
242
+ if(curl_easy_setopt(URL->x.curl, CURLOPT_SSL_VERIFYHOST, 0) != CURLE_OK) {
243
+ fprintf(stderr, "[urlOpen] Couldn't set CURLOPT_SSL_VERIFYHOST to 0!\n");
244
+ goto error;
245
+ }
246
+ if(callBack) {
247
+ code = callBack(URL->x.curl);
248
+ if(code != CURLE_OK) {
249
+ fprintf(stderr, "[urlOpen] The user-supplied call back function returned an error: %s\n", curl_easy_strerror(code));
250
+ goto error;
251
+ }
252
+ }
253
+ code = curl_easy_perform(URL->x.curl);
254
+ errno = 0; //Sometimes curl_easy_perform leaves a random errno remnant
255
+ if(code != CURLE_OK) {
256
+ fprintf(stderr, "[urlOpen] curl_easy_perform received an error: %s\n", curl_easy_strerror(code));
257
+ goto error;
258
+ }
259
+ #endif
260
+ }
261
+ } else {
262
+ URL->type = BWG_FILE;
263
+ URL->x.fp = fopen(fname, mode);
264
+ if(!(URL->x.fp)) {
265
+ free(URL);
266
+ fprintf(stderr, "[urlOpen] Couldn't open %s for writing\n", fname);
267
+ return NULL;
268
+ }
269
+ }
270
+ if(url) free(url);
271
+ if(req) free(req);
272
+ return URL;
273
+
274
+ #ifndef NOCURL
275
+ error:
276
+ if(url) free(url);
277
+ if(req) free(req);
278
+ free(URL->memBuf);
279
+ curl_easy_cleanup(URL->x.curl);
280
+ free(URL);
281
+ return NULL;
282
+ #endif
283
+ }
284
+
285
+ //Performs the necessary free() operations and handles cleaning up curl
286
+ void urlClose(URL_t *URL) {
287
+ if(URL->type == BWG_FILE) {
288
+ fclose(URL->x.fp);
289
+ #ifndef NOCURL
290
+ } else {
291
+ free(URL->memBuf);
292
+ curl_easy_cleanup(URL->x.curl);
293
+ #endif
294
+ }
295
+ free(URL);
296
+ }
@@ -0,0 +1,76 @@
1
+ #include "bigWig.h"
2
+
3
+ int main(int argc, char *argv[]) {
4
+ bigWigFile_t *fp = NULL;
5
+ char *chroms[] = {"1", "2"};
6
+ char *chromsUse[] = {"1", "1", "1"};
7
+ uint32_t chrLens[] = {1000000, 1500000};
8
+ uint32_t starts[] = {0, 100, 125,
9
+ 200, 220, 230,
10
+ 500, 600, 625,
11
+ 700, 800, 850};
12
+ uint32_t ends[] = {5, 120, 126,
13
+ 205, 226, 231};
14
+ float values[] = {0.0f, 1.0f, 200.0f,
15
+ -2.0f, 150.0f, 25.0f,
16
+ 0.0f, 1.0f, 200.0f,
17
+ -2.0f, 150.0f, 25.0f,
18
+ -5.0f, -20.0f, 25.0f,
19
+ -5.0f, -20.0f, 25.0f};
20
+
21
+
22
+ if(bwInit(1<<17) != 0) {
23
+ fprintf(stderr, "Received an error in bwInit\n");
24
+ return 1;
25
+ }
26
+
27
+ fp = bwOpen("test/example_output.bw", NULL, "w");
28
+ if(!fp) {
29
+ fprintf(stderr, "An error occurred while opening example_output.bw for writingn\n");
30
+ return 1;
31
+ }
32
+
33
+ //Allow up to 10 zoom levels, though fewer will be used in practice
34
+ if(bwCreateHdr(fp, 10)) goto error;
35
+
36
+ //Create the chromosome lists
37
+ fp->cl = bwCreateChromList(chroms, chrLens, 2);
38
+ if(!fp->cl) goto error;
39
+
40
+ //Write the header
41
+ if(bwWriteHdr(fp)) goto error;
42
+
43
+ //Some example bedGraph-like entries
44
+ if(bwAddIntervals(fp, chromsUse, starts, ends, values, 3)) goto error;
45
+ //We can continue appending similarly formatted entries
46
+ //N.B. you can't append a different chromosome (those always go into different
47
+ if(bwAppendIntervals(fp, starts+3, ends+3, values+3, 3)) goto error;
48
+
49
+ //Add a new block of entries with a span. Since bwAdd/AppendIntervals was just used we MUST create a new block
50
+ if(bwAddIntervalSpans(fp, "1", starts+6, 20, values+6, 3)) goto error;
51
+ //We can continue appending similarly formatted entries
52
+ if(bwAppendIntervalSpans(fp, starts+9, values+9, 3)) goto error;
53
+
54
+ //Add a new block of fixed-step entries
55
+ if(bwAddIntervalSpanSteps(fp, "1", 900, 20, 30, values+12, 3)) goto error;
56
+ //The start is then 760, since that's where the previous step ended
57
+ if(bwAppendIntervalSpanSteps(fp, values+15, 3)) goto error;
58
+
59
+ //Add a new chromosome
60
+ chromsUse[0] = "2";
61
+ chromsUse[1] = "2";
62
+ chromsUse[2] = "2";
63
+ if(bwAddIntervals(fp, chromsUse, starts, ends, values, 3)) goto error;
64
+
65
+ //Closing the file causes the zoom levels to be created
66
+ bwClose(fp);
67
+ bwCleanup();
68
+
69
+ return 0;
70
+
71
+ error:
72
+ fprintf(stderr, "Received an error somewhere!\n");
73
+ bwClose(fp);
74
+ bwCleanup();
75
+ return 1;
76
+ }
@@ -0,0 +1,132 @@
1
+ #include "bigWig.h"
2
+ #include <stdio.h>
3
+ #include <inttypes.h>
4
+ #include <stdlib.h>
5
+ #include <assert.h>
6
+
7
+ void bwPrintHdr(bigWigFile_t *bb) {
8
+ uint64_t i;
9
+ int64_t i64;
10
+ printf("Version: %"PRIu16"\n", bb->hdr->version);
11
+ printf("Levels: %"PRIu16"\n", bb->hdr->nLevels);
12
+ printf("ctOffset: 0x%"PRIx64"\n", bb->hdr->ctOffset);
13
+ printf("dataOffset: 0x%"PRIx64"\n", bb->hdr->dataOffset);
14
+ printf("indexOffset: 0x%"PRIx64"\n", bb->hdr->indexOffset);
15
+ printf("fieldCount: %"PRIu32"\n", bb->hdr->fieldCount);
16
+ printf("definedFieldCount: %"PRIu32"\n", bb->hdr->definedFieldCount);
17
+ printf("sqlOffset: 0x%"PRIx64"\n", bb->hdr->sqlOffset);
18
+ printf("summaryOffset: 0x%"PRIx64"\n", bb->hdr->summaryOffset);
19
+ printf("bufSize: %"PRIu32"\n", bb->hdr->bufSize);
20
+
21
+ if(bb->hdr->nLevels) {
22
+ printf(" i level data index\n");
23
+ }
24
+ for(i=0; i<bb->hdr->nLevels; i++) {
25
+ printf("\t%"PRIu64"\t%"PRIu32"\t%"PRIx64"\t%"PRIx64"\n", i, bb->hdr->zoomHdrs->level[i], bb->hdr->zoomHdrs->dataOffset[i], bb->hdr->zoomHdrs->indexOffset[i]);
26
+ }
27
+
28
+ printf("nBasesCovered: %"PRIu64"\n", bb->hdr->nBasesCovered);
29
+ printf("minVal: %f\n", bb->hdr->minVal);
30
+ printf("maxVal: %f\n", bb->hdr->maxVal);
31
+ printf("sumData: %f\n", bb->hdr->sumData);
32
+ printf("sumSquared: %f\n", bb->hdr->sumSquared);
33
+
34
+ //Chromosome idx/name/length
35
+ if(bb->cl) {
36
+ printf("Chromosome List\n");
37
+ printf(" idx\tChrom\tLength (bases)\n");
38
+ for(i64=0; i64<bb->cl->nKeys; i64++) {
39
+ printf(" %"PRIu64"\t%s\t%"PRIu32"\n", i64, bb->cl->chrom[i64], bb->cl->len[i64]);
40
+ }
41
+ }
42
+ }
43
+
44
+ void bwPrintIndexNode(bwRTreeNode_t *node, int level) {
45
+ uint16_t i;
46
+ if(!node) return;
47
+ for(i=0; i<node->nChildren; i++) {
48
+ if(node->isLeaf) {
49
+ printf(" %i\t%"PRIu32"\t%"PRIu32"\t%"PRIu32"\t%"PRIu32"\t0x%"PRIx64"\t%"PRIu64"\n", level,\
50
+ node->chrIdxStart[i], \
51
+ node->baseStart[i], \
52
+ node->chrIdxEnd[i], \
53
+ node->baseEnd[i], \
54
+ node->dataOffset[i], \
55
+ node->x.size[i]);
56
+ } else {
57
+ printf(" %i\t%"PRIu32"\t%"PRIu32"\t%"PRIu32"\t%"PRIu32"\t0x%"PRIx64"\tNA\n", level,\
58
+ node->chrIdxStart[i], \
59
+ node->baseStart[i], \
60
+ node->chrIdxEnd[i], \
61
+ node->baseEnd[i], \
62
+ node->dataOffset[i]);
63
+ bwPrintIndexNode(node->x.child[i], level+1);
64
+ }
65
+ }
66
+ }
67
+
68
+ void bwPrintIndexTree(bigWigFile_t *fp) {
69
+ printf("\nIndex tree:\n");
70
+ printf("nItems:\t%"PRIu64"\n", fp->idx->nItems);
71
+ printf("chrIdxStart:\t%"PRIu32"\n", fp->idx->chrIdxStart);
72
+ printf("baseStart:\t%"PRIu32"\n", fp->idx->baseStart);
73
+ printf("chrIdxEnd:\t%"PRIu32"\n", fp->idx->chrIdxEnd);
74
+ printf("baseEnd:\t%"PRIu32"\n", fp->idx->baseEnd);
75
+ printf("idxSize:\t%"PRIu64"\n", fp->idx->idxSize);
76
+ printf(" level\tchrIdxStart\tbaseStart\tchrIdxEnd\tbaseEnd\tchild\tsize\n");
77
+ bwPrintIndexNode(fp->idx->root, 0);
78
+ }
79
+
80
+ int main(int argc, char *argv[]) {
81
+ bigWigFile_t *fp = NULL;
82
+ bbOverlappingEntries_t *o;
83
+ uint32_t i;
84
+ char *sql;
85
+ if(argc != 2) {
86
+ fprintf(stderr, "Usage: %s {file.bb|URL://path/file.bb}\n", argv[0]);
87
+ return 1;
88
+ }
89
+
90
+ if(bwInit(1<<17) != 0) {
91
+ fprintf(stderr, "Received an error in bwInit\n");
92
+ return 1;
93
+ }
94
+
95
+ assert(bwIsBigWig(argv[1], NULL) == 0);
96
+ assert(bbIsBigBed(argv[1], NULL) == 1);
97
+
98
+ fp = bbOpen(argv[1], NULL);
99
+ if(!fp) {
100
+ fprintf(stderr, "An error occured while opening %s\n", argv[1]);
101
+ return 1;
102
+ }
103
+
104
+ bwPrintHdr(fp);
105
+ bwPrintIndexTree(fp);
106
+
107
+ sql = bbGetSQL(fp);
108
+ if(sql) {
109
+ printf("SQL is: %s\n", sql);
110
+ free(sql);
111
+ }
112
+
113
+ //Presumably this is the sort of interface that's needed...
114
+ o = bbGetOverlappingEntries(fp, "chr1", 4450000, 4500000, 1);
115
+ printf("%"PRIu32" entries overlap\n", o->l);
116
+ for(i=0; i<o->l; i++) {
117
+ printf("%"PRIu32"-%"PRIu32"\t %s\n", o->start[i], o->end[i], o->str[i]);
118
+ }
119
+ if(o) bbDestroyOverlappingEntries(o);
120
+
121
+ //Ensure that we can fetch entries with no strings
122
+ o = bbGetOverlappingEntries(fp, "chr1", 4450000, 4500000, 0);
123
+ printf("%"PRIu32" entries overlap\n", o->l);
124
+ for(i=0; i<o->l; i++) {
125
+ printf("%"PRIu32"-%"PRIu32"\n", o->start[i], o->end[i]);
126
+ }
127
+ if(o) bbDestroyOverlappingEntries(o);
128
+
129
+ bwClose(fp);
130
+ bwCleanup();
131
+ return 0;
132
+ }
@@ -0,0 +1,67 @@
1
+ #include "bigWig.h"
2
+ #include <stdio.h>
3
+ #include <inttypes.h>
4
+ #include <stdlib.h>
5
+ #include <assert.h>
6
+
7
+ int main(int argc, char *argv[]) {
8
+ bigWigFile_t *fp = NULL;
9
+ uint32_t i, chunk = 0, tid, blocksPerIteration;
10
+ char *sql, *chrom;
11
+ bwOverlapIterator_t *iter;
12
+ if(argc != 4) {
13
+ fprintf(stderr, "Usage: %s {file.bb|URL://path/file.bb} chromosome blocksPerIteration\n", argv[0]);
14
+ return 1;
15
+ }
16
+ chrom = argv[2];
17
+ blocksPerIteration = strtoul(argv[3], NULL, 10);
18
+
19
+ if(bwInit(1<<17) != 0) {
20
+ fprintf(stderr, "Received an error in bwInit\n");
21
+ return 1;
22
+ }
23
+
24
+ if(bwIsBigWig(argv[1], NULL)) {
25
+ fp = bwOpen(argv[1], NULL, "r");
26
+ } else if(bbIsBigBed(argv[1], NULL)) {
27
+ fp = bbOpen(argv[1], NULL);
28
+ }
29
+
30
+ if(!fp) {
31
+ fprintf(stderr, "An error occured while opening %s\n", argv[1]);
32
+ return 1;
33
+ }
34
+
35
+ sql = bbGetSQL(fp);
36
+ if(sql) {
37
+ printf("SQL is: %s\n", sql);
38
+ free(sql);
39
+ }
40
+
41
+ //So we can get the bounds
42
+ tid = bwGetTid(fp, chrom);
43
+
44
+ if(fp->type == 0) {
45
+ iter = bwOverlappingIntervalsIterator(fp, chrom, 0, fp->cl->len[tid], blocksPerIteration);
46
+ } else {
47
+ iter = bbOverlappingEntriesIterator(fp, chrom, 0, fp->cl->len[tid], 1, blocksPerIteration);
48
+ }
49
+ while(iter->data) {
50
+ if(fp->type == 0) {
51
+ for(i=0; i<iter->intervals->l; i++) {
52
+ printf("chunk %"PRIu32" entry %"PRIu32" %s:%"PRIu32"-%"PRIu32" %f\n", chunk, i, chrom, iter->intervals->start[i], iter->intervals->end[i], iter->intervals->value[i]);
53
+ }
54
+ } else {
55
+ for(i=0; i<iter->entries->l; i++) {
56
+ printf("chunk %"PRIu32" entry %"PRIu32" %s:%"PRIu32"-%"PRIu32" %s\n", chunk, i, chrom, iter->entries->start[i], iter->entries->end[i], iter->entries->str[i]);
57
+ }
58
+ }
59
+ chunk++;
60
+ iter = bwIteratorNext(iter);
61
+ }
62
+ bwIteratorDestroy(iter);
63
+
64
+ bwClose(fp);
65
+ bwCleanup();
66
+ return 0;
67
+ }