forked from hammerlab/pileup.js
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathGA4GHAlignment.js
More file actions
112 lines (95 loc) · 3.11 KB
/
GA4GHAlignment.js
File metadata and controls
112 lines (95 loc) · 3.11 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
/**
* This serves as a bridge between org.ga4gh.GAReadAlignment and the
* pileup.js Alignment type.
* @flow
*/
'use strict';
import type {CigarOp, MateProperties, Strand} from './Alignment';
import ContigInterval from './ContigInterval';
import SamRead from './data/SamRead';
// See https://github.com/ga4gh/schemas/blob/v0.5.1/src/main/resources/avro/common.avdl
var OP_MAP = {
ALIGNMENT_MATCH: 'M',
INSERT: 'I',
DELETE: 'D',
SKIP: 'N',
CLIP_SOFT: 'S',
CLIP_HARD: 'H',
PAD: 'P',
SEQUENCE_MATCH: '=',
SEQUENCE_MISMATCH: 'X'
};
/**
* This class acts as a bridge between org.ga4gh.GAReadAlignment and the
* pileup.js Alignment type.
*/
class GA4GHAlignment /* implements Alignment */ {
pos: number;
ref: string;
alignment: Object;
name: string;
cigarOps: CigarOp[];
_interval: ContigInterval<string>;
// alignment follows org.ga4gh.GAReadAlignment
// https://github.com/ga4gh/schemas/blob/v0.5.1/src/main/resources/avro/reads.avdl
constructor(alignment: Object) {
this.alignment = alignment;
// console.log(alignment)
this.pos = alignment.alignment.position.position;
this.ref = alignment.alignment.position.referenceName;
this.name = alignment.fragmentName;
this.cigarOps = alignment.alignment.cigar.map(
({operation, operationLength: length}) => ({ op: OP_MAP[operation], length }));
this._interval = new ContigInterval(this.ref,
this.pos,
this.pos + this.getReferenceLength() - 1);
}
getKey(): string {
return GA4GHAlignment.keyFromGA4GHResponse(this.alignment);
}
getStrand(): Strand {
return this.alignment.alignment.position.reverseStrand ? '-' : '+';
}
getQualityScores(): number[] {
return this.alignment.alignedQuality;
}
getSequence(): string {
return this.alignment.alignedSequence;
}
getInterval(): ContigInterval<string> {
return this._interval;
}
intersects(interval: ContigInterval<string>): boolean {
return interval.intersects(this.getInterval());
}
getReferenceLength(): number {
return SamRead.referenceLengthFromOps(this.cigarOps);
}
getMateProperties(): ?MateProperties {
var next = this.alignment.nextMatePosition;
return next && {
ref: next.referenceName,
pos: next.position,
strand: next.reverseStrand ? '-' : '+'
};
}
getInferredInsertSize(): number {
// TODO: SAM/BAM writes this explicitly. Does GA4GH really not?
var m = this.getMateProperties();
if (m && m.ref == this.ref) {
var start1 = this._interval.start(),
stop1 = this._interval.stop(),
start2 = m.pos,
stop2 = start2 + this.getSequence().length;
return Math.max(stop1, stop2) - Math.min(start1, start2);
} else {
return 0;
}
}
// This is exposed as a static method to facilitate an optimization in GA4GHDataSource.
static keyFromGA4GHResponse(alignment: Object): string {
// this.alignment.id would be appealing here, but it's not actually unique!
return alignment.fragmentName + ':' + alignment.readNumber;
}
}
module.exports = GA4GHAlignment;