@jbrowse/plugin-alignments 3.5.1 → 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/ModificationParser/consts.d.ts +1 -0
  2. package/dist/ModificationParser/consts.js +4 -0
  3. package/dist/ModificationParser/getMethBins.d.ts +7 -0
  4. package/dist/ModificationParser/getMethBins.js +49 -0
  5. package/dist/ModificationParser/getModPositions.d.ts +6 -0
  6. package/dist/ModificationParser/getModPositions.js +64 -0
  7. package/dist/ModificationParser/getModProbabilities.d.ts +2 -0
  8. package/dist/ModificationParser/getModProbabilities.js +34 -0
  9. package/dist/ModificationParser/getModTypes.d.ts +5 -0
  10. package/dist/ModificationParser/getModTypes.js +35 -0
  11. package/dist/PileupRPC/methods/GetVisibleModifications.js +3 -2
  12. package/dist/PileupRenderer/renderMethylation.js +2 -2
  13. package/dist/SNPCoverageAdapter/processReferenceCpGs.js +2 -2
  14. package/dist/shared/getMaximumModificationAtEachPosition.js +4 -3
  15. package/esm/ModificationParser/consts.d.ts +1 -0
  16. package/esm/ModificationParser/consts.js +1 -0
  17. package/esm/ModificationParser/getMethBins.d.ts +7 -0
  18. package/esm/ModificationParser/getMethBins.js +46 -0
  19. package/esm/ModificationParser/getModPositions.d.ts +6 -0
  20. package/esm/ModificationParser/getModPositions.js +61 -0
  21. package/esm/ModificationParser/getModProbabilities.d.ts +2 -0
  22. package/esm/ModificationParser/getModProbabilities.js +31 -0
  23. package/esm/ModificationParser/getModTypes.d.ts +5 -0
  24. package/esm/ModificationParser/getModTypes.js +32 -0
  25. package/esm/PileupRPC/methods/GetVisibleModifications.js +3 -2
  26. package/esm/PileupRenderer/renderMethylation.js +1 -1
  27. package/esm/SNPCoverageAdapter/processReferenceCpGs.js +1 -1
  28. package/esm/shared/getMaximumModificationAtEachPosition.js +2 -1
  29. package/package.json +6 -6
  30. package/dist/ModificationParser/index.d.ts +0 -19
  31. package/dist/ModificationParser/index.js +0 -127
  32. package/esm/ModificationParser/index.d.ts +0 -19
  33. package/esm/ModificationParser/index.js +0 -121
@@ -0,0 +1 @@
1
+ export declare const modificationRegex: RegExp;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.modificationRegex = void 0;
4
+ exports.modificationRegex = new RegExp(/([A-Z])([-+])([a-z]+|[0-9]+)([.?]?)/);
@@ -0,0 +1,7 @@
1
+ import type { Feature } from '@jbrowse/core/util';
2
+ export declare function getMethBins(feature: Feature, cigarOps: string[]): {
3
+ methBins: number[];
4
+ hydroxyMethBins: number[];
5
+ methProbs: number[];
6
+ hydroxyMethProbs: number[];
7
+ };
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getMethBins = getMethBins;
4
+ const MismatchParser_1 = require("../MismatchParser");
5
+ const getModPositions_1 = require("./getModPositions");
6
+ const getModProbabilities_1 = require("./getModProbabilities");
7
+ const util_1 = require("../util");
8
+ function getMethBins(feature, cigarOps) {
9
+ const fstart = feature.get('start');
10
+ const fend = feature.get('end');
11
+ const fstrand = feature.get('strand');
12
+ const flen = fend - fstart;
13
+ const mm = (0, util_1.getTagAlt)(feature, 'MM', 'Mm') || '';
14
+ const methBins = [];
15
+ const hydroxyMethBins = [];
16
+ const methProbs = [];
17
+ const hydroxyMethProbs = [];
18
+ const seq = feature.get('seq');
19
+ if (seq) {
20
+ const probabilities = (0, getModProbabilities_1.getModProbabilities)(feature);
21
+ const modifications = (0, getModPositions_1.getModPositions)(mm, seq, fstrand);
22
+ let probIndex = 0;
23
+ for (const { type, positions } of modifications) {
24
+ for (const { ref, idx } of (0, MismatchParser_1.getNextRefPos)(cigarOps, positions)) {
25
+ if (ref < 0 || ref >= flen) {
26
+ continue;
27
+ }
28
+ const isReverseStrand = fstrand === -1;
29
+ const idx2 = probIndex + (isReverseStrand ? positions.length - 1 - idx : idx);
30
+ const prob = (probabilities === null || probabilities === void 0 ? void 0 : probabilities[idx2]) || 0;
31
+ if (type === 'm') {
32
+ methBins[ref] = 1;
33
+ methProbs[ref] = prob;
34
+ }
35
+ else if (type === 'h') {
36
+ hydroxyMethBins[ref] = 1;
37
+ hydroxyMethProbs[ref] = prob;
38
+ }
39
+ }
40
+ probIndex += positions.length;
41
+ }
42
+ }
43
+ return {
44
+ methBins,
45
+ hydroxyMethBins,
46
+ methProbs,
47
+ hydroxyMethProbs,
48
+ };
49
+ }
@@ -0,0 +1,6 @@
1
+ export declare function getModPositions(mm: string, fseq: string, fstrand: number): {
2
+ type: string;
3
+ positions: number[];
4
+ base: string;
5
+ strand: string;
6
+ }[];
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getModPositions = getModPositions;
4
+ const util_1 = require("@jbrowse/core/util");
5
+ const consts_1 = require("./consts");
6
+ function getModPositions(mm, fseq, fstrand) {
7
+ const seq = fstrand === -1 ? (0, util_1.revcom)(fseq) : fseq;
8
+ const mods = mm.split(';');
9
+ const result = [];
10
+ for (const mod of mods) {
11
+ if (mod === '') {
12
+ continue;
13
+ }
14
+ const split = mod.split(',');
15
+ const basemod = split[0];
16
+ const matches = consts_1.modificationRegex.exec(basemod);
17
+ if (!matches) {
18
+ throw new Error(`bad format for MM tag: "${mod}"`);
19
+ }
20
+ const [, base, strand, typestr] = matches;
21
+ const types = typestr.split(/(\d+|.)/);
22
+ if (strand === '-') {
23
+ console.warn('unsupported negative strand modifications');
24
+ result.push({
25
+ type: 'unsupported',
26
+ positions: [],
27
+ base: base,
28
+ strand: strand,
29
+ });
30
+ }
31
+ for (const type of types) {
32
+ if (type === '') {
33
+ continue;
34
+ }
35
+ let currPos = 0;
36
+ const positions = [];
37
+ for (let i = 1, l = split.length; i < l; i++) {
38
+ let delta = +split[i];
39
+ do {
40
+ if (base === 'N' || base === seq[currPos]) {
41
+ delta--;
42
+ }
43
+ currPos++;
44
+ } while (delta >= 0 && currPos < seq.length);
45
+ if (fstrand === -1) {
46
+ const pos = seq.length - currPos;
47
+ if (pos >= 0) {
48
+ positions.unshift(pos);
49
+ }
50
+ }
51
+ else {
52
+ positions.push(currPos - 1);
53
+ }
54
+ }
55
+ result.push({
56
+ type,
57
+ base: base,
58
+ strand: strand,
59
+ positions,
60
+ });
61
+ }
62
+ }
63
+ return result;
64
+ }
@@ -0,0 +1,2 @@
1
+ import type { Feature } from '@jbrowse/core/util';
2
+ export declare function getModProbabilities(feature: Feature): number[] | undefined;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getModProbabilities = getModProbabilities;
4
+ const util_1 = require("../util");
5
+ function getModProbabilities(feature) {
6
+ const m = (0, util_1.getTagAlt)(feature, 'ML', 'Ml') || [];
7
+ if (m) {
8
+ const result = [];
9
+ if (typeof m === 'string') {
10
+ const parts = m.split(',');
11
+ for (let i = 0, l = parts.length; i < l; i++) {
12
+ result.push(+parts[i] / 255);
13
+ }
14
+ }
15
+ else {
16
+ for (let i = 0, l = m.length; i < l; i++) {
17
+ result.push(m[i] / 255);
18
+ }
19
+ }
20
+ return result;
21
+ }
22
+ else {
23
+ const mp = (0, util_1.getTagAlt)(feature, 'MP', 'Mp');
24
+ if (mp) {
25
+ const result = [];
26
+ for (let i = 0, l = mp.length; i < l; i++) {
27
+ const phred = mp.charCodeAt(i) - 33;
28
+ result.push(Math.min(1, phred / 50));
29
+ }
30
+ return result;
31
+ }
32
+ return undefined;
33
+ }
34
+ }
@@ -0,0 +1,5 @@
1
+ export declare function getModTypes(mm: string): {
2
+ type: string;
3
+ base: string;
4
+ strand: string;
5
+ }[];
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getModTypes = getModTypes;
4
+ const consts_1 = require("./consts");
5
+ function getModTypes(mm) {
6
+ const result = [];
7
+ const mods = mm.split(';');
8
+ for (let i = 0, modsLen = mods.length; i < modsLen; i++) {
9
+ const mod = mods[i];
10
+ if (mod === '') {
11
+ continue;
12
+ }
13
+ const basemod = mod.split(',')[0];
14
+ const matches = consts_1.modificationRegex.exec(basemod);
15
+ if (!matches) {
16
+ throw new Error(`bad format for MM tag: "${mod}"`);
17
+ }
18
+ const base = matches[1];
19
+ const strand = matches[2];
20
+ const typestr = matches[3];
21
+ const types = typestr.split(/(\d+|.)/);
22
+ for (let j = 0, typesLen = types.length; j < typesLen; j++) {
23
+ const type = types[j];
24
+ if (type === '') {
25
+ continue;
26
+ }
27
+ result.push({
28
+ type,
29
+ base,
30
+ strand,
31
+ });
32
+ }
33
+ }
34
+ return result;
35
+ }
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const dataAdapterCache_1 = require("@jbrowse/core/data_adapters/dataAdapterCache");
7
7
  const rxjs_1 = require("rxjs");
8
8
  const operators_1 = require("rxjs/operators");
9
- const ModificationParser_1 = require("../../ModificationParser");
9
+ const getModTypes_1 = require("../../ModificationParser/getModTypes");
10
10
  const util_1 = require("../../util");
11
11
  const base_1 = __importDefault(require("../base"));
12
12
  class PileupGetVisibleModifications extends base_1.default {
@@ -23,7 +23,8 @@ class PileupGetVisibleModifications extends base_1.default {
23
23
  .pipe((0, operators_1.toArray)()));
24
24
  const uniqueModifications = new Map();
25
25
  for (const feat of featuresArray) {
26
- for (const mod of (0, ModificationParser_1.getModTypes)((0, util_1.getTagAlt)(feat, 'MM', 'Mm') || '')) {
26
+ const mmTag = (0, util_1.getTagAlt)(feat, 'MM', 'Mm');
27
+ for (const mod of (0, getModTypes_1.getModTypes)(typeof mmTag === 'string' ? mmTag : '')) {
27
28
  if (!uniqueModifications.has(mod.type)) {
28
29
  uniqueModifications.set(mod.type, mod);
29
30
  }
@@ -4,7 +4,7 @@ exports.renderMethylation = renderMethylation;
4
4
  const util_1 = require("@jbrowse/core/util");
5
5
  const colord_1 = require("@jbrowse/core/util/colord");
6
6
  const util_2 = require("./util");
7
- const ModificationParser_1 = require("../ModificationParser");
7
+ const getMethBins_1 = require("../ModificationParser/getMethBins");
8
8
  function renderMethylation({ ctx, feat, region, bpPerPx, renderArgs, canvasWidth, cigarOps, }) {
9
9
  const { regionSequence } = renderArgs;
10
10
  const { feature, topPx, heightPx } = feat;
@@ -17,7 +17,7 @@ function renderMethylation({ ctx, feat, region, bpPerPx, renderArgs, canvasWidth
17
17
  }
18
18
  const fstart = feature.get('start');
19
19
  const fend = feature.get('end');
20
- const { methBins, methProbs, hydroxyMethBins, hydroxyMethProbs } = (0, ModificationParser_1.getMethBins)(feature, cigarOps);
20
+ const { methBins, methProbs, hydroxyMethBins, hydroxyMethProbs } = (0, getMethBins_1.getMethBins)(feature, cigarOps);
21
21
  function getCol(k) {
22
22
  if (methBins[k]) {
23
23
  const p = methProbs[k] || 0;
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.processReferenceCpGs = processReferenceCpGs;
4
4
  const util_1 = require("@jbrowse/core/util");
5
5
  const MismatchParser_1 = require("../MismatchParser");
6
- const ModificationParser_1 = require("../ModificationParser");
7
6
  const util_2 = require("./util");
7
+ const getMethBins_1 = require("../ModificationParser/getMethBins");
8
8
  function processReferenceCpGs({ feature, region, bins, regionSequence, }) {
9
9
  var _a;
10
10
  const fstart = feature.get('start');
@@ -15,7 +15,7 @@ function processReferenceCpGs({ feature, region, bins, regionSequence, }) {
15
15
  const r = regionSequence.toLowerCase();
16
16
  if (seq) {
17
17
  const cigarOps = (0, MismatchParser_1.parseCigar)(feature.get('CIGAR'));
18
- const { methBins, methProbs } = (0, ModificationParser_1.getMethBins)(feature, cigarOps);
18
+ const { methBins, methProbs } = (0, getMethBins_1.getMethBins)(feature, cigarOps);
19
19
  const dels = mismatches.filter(f => f.type === 'deletion');
20
20
  for (let i = 0; i < fend - fstart; i++) {
21
21
  const j = i + fstart;
@@ -2,7 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getMaxProbModAtEachPosition = getMaxProbModAtEachPosition;
4
4
  const MismatchParser_1 = require("../MismatchParser");
5
- const ModificationParser_1 = require("../ModificationParser");
5
+ const getModPositions_1 = require("../ModificationParser/getModPositions");
6
+ const getModProbabilities_1 = require("../ModificationParser/getModProbabilities");
6
7
  const util_1 = require("../util");
7
8
  function getMaxProbModAtEachPosition(feature, cigarOps) {
8
9
  const fstrand = feature.get('strand');
@@ -10,8 +11,8 @@ function getMaxProbModAtEachPosition(feature, cigarOps) {
10
11
  const mm = (0, util_1.getTagAlt)(feature, 'MM', 'Mm') || '';
11
12
  const ops = cigarOps || (0, MismatchParser_1.parseCigar)(feature.get('CIGAR'));
12
13
  if (seq) {
13
- const modifications = (0, ModificationParser_1.getModPositions)(mm, seq, fstrand);
14
- const probabilities = (0, ModificationParser_1.getModProbabilities)(feature);
14
+ const modifications = (0, getModPositions_1.getModPositions)(mm, seq, fstrand);
15
+ const probabilities = (0, getModProbabilities_1.getModProbabilities)(feature);
15
16
  const maxProbModForPosition = [];
16
17
  let probIndex = 0;
17
18
  for (const { type, positions } of modifications) {
@@ -0,0 +1 @@
1
+ export declare const modificationRegex: RegExp;
@@ -0,0 +1 @@
1
+ export const modificationRegex = new RegExp(/([A-Z])([-+])([a-z]+|[0-9]+)([.?]?)/);
@@ -0,0 +1,7 @@
1
+ import type { Feature } from '@jbrowse/core/util';
2
+ export declare function getMethBins(feature: Feature, cigarOps: string[]): {
3
+ methBins: number[];
4
+ hydroxyMethBins: number[];
5
+ methProbs: number[];
6
+ hydroxyMethProbs: number[];
7
+ };
@@ -0,0 +1,46 @@
1
+ import { getNextRefPos } from '../MismatchParser';
2
+ import { getModPositions } from './getModPositions';
3
+ import { getModProbabilities } from './getModProbabilities';
4
+ import { getTagAlt } from '../util';
5
+ export function getMethBins(feature, cigarOps) {
6
+ const fstart = feature.get('start');
7
+ const fend = feature.get('end');
8
+ const fstrand = feature.get('strand');
9
+ const flen = fend - fstart;
10
+ const mm = getTagAlt(feature, 'MM', 'Mm') || '';
11
+ const methBins = [];
12
+ const hydroxyMethBins = [];
13
+ const methProbs = [];
14
+ const hydroxyMethProbs = [];
15
+ const seq = feature.get('seq');
16
+ if (seq) {
17
+ const probabilities = getModProbabilities(feature);
18
+ const modifications = getModPositions(mm, seq, fstrand);
19
+ let probIndex = 0;
20
+ for (const { type, positions } of modifications) {
21
+ for (const { ref, idx } of getNextRefPos(cigarOps, positions)) {
22
+ if (ref < 0 || ref >= flen) {
23
+ continue;
24
+ }
25
+ const isReverseStrand = fstrand === -1;
26
+ const idx2 = probIndex + (isReverseStrand ? positions.length - 1 - idx : idx);
27
+ const prob = (probabilities === null || probabilities === void 0 ? void 0 : probabilities[idx2]) || 0;
28
+ if (type === 'm') {
29
+ methBins[ref] = 1;
30
+ methProbs[ref] = prob;
31
+ }
32
+ else if (type === 'h') {
33
+ hydroxyMethBins[ref] = 1;
34
+ hydroxyMethProbs[ref] = prob;
35
+ }
36
+ }
37
+ probIndex += positions.length;
38
+ }
39
+ }
40
+ return {
41
+ methBins,
42
+ hydroxyMethBins,
43
+ methProbs,
44
+ hydroxyMethProbs,
45
+ };
46
+ }
@@ -0,0 +1,6 @@
1
+ export declare function getModPositions(mm: string, fseq: string, fstrand: number): {
2
+ type: string;
3
+ positions: number[];
4
+ base: string;
5
+ strand: string;
6
+ }[];
@@ -0,0 +1,61 @@
1
+ import { revcom } from '@jbrowse/core/util';
2
+ import { modificationRegex } from './consts';
3
+ export function getModPositions(mm, fseq, fstrand) {
4
+ const seq = fstrand === -1 ? revcom(fseq) : fseq;
5
+ const mods = mm.split(';');
6
+ const result = [];
7
+ for (const mod of mods) {
8
+ if (mod === '') {
9
+ continue;
10
+ }
11
+ const split = mod.split(',');
12
+ const basemod = split[0];
13
+ const matches = modificationRegex.exec(basemod);
14
+ if (!matches) {
15
+ throw new Error(`bad format for MM tag: "${mod}"`);
16
+ }
17
+ const [, base, strand, typestr] = matches;
18
+ const types = typestr.split(/(\d+|.)/);
19
+ if (strand === '-') {
20
+ console.warn('unsupported negative strand modifications');
21
+ result.push({
22
+ type: 'unsupported',
23
+ positions: [],
24
+ base: base,
25
+ strand: strand,
26
+ });
27
+ }
28
+ for (const type of types) {
29
+ if (type === '') {
30
+ continue;
31
+ }
32
+ let currPos = 0;
33
+ const positions = [];
34
+ for (let i = 1, l = split.length; i < l; i++) {
35
+ let delta = +split[i];
36
+ do {
37
+ if (base === 'N' || base === seq[currPos]) {
38
+ delta--;
39
+ }
40
+ currPos++;
41
+ } while (delta >= 0 && currPos < seq.length);
42
+ if (fstrand === -1) {
43
+ const pos = seq.length - currPos;
44
+ if (pos >= 0) {
45
+ positions.unshift(pos);
46
+ }
47
+ }
48
+ else {
49
+ positions.push(currPos - 1);
50
+ }
51
+ }
52
+ result.push({
53
+ type,
54
+ base: base,
55
+ strand: strand,
56
+ positions,
57
+ });
58
+ }
59
+ }
60
+ return result;
61
+ }
@@ -0,0 +1,2 @@
1
+ import type { Feature } from '@jbrowse/core/util';
2
+ export declare function getModProbabilities(feature: Feature): number[] | undefined;
@@ -0,0 +1,31 @@
1
+ import { getTagAlt } from '../util';
2
+ export function getModProbabilities(feature) {
3
+ const m = getTagAlt(feature, 'ML', 'Ml') || [];
4
+ if (m) {
5
+ const result = [];
6
+ if (typeof m === 'string') {
7
+ const parts = m.split(',');
8
+ for (let i = 0, l = parts.length; i < l; i++) {
9
+ result.push(+parts[i] / 255);
10
+ }
11
+ }
12
+ else {
13
+ for (let i = 0, l = m.length; i < l; i++) {
14
+ result.push(m[i] / 255);
15
+ }
16
+ }
17
+ return result;
18
+ }
19
+ else {
20
+ const mp = getTagAlt(feature, 'MP', 'Mp');
21
+ if (mp) {
22
+ const result = [];
23
+ for (let i = 0, l = mp.length; i < l; i++) {
24
+ const phred = mp.charCodeAt(i) - 33;
25
+ result.push(Math.min(1, phred / 50));
26
+ }
27
+ return result;
28
+ }
29
+ return undefined;
30
+ }
31
+ }
@@ -0,0 +1,5 @@
1
+ export declare function getModTypes(mm: string): {
2
+ type: string;
3
+ base: string;
4
+ strand: string;
5
+ }[];
@@ -0,0 +1,32 @@
1
+ import { modificationRegex } from './consts';
2
+ export function getModTypes(mm) {
3
+ const result = [];
4
+ const mods = mm.split(';');
5
+ for (let i = 0, modsLen = mods.length; i < modsLen; i++) {
6
+ const mod = mods[i];
7
+ if (mod === '') {
8
+ continue;
9
+ }
10
+ const basemod = mod.split(',')[0];
11
+ const matches = modificationRegex.exec(basemod);
12
+ if (!matches) {
13
+ throw new Error(`bad format for MM tag: "${mod}"`);
14
+ }
15
+ const base = matches[1];
16
+ const strand = matches[2];
17
+ const typestr = matches[3];
18
+ const types = typestr.split(/(\d+|.)/);
19
+ for (let j = 0, typesLen = types.length; j < typesLen; j++) {
20
+ const type = types[j];
21
+ if (type === '') {
22
+ continue;
23
+ }
24
+ result.push({
25
+ type,
26
+ base,
27
+ strand,
28
+ });
29
+ }
30
+ }
31
+ return result;
32
+ }
@@ -1,7 +1,7 @@
1
1
  import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache';
2
2
  import { firstValueFrom } from 'rxjs';
3
3
  import { toArray } from 'rxjs/operators';
4
- import { getModTypes } from '../../ModificationParser';
4
+ import { getModTypes } from '../../ModificationParser/getModTypes';
5
5
  import { getTagAlt } from '../../util';
6
6
  import PileupBaseRPC from '../base';
7
7
  export default class PileupGetVisibleModifications extends PileupBaseRPC {
@@ -18,7 +18,8 @@ export default class PileupGetVisibleModifications extends PileupBaseRPC {
18
18
  .pipe(toArray()));
19
19
  const uniqueModifications = new Map();
20
20
  for (const feat of featuresArray) {
21
- for (const mod of getModTypes(getTagAlt(feat, 'MM', 'Mm') || '')) {
21
+ const mmTag = getTagAlt(feat, 'MM', 'Mm');
22
+ for (const mod of getModTypes(typeof mmTag === 'string' ? mmTag : '')) {
22
23
  if (!uniqueModifications.has(mod.type)) {
23
24
  uniqueModifications.set(mod.type, mod);
24
25
  }
@@ -1,7 +1,7 @@
1
1
  import { bpSpanPx } from '@jbrowse/core/util';
2
2
  import { colord } from '@jbrowse/core/util/colord';
3
3
  import { fillRect } from './util';
4
- import { getMethBins } from '../ModificationParser';
4
+ import { getMethBins } from '../ModificationParser/getMethBins';
5
5
  export function renderMethylation({ ctx, feat, region, bpPerPx, renderArgs, canvasWidth, cigarOps, }) {
6
6
  const { regionSequence } = renderArgs;
7
7
  const { feature, topPx, heightPx } = feat;
@@ -1,7 +1,7 @@
1
1
  import { doesIntersect2 } from '@jbrowse/core/util';
2
2
  import { parseCigar } from '../MismatchParser';
3
- import { getMethBins } from '../ModificationParser';
4
3
  import { incWithProbabilities } from './util';
4
+ import { getMethBins } from '../ModificationParser/getMethBins';
5
5
  export function processReferenceCpGs({ feature, region, bins, regionSequence, }) {
6
6
  var _a;
7
7
  const fstart = feature.get('start');
@@ -1,5 +1,6 @@
1
1
  import { getNextRefPos, parseCigar } from '../MismatchParser';
2
- import { getModPositions, getModProbabilities } from '../ModificationParser';
2
+ import { getModPositions } from '../ModificationParser/getModPositions';
3
+ import { getModProbabilities } from '../ModificationParser/getModProbabilities';
3
4
  import { getTagAlt } from '../util';
4
5
  export function getMaxProbModAtEachPosition(feature, cigarOps) {
5
6
  const fstrand = feature.get('strand');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/plugin-alignments",
3
- "version": "3.5.1",
3
+ "version": "3.6.0",
4
4
  "description": "JBrowse 2 alignments adapters, tracks, etc.",
5
5
  "keywords": [
6
6
  "jbrowse",
@@ -38,10 +38,10 @@
38
38
  "dependencies": {
39
39
  "@gmod/bam": "^6.0.1",
40
40
  "@gmod/cram": "^5.0.4",
41
- "@jbrowse/core": "^3.5.1",
42
- "@jbrowse/plugin-linear-genome-view": "^3.5.1",
43
- "@jbrowse/plugin-wiggle": "^3.5.1",
44
- "@jbrowse/sv-core": "^3.5.1",
41
+ "@jbrowse/core": "^3.6.0",
42
+ "@jbrowse/plugin-linear-genome-view": "^3.6.0",
43
+ "@jbrowse/plugin-wiggle": "^3.6.0",
44
+ "@jbrowse/sv-core": "^3.6.0",
45
45
  "@mui/icons-material": "^7.0.0",
46
46
  "@mui/material": "^7.0.0",
47
47
  "canvas2svg": "^1.0.16",
@@ -63,5 +63,5 @@
63
63
  "distModule": "esm/index.js",
64
64
  "srcModule": "src/index.ts",
65
65
  "module": "esm/index.js",
66
- "gitHead": "cb8859da9d838ad2594964777c5c54f385d98f5e"
66
+ "gitHead": "133a68815ab348d156c18d83cffc997356c3cfbb"
67
67
  }
@@ -1,19 +0,0 @@
1
- import type { Feature } from '@jbrowse/core/util';
2
- export declare function getModProbabilities(feature: Feature): number[] | undefined;
3
- export declare function getModPositions(mm: string, fseq: string, fstrand: number): {
4
- type: string;
5
- positions: number[];
6
- base: string;
7
- strand: string;
8
- }[];
9
- export declare function getModTypes(mm: string): {
10
- type: string;
11
- base: string;
12
- strand: string;
13
- }[];
14
- export declare function getMethBins(feature: Feature, cigarOps: string[]): {
15
- methBins: number[];
16
- hydroxyMethBins: number[];
17
- methProbs: number[];
18
- hydroxyMethProbs: number[];
19
- };
@@ -1,127 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getModProbabilities = getModProbabilities;
4
- exports.getModPositions = getModPositions;
5
- exports.getModTypes = getModTypes;
6
- exports.getMethBins = getMethBins;
7
- const util_1 = require("@jbrowse/core/util");
8
- const MismatchParser_1 = require("../MismatchParser");
9
- const util_2 = require("../util");
10
- const modificationRegex = new RegExp(/([A-Z])([-+])([^,.?]+)([.?])?/);
11
- function getModProbabilities(feature) {
12
- var _a;
13
- const m = (0, util_2.getTagAlt)(feature, 'ML', 'Ml') || [];
14
- return m
15
- ? (typeof m === 'string' ? m.split(',').map(e => +e) : m).map(e => e / 255)
16
- : (_a = (0, util_2.getTagAlt)(feature, 'MP', 'Mp')) === null || _a === void 0 ? void 0 : _a.split('').map(s => s.charCodeAt(0) - 33).map(elt => Math.min(1, elt / 50));
17
- }
18
- function getModPositions(mm, fseq, fstrand) {
19
- const seq = fstrand === -1 ? (0, util_1.revcom)(fseq) : fseq;
20
- const mods = mm.split(';').filter(mod => !!mod);
21
- const result = [];
22
- for (const mod of mods) {
23
- const [basemod, ...skips] = mod.split(',');
24
- const matches = modificationRegex.exec(basemod);
25
- if (!matches) {
26
- throw new Error('bad format for MM tag');
27
- }
28
- const [, base, strand, typestr] = matches;
29
- const types = typestr.split(/(\d+|.)/).filter(f => !!f);
30
- if (strand === '-') {
31
- console.warn('unsupported negative strand modifications');
32
- result.push({
33
- type: 'unsupported',
34
- positions: [],
35
- base: base,
36
- strand: strand,
37
- });
38
- }
39
- for (const type of types) {
40
- let i = 0;
41
- const positions = [];
42
- for (const d of skips) {
43
- let delta = +d;
44
- do {
45
- if (base === 'N' || base === seq[i]) {
46
- delta--;
47
- }
48
- i++;
49
- } while (delta >= 0 && i < seq.length);
50
- if (fstrand === -1) {
51
- const pos = seq.length - i;
52
- if (pos >= 0) {
53
- positions.unshift(pos);
54
- }
55
- }
56
- else {
57
- positions.push(i - 1);
58
- }
59
- }
60
- result.push({
61
- type,
62
- base: base,
63
- strand: strand,
64
- positions,
65
- });
66
- }
67
- }
68
- return result;
69
- }
70
- function getModTypes(mm) {
71
- return mm
72
- .split(';')
73
- .filter(mod => !!mod)
74
- .flatMap(mod => {
75
- const basemod = mod.split(',')[0];
76
- const matches = modificationRegex.exec(basemod);
77
- if (!matches) {
78
- throw new Error('bad format for MM tag');
79
- }
80
- const [, base, strand, typestr] = matches;
81
- return typestr
82
- .split(/(\d+|.)/)
83
- .filter(f => !!f)
84
- .map(type => ({
85
- type,
86
- base: base,
87
- strand: strand,
88
- }));
89
- });
90
- }
91
- function getMethBins(feature, cigarOps) {
92
- const fstart = feature.get('start');
93
- const fend = feature.get('end');
94
- const fstrand = feature.get('strand');
95
- const flen = fend - fstart;
96
- const mm = (0, util_2.getTagAlt)(feature, 'MM', 'Mm') || '';
97
- const methBins = [];
98
- const hydroxyMethBins = [];
99
- const methProbs = [];
100
- const hydroxyMethProbs = [];
101
- const seq = feature.get('seq');
102
- if (seq) {
103
- const probabilities = getModProbabilities(feature);
104
- const modifications = getModPositions(mm, seq, fstrand);
105
- let probIndex = 0;
106
- for (const { type, positions } of modifications) {
107
- for (const { ref, idx } of (0, MismatchParser_1.getNextRefPos)(cigarOps, positions)) {
108
- const idx2 = probIndex + (fstrand === -1 ? positions.length - 1 - idx : idx);
109
- const prob = (probabilities === null || probabilities === void 0 ? void 0 : probabilities[idx2]) || 0;
110
- if (type === 'm') {
111
- if (ref >= 0 && ref < flen) {
112
- methBins[ref] = 1;
113
- methProbs[ref] = prob;
114
- }
115
- }
116
- else if (type === 'h') {
117
- if (ref >= 0 && ref < flen) {
118
- hydroxyMethBins[ref] = 1;
119
- hydroxyMethProbs[ref] = prob;
120
- }
121
- }
122
- }
123
- probIndex += positions.length;
124
- }
125
- }
126
- return { methBins, hydroxyMethBins, methProbs, hydroxyMethProbs };
127
- }
@@ -1,19 +0,0 @@
1
- import type { Feature } from '@jbrowse/core/util';
2
- export declare function getModProbabilities(feature: Feature): number[] | undefined;
3
- export declare function getModPositions(mm: string, fseq: string, fstrand: number): {
4
- type: string;
5
- positions: number[];
6
- base: string;
7
- strand: string;
8
- }[];
9
- export declare function getModTypes(mm: string): {
10
- type: string;
11
- base: string;
12
- strand: string;
13
- }[];
14
- export declare function getMethBins(feature: Feature, cigarOps: string[]): {
15
- methBins: number[];
16
- hydroxyMethBins: number[];
17
- methProbs: number[];
18
- hydroxyMethProbs: number[];
19
- };
@@ -1,121 +0,0 @@
1
- import { revcom } from '@jbrowse/core/util';
2
- import { getNextRefPos } from '../MismatchParser';
3
- import { getTagAlt } from '../util';
4
- const modificationRegex = new RegExp(/([A-Z])([-+])([^,.?]+)([.?])?/);
5
- export function getModProbabilities(feature) {
6
- var _a;
7
- const m = getTagAlt(feature, 'ML', 'Ml') || [];
8
- return m
9
- ? (typeof m === 'string' ? m.split(',').map(e => +e) : m).map(e => e / 255)
10
- : (_a = getTagAlt(feature, 'MP', 'Mp')) === null || _a === void 0 ? void 0 : _a.split('').map(s => s.charCodeAt(0) - 33).map(elt => Math.min(1, elt / 50));
11
- }
12
- export function getModPositions(mm, fseq, fstrand) {
13
- const seq = fstrand === -1 ? revcom(fseq) : fseq;
14
- const mods = mm.split(';').filter(mod => !!mod);
15
- const result = [];
16
- for (const mod of mods) {
17
- const [basemod, ...skips] = mod.split(',');
18
- const matches = modificationRegex.exec(basemod);
19
- if (!matches) {
20
- throw new Error('bad format for MM tag');
21
- }
22
- const [, base, strand, typestr] = matches;
23
- const types = typestr.split(/(\d+|.)/).filter(f => !!f);
24
- if (strand === '-') {
25
- console.warn('unsupported negative strand modifications');
26
- result.push({
27
- type: 'unsupported',
28
- positions: [],
29
- base: base,
30
- strand: strand,
31
- });
32
- }
33
- for (const type of types) {
34
- let i = 0;
35
- const positions = [];
36
- for (const d of skips) {
37
- let delta = +d;
38
- do {
39
- if (base === 'N' || base === seq[i]) {
40
- delta--;
41
- }
42
- i++;
43
- } while (delta >= 0 && i < seq.length);
44
- if (fstrand === -1) {
45
- const pos = seq.length - i;
46
- if (pos >= 0) {
47
- positions.unshift(pos);
48
- }
49
- }
50
- else {
51
- positions.push(i - 1);
52
- }
53
- }
54
- result.push({
55
- type,
56
- base: base,
57
- strand: strand,
58
- positions,
59
- });
60
- }
61
- }
62
- return result;
63
- }
64
- export function getModTypes(mm) {
65
- return mm
66
- .split(';')
67
- .filter(mod => !!mod)
68
- .flatMap(mod => {
69
- const basemod = mod.split(',')[0];
70
- const matches = modificationRegex.exec(basemod);
71
- if (!matches) {
72
- throw new Error('bad format for MM tag');
73
- }
74
- const [, base, strand, typestr] = matches;
75
- return typestr
76
- .split(/(\d+|.)/)
77
- .filter(f => !!f)
78
- .map(type => ({
79
- type,
80
- base: base,
81
- strand: strand,
82
- }));
83
- });
84
- }
85
- export function getMethBins(feature, cigarOps) {
86
- const fstart = feature.get('start');
87
- const fend = feature.get('end');
88
- const fstrand = feature.get('strand');
89
- const flen = fend - fstart;
90
- const mm = getTagAlt(feature, 'MM', 'Mm') || '';
91
- const methBins = [];
92
- const hydroxyMethBins = [];
93
- const methProbs = [];
94
- const hydroxyMethProbs = [];
95
- const seq = feature.get('seq');
96
- if (seq) {
97
- const probabilities = getModProbabilities(feature);
98
- const modifications = getModPositions(mm, seq, fstrand);
99
- let probIndex = 0;
100
- for (const { type, positions } of modifications) {
101
- for (const { ref, idx } of getNextRefPos(cigarOps, positions)) {
102
- const idx2 = probIndex + (fstrand === -1 ? positions.length - 1 - idx : idx);
103
- const prob = (probabilities === null || probabilities === void 0 ? void 0 : probabilities[idx2]) || 0;
104
- if (type === 'm') {
105
- if (ref >= 0 && ref < flen) {
106
- methBins[ref] = 1;
107
- methProbs[ref] = prob;
108
- }
109
- }
110
- else if (type === 'h') {
111
- if (ref >= 0 && ref < flen) {
112
- hydroxyMethBins[ref] = 1;
113
- hydroxyMethProbs[ref] = prob;
114
- }
115
- }
116
- }
117
- probIndex += positions.length;
118
- }
119
- }
120
- return { methBins, hydroxyMethBins, methProbs, hydroxyMethProbs };
121
- }