-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathshift.c
85 lines (79 loc) · 2.24 KB
/
shift.c
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
/* bwtool_shift - shifting data */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <jkweb/common.h>
#include <jkweb/linefile.h>
#include <jkweb/hash.h>
#include <jkweb/options.h>
#include <jkweb/sqlNum.h>
#include <jkweb/basicBed.h>
#include <jkweb/bigWig.h>
#include <beato/bigs.h>
#include "bwtool.h"
#include "bwtool_shared.h"
#include <math.h>
#define NANUM sqrt(-1)
void usage_shift()
/* Explain usage and exit. */
{
errAbort(
"bwtool shift - move the data on the chromosome by N number of bases\n"
"usage:\n"
" bwtool shift N input.bw[:chr:start-end] output.bw\n"
);
}
void bwtool_shift(struct hash *options, char *favorites, char *regions, unsigned decimals, enum wigOutType wot,
boolean condense, char *val_s, char *bigfile, char *tmp_dir, char *outputfile)
/* bwtool_shift - main for shifting program */
{
const double na = NANUM;
int shft = sqlSigned(val_s);
int abs_shft = abs(shft);
struct metaBig *mb = metaBigOpen_check(bigfile, tmp_dir, regions);
if (!mb)
errAbort("problem opening %s", bigfile);
char wigfile[512];
safef(wigfile, sizeof(wigfile), "%s.tmp.wig", outputfile);
FILE *out = mustOpen(wigfile, "w");
struct bed *section;
boolean up = TRUE;
if (shft > 0)
up = FALSE;
if (shft == 0)
errAbort("it doesn't make sense to shift by zero.");
for (section = mb->sections; section != NULL; section = section->next)
{
struct perBaseWig *pbw = perBaseWigLoadSingleContinue(mb, section->chrom, section->chromStart,
section->chromEnd, FALSE, na);
int i;
/* if the shift size is bigger than the section, NA the entire thing */
int size = pbw->len;
if (abs_shft >= size)
for (i = 0; i < size; i++)
pbw->data[i] = na;
else
{
if (!up)
{
for (i = size-1; i >= abs_shft; i--)
pbw->data[i] = pbw->data[i - abs_shft];
for (; i >= 0; i--)
pbw->data[i] = na;
}
else
{
for (i = 0; i < size - abs_shft; i++)
pbw->data[i] = pbw->data[i + abs_shft];
for (; i < size; i++)
pbw->data[i] = na;
}
}
perBaseWigOutputNASkip(pbw, out, wot, decimals, NULL, FALSE, condense);
perBaseWigFree(&pbw);
}
carefulClose(&out);
writeBw(wigfile, outputfile, mb->chromSizeHash);
remove(wigfile);
metaBigClose(&mb);
}