@teselagen/range-utils 0.3.14-beta.3 → 0.3.18
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.
- package/adjustRangeToDeletionOfAnotherRange.d.ts +1 -2
- package/adjustRangeToInsert.d.ts +1 -2
- package/adjustRangeToRotation.d.ts +1 -5
- package/checkIfNonCircularRangesOverlap.d.ts +1 -2
- package/checkIfPotentiallyCircularRangesOverlap.d.ts +1 -2
- package/collapseOverlapsGeneratedFromRangeComparisonIfPossible.d.ts +1 -2
- package/convertRangeIndices.d.ts +1 -10
- package/convertRangeTo0Based.d.ts +1 -5
- package/convertRangeTo1Based.d.ts +1 -5
- package/doesRangeSpanEntireSequence.d.ts +1 -2
- package/doesRangeSpanOrigin.d.ts +1 -2
- package/expandOrContractCircularRangeToPosition.d.ts +2 -3
- package/expandOrContractNonCircularRangeToPosition.d.ts +2 -3
- package/expandOrContractRangeByLength.d.ts +1 -5
- package/expandOrContractRangeToPosition.d.ts +2 -3
- package/flipContainedRange.d.ts +1 -5
- package/generateRandomRange.d.ts +3 -3
- package/getAnnotationRangeType.d.ts +1 -2
- package/getEachPositionInRangeAsArray.d.ts +1 -2
- package/getLengthOfOverlappingRegionsBetweenTwoRanges.d.ts +1 -2
- package/getMiddleOfRange.d.ts +1 -2
- package/getOverlapOfNonCircularRanges.d.ts +4 -5
- package/getOverlapsOfPotentiallyCircularRanges.d.ts +1 -2
- package/getPositionFromAngle.d.ts +1 -1
- package/getRangeAngles.d.ts +7 -3
- package/getRangeLength.d.ts +1 -5
- package/getRangesBetweenTwoRanges.d.ts +1 -2
- package/getSequenceWithinRange.d.ts +1 -2
- package/getShortestDistanceBetweenTwoPositions.d.ts +1 -1
- package/getYOffsetForPotentiallyCircularRange.d.ts +1 -2
- package/getYOffsetsForPotentiallyCircularRanges.d.ts +2 -3
- package/getZeroedRangeOverlaps.d.ts +1 -2
- package/index.cjs +41 -52
- package/index.d.ts +0 -1
- package/index.js +41 -52
- package/index.umd.cjs +41 -52
- package/invertRange.d.ts +1 -5
- package/isPositionCloserToRangeStartThanRangeEnd.d.ts +1 -2
- package/isPositionWithinRange.d.ts +2 -3
- package/isRangeOrPositionWithinRange.d.ts +1 -2
- package/isRangeWithinRange.d.ts +1 -2
- package/loopEachPositionInRange.d.ts +1 -2
- package/modulatePositionByRange.d.ts +1 -2
- package/modulateRangeBySequenceLength.d.ts +1 -8
- package/normalizePositionByRangeLength.d.ts +1 -1
- package/normalizePositionByRangeLength1Based.d.ts +1 -1
- package/normalizeRange.d.ts +1 -5
- package/package.json +4 -12
- package/provideInclusiveOptions.d.ts +1 -6
- package/reversePositionInRange.d.ts +1 -1
- package/splitRangeIntoTwoPartsIfItIsCircular.d.ts +3 -4
- package/translateRange.d.ts +1 -5
- package/trimAnnStartEndToFitSeqLength.d.ts +1 -1
- package/trimNonCicularRangeByAnotherNonCircularRange.d.ts +4 -2
- package/trimNumberToFitWithin0ToAnotherNumber.d.ts +1 -1
- package/trimRangeByAnotherRange.d.ts +1 -2
- package/zeroSubrangeByContainerRange.d.ts +1 -2
- package/RangeAngles.d.ts +0 -7
- package/src/RangeAngles.ts +0 -9
- package/src/adjustRangeToDeletionOfAnotherRange.ts +0 -57
- package/src/adjustRangeToInsert.ts +0 -32
- package/src/adjustRangeToRotation.ts +0 -23
- package/src/checkIfNonCircularRangesOverlap.ts +0 -35
- package/src/checkIfPotentiallyCircularRangesOverlap.ts +0 -28
- package/src/collapseOverlapsGeneratedFromRangeComparisonIfPossible.ts +0 -81
- package/src/convertRangeIndices.ts +0 -34
- package/src/convertRangeTo0Based.ts +0 -9
- package/src/convertRangeTo1Based.ts +0 -10
- package/src/doesRangeSpanEntireSequence.ts +0 -12
- package/src/doesRangeSpanOrigin.ts +0 -5
- package/src/expandOrContractCircularRangeToPosition.ts +0 -50
- package/src/expandOrContractNonCircularRangeToPosition.ts +0 -30
- package/src/expandOrContractRangeByLength.ts +0 -18
- package/src/expandOrContractRangeToPosition.ts +0 -16
- package/src/flipContainedRange.ts +0 -156
- package/src/generateRandomRange.ts +0 -26
- package/src/getAnnotationRangeType.ts +0 -30
- package/src/getEachPositionInRangeAsArray.ts +0 -19
- package/src/getLengthOfOverlappingRegionsBetweenTwoRanges.ts +0 -18
- package/src/getMiddleOfRange.ts +0 -11
- package/src/getOverlapOfNonCircularRanges.ts +0 -41
- package/src/getOverlapsOfPotentiallyCircularRanges.ts +0 -60
- package/src/getPositionFromAngle.ts +0 -12
- package/src/getRangeAngles.ts +0 -38
- package/src/getRangeLength.test.ts +0 -30
- package/src/getRangeLength.ts +0 -17
- package/src/getRangesBetweenTwoRanges.ts +0 -42
- package/src/getSequenceWithinRange.test.ts +0 -47
- package/src/getSequenceWithinRange.ts +0 -24
- package/src/getShortestDistanceBetweenTwoPositions.test.ts +0 -12
- package/src/getShortestDistanceBetweenTwoPositions.ts +0 -16
- package/src/getYOffsetForPotentiallyCircularRange.ts +0 -37
- package/src/getYOffsetsForPotentiallyCircularRanges.test.ts +0 -17
- package/src/getYOffsetsForPotentiallyCircularRanges.ts +0 -28
- package/src/getZeroedRangeOverlaps.test.ts +0 -65
- package/src/getZeroedRangeOverlaps.ts +0 -33
- package/src/index.test.ts +0 -39
- package/src/index.ts +0 -53
- package/src/invertRange.ts +0 -25
- package/src/isPositionCloserToRangeStartThanRangeEnd.ts +0 -22
- package/src/isPositionWithinRange.ts +0 -40
- package/src/isRangeOrPositionWithinRange.ts +0 -40
- package/src/isRangeWithinRange.ts +0 -18
- package/src/loopEachPositionInRange.ts +0 -11
- package/src/modulatePositionByRange.ts +0 -15
- package/src/modulateRangeBySequenceLength.ts +0 -13
- package/src/normalizePositionByRangeLength.ts +0 -24
- package/src/normalizePositionByRangeLength1Based.ts +0 -9
- package/src/normalizeRange.ts +0 -12
- package/src/provideInclusiveOptions.ts +0 -79
- package/src/reversePositionInRange.ts +0 -17
- package/src/splitRangeIntoTwoPartsIfItIsCircular.ts +0 -36
- package/src/translateRange.ts +0 -21
- package/src/trimAnnStartEndToFitSeqLength.ts +0 -9
- package/src/trimNonCicularRangeByAnotherNonCircularRange.ts +0 -63
- package/src/trimNumberToFitWithin0ToAnotherNumber.ts +0 -15
- package/src/trimRangeByAnotherRange.ts +0 -103
- package/src/types.ts +0 -12
- package/src/zeroSubrangeByContainerRange.ts +0 -49
- package/types.d.ts +0 -12
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import getRangeLength from "./getRangeLength";
|
|
2
|
-
import getOverlapsOfPotentiallyCircularRanges from "./getOverlapsOfPotentiallyCircularRanges";
|
|
3
|
-
import { Range } from "./types";
|
|
4
|
-
|
|
5
|
-
export default function getLengthOfOverlappingRegionsBetweenTwoRanges(
|
|
6
|
-
rangeA: Range,
|
|
7
|
-
rangeB: Range,
|
|
8
|
-
maxLength: number
|
|
9
|
-
) {
|
|
10
|
-
const overlaps = getOverlapsOfPotentiallyCircularRanges(
|
|
11
|
-
rangeA,
|
|
12
|
-
rangeB,
|
|
13
|
-
maxLength
|
|
14
|
-
);
|
|
15
|
-
return overlaps.reduce(function (counter, overlap) {
|
|
16
|
-
return counter + getRangeLength(overlap, maxLength);
|
|
17
|
-
}, 0);
|
|
18
|
-
}
|
package/src/getMiddleOfRange.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import getRangeLength from "./getRangeLength";
|
|
2
|
-
import normalizePositionByRangeLength from "./normalizePositionByRangeLength";
|
|
3
|
-
import { Range } from "./types";
|
|
4
|
-
|
|
5
|
-
export default function getMiddleOfRange(range: Range, rangeMax: number) {
|
|
6
|
-
const len = getRangeLength({ start: range.start, end: range.end }, rangeMax);
|
|
7
|
-
return normalizePositionByRangeLength(
|
|
8
|
-
range.start + Math.floor(len / 2),
|
|
9
|
-
rangeMax
|
|
10
|
-
);
|
|
11
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { Range } from "./types";
|
|
2
|
-
|
|
3
|
-
export default function getOverlapOfNonCircularRanges(
|
|
4
|
-
rangeA: Range,
|
|
5
|
-
rangeB: Range
|
|
6
|
-
) {
|
|
7
|
-
if (rangeA.start < rangeB.start) {
|
|
8
|
-
if (rangeA.end < rangeB.start) {
|
|
9
|
-
//no overlap
|
|
10
|
-
} else {
|
|
11
|
-
if (rangeA.end < rangeB.end) {
|
|
12
|
-
return {
|
|
13
|
-
start: rangeB.start,
|
|
14
|
-
end: rangeA.end
|
|
15
|
-
};
|
|
16
|
-
} else {
|
|
17
|
-
return {
|
|
18
|
-
start: rangeB.start,
|
|
19
|
-
end: rangeB.end
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
} else {
|
|
24
|
-
if (rangeA.start > rangeB.end) {
|
|
25
|
-
//no overlap
|
|
26
|
-
} else {
|
|
27
|
-
if (rangeA.end < rangeB.end) {
|
|
28
|
-
return {
|
|
29
|
-
start: rangeA.start,
|
|
30
|
-
end: rangeA.end
|
|
31
|
-
};
|
|
32
|
-
} else {
|
|
33
|
-
return {
|
|
34
|
-
start: rangeA.start,
|
|
35
|
-
end: rangeB.end
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { flatMap } from "lodash-es";
|
|
2
|
-
import splitRangeIntoTwoPartsIfItIsCircular from "./splitRangeIntoTwoPartsIfItIsCircular";
|
|
3
|
-
import getOverlapOfNonCircularRanges from "./getOverlapOfNonCircularRanges";
|
|
4
|
-
|
|
5
|
-
//returns an array of the overlaps between two potentially circular ranges
|
|
6
|
-
import { Range } from "./types";
|
|
7
|
-
|
|
8
|
-
//returns an array of the overlaps between two potentially circular ranges
|
|
9
|
-
export default function getOverlapsOfPotentiallyCircularRanges(
|
|
10
|
-
rangeA: Range,
|
|
11
|
-
rangeB: Range,
|
|
12
|
-
maxRangeLength: number,
|
|
13
|
-
joinIfPossible = false //by default this fn only returns **non-circular** overlaps, if true it will try to join overlaps split on the origin
|
|
14
|
-
) {
|
|
15
|
-
const normalizedRangeA = splitRangeIntoTwoPartsIfItIsCircular(
|
|
16
|
-
rangeA,
|
|
17
|
-
maxRangeLength
|
|
18
|
-
);
|
|
19
|
-
const normalizedRangeB = splitRangeIntoTwoPartsIfItIsCircular(
|
|
20
|
-
rangeB,
|
|
21
|
-
maxRangeLength
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
let overlaps: Range[] = [];
|
|
25
|
-
|
|
26
|
-
normalizedRangeA.forEach(function (nonCircularRangeA) {
|
|
27
|
-
normalizedRangeB.forEach(function (nonCircularRangeB) {
|
|
28
|
-
const overlap = getOverlapOfNonCircularRanges(
|
|
29
|
-
nonCircularRangeA,
|
|
30
|
-
nonCircularRangeB
|
|
31
|
-
);
|
|
32
|
-
if (overlap) {
|
|
33
|
-
overlaps.push(overlap);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
if (
|
|
38
|
-
joinIfPossible &&
|
|
39
|
-
normalizedRangeA.length === 2 &&
|
|
40
|
-
normalizedRangeB.length === 2 &&
|
|
41
|
-
maxRangeLength
|
|
42
|
-
) {
|
|
43
|
-
//we have 2 circular ranges that will have gotten split on the origin, so we'll manually mend those pieces back together
|
|
44
|
-
const joinedOverlap: Partial<Range> = {};
|
|
45
|
-
overlaps = flatMap(overlaps, o => {
|
|
46
|
-
if (o.start === 0) {
|
|
47
|
-
joinedOverlap.end = o.end;
|
|
48
|
-
return [];
|
|
49
|
-
} else if (o.end === maxRangeLength - 1) {
|
|
50
|
-
joinedOverlap.start = o.start;
|
|
51
|
-
return [];
|
|
52
|
-
}
|
|
53
|
-
return [o];
|
|
54
|
-
});
|
|
55
|
-
if (Object.keys(joinedOverlap).length > 0) {
|
|
56
|
-
overlaps.push(joinedOverlap as Range);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return overlaps;
|
|
60
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export default function getPositionFromAngle(
|
|
2
|
-
angle: number,
|
|
3
|
-
rangeMax: number,
|
|
4
|
-
isInBetweenPositions?: boolean
|
|
5
|
-
) {
|
|
6
|
-
//percent through sequence * rangeMax
|
|
7
|
-
const unroundedPostion = (angle / Math.PI / 2) * rangeMax;
|
|
8
|
-
//return either the nearest position, or the nearest "inBetween" postion
|
|
9
|
-
return isInBetweenPositions
|
|
10
|
-
? Math.round(unroundedPostion)
|
|
11
|
-
: Math.floor(unroundedPostion);
|
|
12
|
-
}
|
package/src/getRangeAngles.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import getRangeLength from "./getRangeLength";
|
|
2
|
-
import { Range } from "./types";
|
|
3
|
-
import { RangeAngles } from "./RangeAngles";
|
|
4
|
-
|
|
5
|
-
export default function getRangeAngles(
|
|
6
|
-
range: Range,
|
|
7
|
-
rangeMax: number
|
|
8
|
-
): RangeAngles {
|
|
9
|
-
const { startAngle, totalAngle, endAngle } = getStartEndAndTotalAngle(
|
|
10
|
-
range,
|
|
11
|
-
rangeMax
|
|
12
|
-
);
|
|
13
|
-
|
|
14
|
-
return {
|
|
15
|
-
startAngle,
|
|
16
|
-
totalAngle,
|
|
17
|
-
endAngle,
|
|
18
|
-
centerAngle: startAngle + totalAngle / 2,
|
|
19
|
-
locationAngles:
|
|
20
|
-
range.locations &&
|
|
21
|
-
range.locations.map((location: Range) => {
|
|
22
|
-
return getRangeAngles(location, rangeMax);
|
|
23
|
-
})
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function getStartEndAndTotalAngle(range: Range, rangeMax: number) {
|
|
28
|
-
const rangeLength = getRangeLength(
|
|
29
|
-
{ start: range.start, end: range.end },
|
|
30
|
-
rangeMax
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
return {
|
|
34
|
-
startAngle: 2 * Math.PI * (range.start / rangeMax),
|
|
35
|
-
totalAngle: (rangeLength / rangeMax) * Math.PI * 2,
|
|
36
|
-
endAngle: (2 * Math.PI * (range.end + 1)) / rangeMax //use a +1 here because the angle must encompass the end of the annotation
|
|
37
|
-
};
|
|
38
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
//0123456789
|
|
2
|
-
//r--------r
|
|
3
|
-
//
|
|
4
|
-
//0123
|
|
5
|
-
//r--r
|
|
6
|
-
// 0
|
|
7
|
-
// 3 1
|
|
8
|
-
// 2
|
|
9
|
-
|
|
10
|
-
import assert from "assert";
|
|
11
|
-
|
|
12
|
-
import getRangeLength from "./getRangeLength";
|
|
13
|
-
describe("getRangeLength", function () {
|
|
14
|
-
it("should return the correct length for ranges that cross the origin", function () {
|
|
15
|
-
const length = getRangeLength({ start: 9, end: 0 }, 10);
|
|
16
|
-
assert(length === 2);
|
|
17
|
-
});
|
|
18
|
-
it("should return the correct length for ranges that do not cross the origin", function () {
|
|
19
|
-
const length = getRangeLength({ start: 4, end: 6 }, 10);
|
|
20
|
-
assert(length === 3);
|
|
21
|
-
});
|
|
22
|
-
it("should return the correct length for ranges that overlapSelf", function () {
|
|
23
|
-
const length = getRangeLength({ start: 4, end: 6, overlapsSelf: true }, 10);
|
|
24
|
-
assert(length === 13);
|
|
25
|
-
});
|
|
26
|
-
it("should return the correct length for ranges that overlapSelf and origin", function () {
|
|
27
|
-
const length = getRangeLength({ start: 9, end: 1, overlapsSelf: true }, 10);
|
|
28
|
-
assert(length === 13);
|
|
29
|
-
});
|
|
30
|
-
});
|
package/src/getRangeLength.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import provideInclusiveOptions from "./provideInclusiveOptions";
|
|
2
|
-
import { Range } from "./types";
|
|
3
|
-
|
|
4
|
-
export default provideInclusiveOptions(getRangeLength);
|
|
5
|
-
|
|
6
|
-
function getRangeLength(range: Range, rangeMax: number) {
|
|
7
|
-
let toRet;
|
|
8
|
-
if (range.end < range.start) {
|
|
9
|
-
toRet = rangeMax - range.start + range.end + 1;
|
|
10
|
-
} else {
|
|
11
|
-
toRet = range.end - range.start + 1;
|
|
12
|
-
}
|
|
13
|
-
if (range.overlapsSelf && rangeMax) {
|
|
14
|
-
toRet += rangeMax;
|
|
15
|
-
}
|
|
16
|
-
return toRet;
|
|
17
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { Range } from "./types";
|
|
2
|
-
|
|
3
|
-
export default function getRangesBetweenTwoRanges(
|
|
4
|
-
range1: Range,
|
|
5
|
-
range2: Range
|
|
6
|
-
) {
|
|
7
|
-
// {
|
|
8
|
-
// start: 85,
|
|
9
|
-
// end: 92
|
|
10
|
-
// }
|
|
11
|
-
|
|
12
|
-
// {
|
|
13
|
-
// start: 130,
|
|
14
|
-
// end: 189
|
|
15
|
-
// }
|
|
16
|
-
|
|
17
|
-
// start1 - end2
|
|
18
|
-
|
|
19
|
-
// start2 - end1
|
|
20
|
-
|
|
21
|
-
const newRanges: Range[] = [];
|
|
22
|
-
if (
|
|
23
|
-
!(
|
|
24
|
-
range1.start > -1 &&
|
|
25
|
-
range1.end > -1 &&
|
|
26
|
-
range2.start > -1 &&
|
|
27
|
-
range2.end > -1
|
|
28
|
-
)
|
|
29
|
-
) {
|
|
30
|
-
return newRanges;
|
|
31
|
-
}
|
|
32
|
-
return [
|
|
33
|
-
{
|
|
34
|
-
start: range1.start,
|
|
35
|
-
end: range2.end
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
start: range2.start,
|
|
39
|
-
end: range1.end
|
|
40
|
-
}
|
|
41
|
-
];
|
|
42
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import getSequenceWithinRange from "./getSequenceWithinRange.js";
|
|
2
|
-
|
|
3
|
-
import assert from "assert";
|
|
4
|
-
let subseq;
|
|
5
|
-
|
|
6
|
-
describe("getSequenceWithinRange", function () {
|
|
7
|
-
it("works with an array (translation amino acids for example) as well", function () {
|
|
8
|
-
subseq = getSequenceWithinRange({ start: 0, end: 0 }, ["a", "t", "g", "c"]);
|
|
9
|
-
assert.deepEqual(subseq, ["a"]);
|
|
10
|
-
subseq = getSequenceWithinRange({ start: 1, end: 1 }, ["a", "t", "g", "c"]);
|
|
11
|
-
assert.deepEqual(subseq, ["t"]);
|
|
12
|
-
subseq = getSequenceWithinRange({ start: 1, end: 0 }, ["a", "t", "g", "c"]);
|
|
13
|
-
assert.deepEqual(subseq, ["t", "g", "c", "a"]);
|
|
14
|
-
});
|
|
15
|
-
it("gets a non circular range", function () {
|
|
16
|
-
subseq = getSequenceWithinRange({ start: 0, end: 0 }, "atgc");
|
|
17
|
-
assert.equal(subseq, "a");
|
|
18
|
-
subseq = getSequenceWithinRange({ start: 1, end: 1 }, "atgc");
|
|
19
|
-
assert.equal(subseq, "t");
|
|
20
|
-
subseq = getSequenceWithinRange({ start: 0, end: 3 }, "atgc");
|
|
21
|
-
assert.equal(subseq, "atgc");
|
|
22
|
-
});
|
|
23
|
-
it("gets a circular range", function () {
|
|
24
|
-
subseq = getSequenceWithinRange({ start: 1, end: 0 }, "atgc");
|
|
25
|
-
assert.deepEqual(subseq, "tgca");
|
|
26
|
-
subseq = getSequenceWithinRange({ start: 2, end: 1 }, "atgc");
|
|
27
|
-
assert.deepEqual(subseq, "gcat");
|
|
28
|
-
subseq = getSequenceWithinRange({ start: 3, end: 0 }, "atgc");
|
|
29
|
-
assert.deepEqual(subseq, "ca");
|
|
30
|
-
});
|
|
31
|
-
it("gets a circular range", function () {
|
|
32
|
-
subseq = getSequenceWithinRange({ start: 1, end: 0 }, "atgc");
|
|
33
|
-
assert.deepEqual(subseq, "tgca");
|
|
34
|
-
subseq = getSequenceWithinRange({ start: 2, end: 1 }, "atgc");
|
|
35
|
-
assert.deepEqual(subseq, "gcat");
|
|
36
|
-
subseq = getSequenceWithinRange({ start: 3, end: 0 }, "atgc");
|
|
37
|
-
assert.deepEqual(subseq, "ca");
|
|
38
|
-
});
|
|
39
|
-
it("returns an empty string if the range is invalid", function () {
|
|
40
|
-
subseq = getSequenceWithinRange({ start: -1, end: 0 }, "atgc");
|
|
41
|
-
assert.deepEqual(subseq, "");
|
|
42
|
-
subseq = getSequenceWithinRange({ start: -1, end: -1 }, "atgc");
|
|
43
|
-
assert.deepEqual(subseq, "");
|
|
44
|
-
subseq = getSequenceWithinRange({ start: 3, end: -1 }, "atgc");
|
|
45
|
-
assert.deepEqual(subseq, "");
|
|
46
|
-
});
|
|
47
|
-
});
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Range } from "./types";
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
export default function getSequenceWithinRange<T>(
|
|
5
|
-
range: Range,
|
|
6
|
-
sequence: string | T[]
|
|
7
|
-
) {
|
|
8
|
-
// ac.throw([ac.range, ac.oneOfType([ac.array, ac.string])], arguments);
|
|
9
|
-
if (range.start < 0 || range.end < 0) return "";
|
|
10
|
-
if (range.start > range.end) {
|
|
11
|
-
//circular range
|
|
12
|
-
let subSequence = sequence.slice(range.start, sequence.length);
|
|
13
|
-
if (typeof subSequence === "string") {
|
|
14
|
-
subSequence += sequence.slice(0, range.end + 1);
|
|
15
|
-
} else {
|
|
16
|
-
subSequence = (subSequence as T[]).concat(
|
|
17
|
-
sequence.slice(0, range.end + 1) as T[]
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
return subSequence;
|
|
21
|
-
} else {
|
|
22
|
-
return sequence.slice(range.start, range.end + 1);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import assert from "assert";
|
|
2
|
-
import getShortestDistanceBetweenTwoPositions from "./getShortestDistanceBetweenTwoPositions";
|
|
3
|
-
describe("getShortestDistanceBetweenTwoPositions", function () {
|
|
4
|
-
it("should return the correct length for positions that cross the origin", function () {
|
|
5
|
-
const length = getShortestDistanceBetweenTwoPositions(9, 0, 10);
|
|
6
|
-
assert(length === 1);
|
|
7
|
-
});
|
|
8
|
-
it("should return the correct length for ranges that do not cross the origin", function () {
|
|
9
|
-
const length = getShortestDistanceBetweenTwoPositions(4, 6, 10);
|
|
10
|
-
assert(length === 2);
|
|
11
|
-
});
|
|
12
|
-
});
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export default function getShortestDistanceBetweenTwoPositions(
|
|
2
|
-
position1: number,
|
|
3
|
-
position2: number,
|
|
4
|
-
sequenceLength: number
|
|
5
|
-
) {
|
|
6
|
-
if (position1 < position2) {
|
|
7
|
-
const position1Holder = position1;
|
|
8
|
-
position1 = position2;
|
|
9
|
-
position2 = position1Holder;
|
|
10
|
-
}
|
|
11
|
-
//position 1 is now always >= position 2
|
|
12
|
-
|
|
13
|
-
const d1 = position1 - position2;
|
|
14
|
-
const d2 = sequenceLength - position1 + position2;
|
|
15
|
-
return Math.min(d1, d2);
|
|
16
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import checkIfPotentiallyCircularRangesOverlap from "./checkIfPotentiallyCircularRangesOverlap";
|
|
2
|
-
import { Range } from "./types";
|
|
3
|
-
|
|
4
|
-
export default function getYOffsetForPotentiallyCircularRange(
|
|
5
|
-
range: Range,
|
|
6
|
-
YOffsetLevelsWithRanges: Range[][],
|
|
7
|
-
assignYOffsetToRange: boolean
|
|
8
|
-
) {
|
|
9
|
-
//adjust the yOffset of the range being pushed in by checking its range against other range already in the row
|
|
10
|
-
let yOffset = 0;
|
|
11
|
-
//YOffsetLevelsWithRanges is an array of arrays (array of yOffset levels holding arrays of range)
|
|
12
|
-
//loop through y offset levels starting with the 0 level until an empty one is found and push the range into it. If none are found, add another level.
|
|
13
|
-
const openYOffsetFound = YOffsetLevelsWithRanges.some(
|
|
14
|
-
function (rangesAlreadyAddedToYOffset, index) {
|
|
15
|
-
const rangeBlocked = rangesAlreadyAddedToYOffset.some(
|
|
16
|
-
function (comparisonRange) {
|
|
17
|
-
return checkIfPotentiallyCircularRangesOverlap(
|
|
18
|
-
range,
|
|
19
|
-
comparisonRange
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
);
|
|
23
|
-
if (!rangeBlocked) {
|
|
24
|
-
yOffset = index;
|
|
25
|
-
if (assignYOffsetToRange) range.yOffset = index;
|
|
26
|
-
rangesAlreadyAddedToYOffset.push(range);
|
|
27
|
-
return true;
|
|
28
|
-
}
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
);
|
|
32
|
-
if (!openYOffsetFound) {
|
|
33
|
-
yOffset = YOffsetLevelsWithRanges.length;
|
|
34
|
-
if (assignYOffsetToRange) range.yOffset = YOffsetLevelsWithRanges.length;
|
|
35
|
-
}
|
|
36
|
-
return yOffset;
|
|
37
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { expect } from "chai";
|
|
2
|
-
import getYOffsetsForPotentiallyCircularRanges from "./getYOffsetsForPotentiallyCircularRanges.js";
|
|
3
|
-
describe("getYOffsetsForPotentiallyCircularRanges", function () {
|
|
4
|
-
it("returns correct yOffset for overlapping ranges", function () {
|
|
5
|
-
const ranges = [
|
|
6
|
-
{ start: 0, end: 10, id: "1" },
|
|
7
|
-
{ start: 5, end: 20, id: "2" },
|
|
8
|
-
{ start: 15, end: 25, id: "3" }
|
|
9
|
-
];
|
|
10
|
-
getYOffsetsForPotentiallyCircularRanges(ranges, false);
|
|
11
|
-
expect(ranges).to.deep.equal([
|
|
12
|
-
{ start: 0, end: 10, id: "1", yOffset: 0 },
|
|
13
|
-
{ start: 5, end: 20, id: "2", yOffset: 1 },
|
|
14
|
-
{ start: 15, end: 25, id: "3", yOffset: 0 }
|
|
15
|
-
]);
|
|
16
|
-
});
|
|
17
|
-
});
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import getYOffsetForPotentiallyCircularRange from "./getYOffsetForPotentiallyCircularRange";
|
|
2
|
-
import { Range } from "./types";
|
|
3
|
-
|
|
4
|
-
export default function getYOffsetsForPotentiallyCircularRanges(
|
|
5
|
-
ranges: Range[],
|
|
6
|
-
assignYOffsetToRange: boolean
|
|
7
|
-
) {
|
|
8
|
-
//adjust the yOffset of the range being pushed in by checking its range against other ranges already in the row
|
|
9
|
-
const yOffsets: number[] = [];
|
|
10
|
-
let maxYOffset = 0;
|
|
11
|
-
const yOffsetLevels: Range[][] = []; //yOffsetLevels is an array of arrays (array of yOffset levels holding arrays of ranges)
|
|
12
|
-
ranges.forEach(function (range) {
|
|
13
|
-
//loop through y offset levels starting with the 0 level until an empty one is found and push the range into it. If none are found, add another level.
|
|
14
|
-
const yOffset = getYOffsetForPotentiallyCircularRange(
|
|
15
|
-
range,
|
|
16
|
-
yOffsetLevels,
|
|
17
|
-
assignYOffsetToRange
|
|
18
|
-
);
|
|
19
|
-
yOffsets.push(yOffset);
|
|
20
|
-
if (yOffset > maxYOffset) {
|
|
21
|
-
maxYOffset = yOffset;
|
|
22
|
-
}
|
|
23
|
-
range.yOffset = yOffset;
|
|
24
|
-
if (!yOffsetLevels[yOffset]) yOffsetLevels[yOffset] = [];
|
|
25
|
-
yOffsetLevels[yOffset].push(range);
|
|
26
|
-
});
|
|
27
|
-
return { yOffsets: yOffsets, maxYOffset: maxYOffset };
|
|
28
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import assert from "assert";
|
|
2
|
-
import getZeroedRangeOverlaps from "./getZeroedRangeOverlaps";
|
|
3
|
-
describe("getZeroedRangeOverlaps", function () {
|
|
4
|
-
it("annotation non-circular, selection non circular ", function () {
|
|
5
|
-
const res = getZeroedRangeOverlaps(
|
|
6
|
-
{ start: 0, end: 3 },
|
|
7
|
-
{ start: 2, end: 3 },
|
|
8
|
-
4
|
|
9
|
-
);
|
|
10
|
-
assert.deepEqual(res, [{ start: 0, end: 1 }]);
|
|
11
|
-
});
|
|
12
|
-
it("annotation non circular, selection circular", function () {
|
|
13
|
-
//01234
|
|
14
|
-
//aaaa
|
|
15
|
-
//s sss
|
|
16
|
-
const res = getZeroedRangeOverlaps(
|
|
17
|
-
{ start: 0, end: 3 },
|
|
18
|
-
{ start: 2, end: 0 },
|
|
19
|
-
5
|
|
20
|
-
);
|
|
21
|
-
assert.deepEqual(res, [
|
|
22
|
-
{ start: 3, end: 3 },
|
|
23
|
-
{ start: 0, end: 1 }
|
|
24
|
-
]);
|
|
25
|
-
});
|
|
26
|
-
it("annotation non circular, selection circular 2", function () {
|
|
27
|
-
//0123
|
|
28
|
-
//aaaa
|
|
29
|
-
//ssss
|
|
30
|
-
const res = getZeroedRangeOverlaps(
|
|
31
|
-
{ start: 0, end: 3 },
|
|
32
|
-
{ start: 2, end: 1 },
|
|
33
|
-
4
|
|
34
|
-
);
|
|
35
|
-
assert.deepEqual(res, [
|
|
36
|
-
{ start: 2, end: 3 },
|
|
37
|
-
{ start: 0, end: 1 }
|
|
38
|
-
]);
|
|
39
|
-
});
|
|
40
|
-
it("annotation circular, selection fully containing", function () {
|
|
41
|
-
//01234
|
|
42
|
-
//aa aa
|
|
43
|
-
//sssss
|
|
44
|
-
const res = getZeroedRangeOverlaps(
|
|
45
|
-
{ start: 3, end: 1 },
|
|
46
|
-
{ start: 0, end: 4 },
|
|
47
|
-
5
|
|
48
|
-
);
|
|
49
|
-
assert.deepEqual(res, [{ start: 3, end: 1 }]);
|
|
50
|
-
});
|
|
51
|
-
it("annotation circular, selection fully containing 2", function () {
|
|
52
|
-
//01234
|
|
53
|
-
//aa aa
|
|
54
|
-
//sssss
|
|
55
|
-
const res = getZeroedRangeOverlaps(
|
|
56
|
-
{ start: 3, end: 1 },
|
|
57
|
-
{ start: 1, end: 0 },
|
|
58
|
-
5
|
|
59
|
-
);
|
|
60
|
-
assert.deepEqual(res, [
|
|
61
|
-
{ start: 2, end: 4 },
|
|
62
|
-
{ start: 0, end: 0 }
|
|
63
|
-
]);
|
|
64
|
-
});
|
|
65
|
-
});
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { Range } from "./types";
|
|
2
|
-
import getOverlapsOfPotentiallyCircularRanges from "./getOverlapsOfPotentiallyCircularRanges";
|
|
3
|
-
import collapseOverlapsGeneratedFromRangeComparisonIfPossible from "./collapseOverlapsGeneratedFromRangeComparisonIfPossible";
|
|
4
|
-
import zeroSubrangeByContainerRange from "./zeroSubrangeByContainerRange";
|
|
5
|
-
import normalizePositionByRangeLength from "./normalizePositionByRangeLength";
|
|
6
|
-
|
|
7
|
-
//gets the overlapping sections of two ranges and zeroes them to their first point of intersection!
|
|
8
|
-
export default function getZeroedRangeOverlaps(
|
|
9
|
-
annotation: Range,
|
|
10
|
-
selection: Range,
|
|
11
|
-
sequenceLength: number
|
|
12
|
-
) {
|
|
13
|
-
const overlaps = collapseOverlapsGeneratedFromRangeComparisonIfPossible(
|
|
14
|
-
getOverlapsOfPotentiallyCircularRanges(
|
|
15
|
-
annotation,
|
|
16
|
-
selection,
|
|
17
|
-
sequenceLength
|
|
18
|
-
),
|
|
19
|
-
sequenceLength,
|
|
20
|
-
annotation
|
|
21
|
-
);
|
|
22
|
-
const zeroedOverlaps = overlaps.map(overlap => {
|
|
23
|
-
return zeroSubrangeByContainerRange(
|
|
24
|
-
overlap,
|
|
25
|
-
{
|
|
26
|
-
start: selection.start,
|
|
27
|
-
end: normalizePositionByRangeLength(selection.start - 1, sequenceLength)
|
|
28
|
-
},
|
|
29
|
-
sequenceLength
|
|
30
|
-
);
|
|
31
|
-
});
|
|
32
|
-
return zeroedOverlaps;
|
|
33
|
-
}
|
package/src/index.test.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import * as src from "./index";
|
|
2
|
-
import fs from "fs";
|
|
3
|
-
|
|
4
|
-
describe("index.js", () => {
|
|
5
|
-
it(`should export all functions defined`, () => {
|
|
6
|
-
return new Promise<void>(resolve => {
|
|
7
|
-
fs.readdir(__dirname, (err, files) => {
|
|
8
|
-
let passes = true;
|
|
9
|
-
files.forEach(file => {
|
|
10
|
-
if (
|
|
11
|
-
file.indexOf(".test.js") > -1 ||
|
|
12
|
-
file.indexOf(".test.ts") > -1 ||
|
|
13
|
-
file.indexOf("index.js") > -1 ||
|
|
14
|
-
file.indexOf("types.ts") > -1 ||
|
|
15
|
-
file.indexOf("RangeAngles.ts") > -1 ||
|
|
16
|
-
file.indexOf("index.ts") > -1
|
|
17
|
-
) {
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
-
const funcOrObj = (src as any)[file.replace(/\.(ts|js)$/, "")];
|
|
22
|
-
if (!funcOrObj) {
|
|
23
|
-
console.info(
|
|
24
|
-
`Uh oh, it looks like you forgot to export (or explicitly ignore) this file:`,
|
|
25
|
-
file
|
|
26
|
-
);
|
|
27
|
-
passes = false;
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
if (!passes) {
|
|
31
|
-
throw new Error(
|
|
32
|
-
"Please make sure to export (or ignore) each file! Update index.js to export the file"
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
resolve();
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
});
|
package/src/index.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
export { default as adjustRangeToDeletionOfAnotherRange } from "./adjustRangeToDeletionOfAnotherRange";
|
|
2
|
-
export { default as adjustRangeToInsert } from "./adjustRangeToInsert";
|
|
3
|
-
export { default as checkIfNonCircularRangesOverlap } from "./checkIfNonCircularRangesOverlap";
|
|
4
|
-
export { default as checkIfPotentiallyCircularRangesOverlap } from "./checkIfPotentiallyCircularRangesOverlap";
|
|
5
|
-
export { default as collapseOverlapsGeneratedFromRangeComparisonIfPossible } from "./collapseOverlapsGeneratedFromRangeComparisonIfPossible";
|
|
6
|
-
export { default as convertRangeIndices } from "./convertRangeIndices";
|
|
7
|
-
export { default as convertRangeTo0Based } from "./convertRangeTo0Based";
|
|
8
|
-
export { default as convertRangeTo1Based } from "./convertRangeTo1Based";
|
|
9
|
-
export { default as doesRangeSpanEntireSequence } from "./doesRangeSpanEntireSequence";
|
|
10
|
-
export { default as isRangeOrPositionWithinRange } from "./isRangeOrPositionWithinRange";
|
|
11
|
-
export { default as doesRangeSpanOrigin } from "./doesRangeSpanOrigin";
|
|
12
|
-
export { default as expandOrContractCircularRangeToPosition } from "./expandOrContractCircularRangeToPosition";
|
|
13
|
-
export { default as expandOrContractNonCircularRangeToPosition } from "./expandOrContractNonCircularRangeToPosition";
|
|
14
|
-
export { default as expandOrContractRangeByLength } from "./expandOrContractRangeByLength";
|
|
15
|
-
export { default as expandOrContractRangeToPosition } from "./expandOrContractRangeToPosition";
|
|
16
|
-
export { default as flipContainedRange } from "./flipContainedRange";
|
|
17
|
-
export { default as generateRandomRange } from "./generateRandomRange";
|
|
18
|
-
export { default as getAnnotationRangeType } from "./getAnnotationRangeType";
|
|
19
|
-
export { default as getEachPositionInRangeAsArray } from "./getEachPositionInRangeAsArray";
|
|
20
|
-
export { default as getLengthOfOverlappingRegionsBetweenTwoRanges } from "./getLengthOfOverlappingRegionsBetweenTwoRanges";
|
|
21
|
-
export { default as getOverlapOfNonCircularRanges } from "./getOverlapOfNonCircularRanges";
|
|
22
|
-
export { default as getOverlapsOfPotentiallyCircularRanges } from "./getOverlapsOfPotentiallyCircularRanges";
|
|
23
|
-
export { default as getPositionFromAngle } from "./getPositionFromAngle";
|
|
24
|
-
export { default as getRangeAngles } from "./getRangeAngles";
|
|
25
|
-
export { default as getRangeLength } from "./getRangeLength";
|
|
26
|
-
export { default as getMiddleOfRange } from "./getMiddleOfRange";
|
|
27
|
-
export { default as getRangesBetweenTwoRanges } from "./getRangesBetweenTwoRanges";
|
|
28
|
-
export { default as getSequenceWithinRange } from "./getSequenceWithinRange";
|
|
29
|
-
export { default as getShortestDistanceBetweenTwoPositions } from "./getShortestDistanceBetweenTwoPositions";
|
|
30
|
-
export { default as getYOffsetForPotentiallyCircularRange } from "./getYOffsetForPotentiallyCircularRange";
|
|
31
|
-
export { default as getYOffsetsForPotentiallyCircularRanges } from "./getYOffsetsForPotentiallyCircularRanges";
|
|
32
|
-
export { default as invertRange } from "./invertRange";
|
|
33
|
-
export { default as isPositionCloserToRangeStartThanRangeEnd } from "./isPositionCloserToRangeStartThanRangeEnd";
|
|
34
|
-
export { default as isPositionWithinRange } from "./isPositionWithinRange";
|
|
35
|
-
export { default as isRangeWithinRange } from "./isRangeWithinRange";
|
|
36
|
-
export { default as loopEachPositionInRange } from "./loopEachPositionInRange";
|
|
37
|
-
export { default as modulatePositionByRange } from "./modulatePositionByRange";
|
|
38
|
-
export { default as modulateRangeBySequenceLength } from "./modulateRangeBySequenceLength";
|
|
39
|
-
export { default as normalizePositionByRangeLength } from "./normalizePositionByRangeLength";
|
|
40
|
-
export { default as normalizePositionByRangeLength1Based } from "./normalizePositionByRangeLength1Based";
|
|
41
|
-
export { default as normalizeRange } from "./normalizeRange";
|
|
42
|
-
export { default as provideInclusiveOptions } from "./provideInclusiveOptions";
|
|
43
|
-
export { default as reversePositionInRange } from "./reversePositionInRange";
|
|
44
|
-
export { default as splitRangeIntoTwoPartsIfItIsCircular } from "./splitRangeIntoTwoPartsIfItIsCircular";
|
|
45
|
-
export { default as translateRange } from "./translateRange";
|
|
46
|
-
export { default as trimNonCicularRangeByAnotherNonCircularRange } from "./trimNonCicularRangeByAnotherNonCircularRange";
|
|
47
|
-
export { default as trimNumberToFitWithin0ToAnotherNumber } from "./trimNumberToFitWithin0ToAnotherNumber";
|
|
48
|
-
export { default as trimRangeByAnotherRange } from "./trimRangeByAnotherRange";
|
|
49
|
-
export { default as zeroSubrangeByContainerRange } from "./zeroSubrangeByContainerRange";
|
|
50
|
-
export { default as adjustRangeToRotation } from "./adjustRangeToRotation";
|
|
51
|
-
export { default as getZeroedRangeOverlaps } from "./getZeroedRangeOverlaps";
|
|
52
|
-
export { default as trimAnnStartEndToFitSeqLength } from "./trimAnnStartEndToFitSeqLength";
|
|
53
|
-
export * from "./types";
|