diff --git a/README.md b/README.md
index bb51dbe..1c7d586 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@
* **[VariantKey Format](#vkformat)**
* [VariantKey Properties](#vkproperties)
* [VariantKey Input values](#vkinput)
-* [RegionKey](#regionkey)
+* **[RegionKey](#regionkey)**
* [Binary file formats for lookup tables](#binaryfiles)
* [C Library](#clib)
* [GO Library](#golib)
@@ -369,7 +369,11 @@ The VariantKey is composed of 3 sections arranged in 64 bit:
## RegionKey
-This library also includes functions to represent a human genetic region as number.
+*RegionKey* encodes a human genetic region (defined as the set of *chromosome*, *start position*, *end position* and *strand direction*) in a 64 bit unsigned integer number.
+
+RegionKey allows to repesent a region as a single entity, and provides analogous properties as the ones listed in [VariantKey Properties](#vkproperties).
+
+The encoding of the first 33 bit (CROM, STARTPOS) is the same as in VariantKey.
The RegionKey is composed of 4 sections arranged in 64 bit:
@@ -433,7 +437,9 @@ The RegionKey is composed of 4 sections arranged in 64 bit:
+1 : 1 dec = "01" bin
```
-The last bit of RegionKey is reserved.
+* The last bit of RegionKey is reserved.
+
+This software library provides several functions to operate with *RegionKey* and interact with *VariantKey*.
diff --git a/VERSION b/VERSION
index edcfe40..68e69e4 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.14.0
+2.15.0
diff --git a/c/src/nrvk.c b/c/src/nrvk.c
index 05c40ce..21f66c4 100644
--- a/c/src/nrvk.c
+++ b/c/src/nrvk.c
@@ -58,11 +58,9 @@ size_t find_ref_alt_by_variantkey(const unsigned char *src, uint64_t last, uint6
size_t reverse_variantkey(const unsigned char *src, uint64_t last, uint64_t vk, variantkey_rev_t *rev)
{
- variantkey_t h = {0,0,0};
- decode_variantkey(vk, &h);
- decode_chrom(h.chrom, rev->chrom);
- rev->pos = h.pos;
- size_t len = decode_refalt(h.refalt, rev->ref, &rev->sizeref, rev->alt, &rev->sizealt);
+ decode_chrom(extract_variantkey_chrom(vk), rev->chrom);
+ rev->pos = extract_variantkey_pos(vk);
+ size_t len = decode_refalt(extract_variantkey_refalt(vk), rev->ref, &rev->sizeref, rev->alt, &rev->sizealt);
if ((len == 0) && (last > 0))
{
len = find_ref_alt_by_variantkey(src, last, vk, rev->ref, &rev->sizeref, rev->alt, &rev->sizealt);
diff --git a/c/src/regionkey.c b/c/src/regionkey.c
index c7d48dd..371148d 100644
--- a/c/src/regionkey.c
+++ b/c/src/regionkey.c
@@ -80,12 +80,10 @@ void decode_regionkey(uint64_t code, regionkey_t *rk)
void reverse_regionkey(uint64_t rk, regionkey_rev_t *rev)
{
- regionkey_t h = {0,0,0,0};
- decode_regionkey(rk, &h);
- decode_chrom(h.chrom, rev->chrom);
- rev->startpos = h.startpos;
- rev->endpos = h.endpos;
- rev->strand = decode_region_strand(h.strand);
+ decode_chrom(extract_regionkey_chrom(rk), rev->chrom);
+ rev->startpos = extract_regionkey_startpos(rk);
+ rev->endpos = extract_regionkey_endpos(rk);
+ rev->strand = decode_region_strand(extract_regionkey_strand(rk));
}
uint64_t regionkey(const char *chrom, size_t sizechrom, uint32_t startpos, uint32_t endpos, int8_t strand)
diff --git a/conda/c.vk/meta.yaml b/conda/c.vk/meta.yaml
index ad00a72..9cab2d1 100644
--- a/conda/c.vk/meta.yaml
+++ b/conda/c.vk/meta.yaml
@@ -1,6 +1,6 @@
package:
name: vk
- version: 2.14.0
+ version: 2.15.0
source:
path: ../..
diff --git a/conda/python/meta.yaml b/conda/python/meta.yaml
index 274ec5f..3cc9ebd 100644
--- a/conda/python/meta.yaml
+++ b/conda/python/meta.yaml
@@ -1,6 +1,6 @@
package:
name: variantkey
- version: 2.14.0
+ version: 2.15.0
source:
path: ../..
diff --git a/conda/r/meta.yaml b/conda/r/meta.yaml
index 5484775..79e0396 100644
--- a/conda/r/meta.yaml
+++ b/conda/r/meta.yaml
@@ -1,6 +1,6 @@
package:
name: r-variantkey
- version: 2.14.0
+ version: 2.15.0
source:
path: ../..
diff --git a/javascript/Makefile b/javascript/Makefile
index 13297ae..5672640 100644
--- a/javascript/Makefile
+++ b/javascript/Makefile
@@ -33,6 +33,7 @@ build:
@mkdir -p target/build
uglifyjs --compress --keep-fnames --comments --output target/build/variantkey.js src/variantkey.js
cd test && node test_variantkey.js '../target/build/variantkey.js'
+ cd test && node test_regionkey.js '../target/build/variantkey.js'
# Format the source code
format:
diff --git a/javascript/src/variantkey.js b/javascript/src/variantkey.js
index 692aa5e..be18af3 100644
--- a/javascript/src/variantkey.js
+++ b/javascript/src/variantkey.js
@@ -39,7 +39,7 @@ function encodeChrom(chrom) {
return 0;
}
// X > 23 ; Y > 24 ; M > 25
- onecharmap = [
+ var onecharmap = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* M X Y */
@@ -90,7 +90,7 @@ function encodeBase(c) {
G > 2
T > 3
*/
- map = [
+ var map = [
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
/* A C G T */
@@ -259,7 +259,7 @@ function extractVariantKeyChrom(vk) {
}
function extractVariantKeyPos(vk) {
- return (((vk.hi & 0x7FFFFFF) << 1) | (vk.lo >>> 31)) >>> 0;
+ return (((vk.hi & 0x07FFFFFF) << 1) | (vk.lo >>> 31)) >>> 0;
}
function extractVariantKeyRefAlt(vk) {
@@ -274,6 +274,16 @@ function decodeVariantKey(vk) {
};
}
+function reverseVariantKey(vk) {
+ var ra = decodeRefAlt(extractVariantKeyRefAlt(vk));
+ return {
+ "chrom": decodeChrom(extractVariantKeyChrom(vk)),
+ "pos": extractVariantKeyPos(vk),
+ "ref": ra.ref,
+ "alt": ra.alt
+ }
+}
+
function variantKey(chrom, pos, ref, alt) {
return encodeVariantKey(encodeChrom(chrom), pos, encodeRefAlt(ref, alt));
}
@@ -322,14 +332,90 @@ function parseHex(vs) {
};
}
-function reverseVariantKey(dvk) {
- var ra = decodeRefAlt(dvk.refalt);
+function encodeRegionStrand(strand) {
+ var map = [2, 0, 1, 0];
+ return map[((++strand) & 3)];
+}
+
+function decodeRegionStrand(strand) {
+ var map = [0, 1, -1, 0];
+ return map[(strand & 3)];
+}
+
+function encodeRegionKey(chrom, startpos, endpos, strand) {
return {
- "chrom": decodeChrom(dvk.chrom),
- "pos": dvk.pos,
- "ref": ra.ref,
- "alt": ra.alt
- }
+ "hi": ((((chrom >>> 0) << 27) | (startpos >>> 1)) >>> 0),
+ "lo": ((((startpos >>> 0) << 31) | ((endpos >>> 0) << 3) | ((strand >>> 0) << 1)) >>> 0)
+ };
+}
+
+function extractRegionKeyChrom(rk) {
+ return ((rk.hi & 0xF8000000) >>> 27);
+}
+
+function extractRegionKeyStartPos(rk) {
+ return (((rk.hi & 0x07FFFFFF) << 1) | (rk.lo >>> 31)) >>> 0;
+}
+
+function extractRegionKeyEndPos(rk) {
+ return (rk.lo & 0x7FFFFFF8) >>> 3
+}
+
+function extractRegionKeyStrand(rk) {
+ return (rk.lo & 0x00000006) >>> 1;
+}
+
+function decodeRegionKey(rk) {
+ return {
+ "chrom": extractRegionKeyChrom(rk),
+ "startpos": extractRegionKeyStartPos(rk),
+ "endpos": extractRegionKeyEndPos(rk),
+ "strand": extractRegionKeyStrand(rk)
+ };
+}
+
+function reverseRegionKey(rk) {
+ return {
+ "chrom": decodeChrom(extractRegionKeyChrom(rk)),
+ "startpos": extractRegionKeyStartPos(rk),
+ "endpos": extractRegionKeyEndPos(rk),
+ "strand": decodeRegionStrand(extractRegionKeyStrand(rk))
+ };
+}
+
+function regionKey(chrom, startpos, endpos, strand) {
+ return encodeRegionKey(encodeChrom(chrom), startpos, endpos, encodeRegionStrand(strand));
+}
+
+function regionKeyString(rk) {
+ return padL08(rk.hi.toString(16)) + padL08(rk.lo.toString(16));
+}
+
+function getVariantKeyEndPos(vk) {
+ return extractVariantKeyPos(vk) + ((vk.lo & 0x78000000) >>> 27);
+}
+
+function areOverlappingRegions(a_chrom, a_startpos, a_endpos, b_chrom, b_startpos, b_endpos) {
+ return ((a_chrom == b_chrom) && (a_startpos < b_endpos) && (a_endpos > b_startpos));
+}
+
+function areOverlappingRegionRegionKey(chrom, startpos, endpos, rk) {
+ return ((chrom == extractRegionKeyChrom(rk)) && (startpos < extractRegionKeyEndPos(rk)) && (endpos > extractRegionKeyStartPos(rk)));
+}
+
+function areOverlappingRegionKeys(rka, rkb) {
+ return ((extractRegionKeyChrom(rka) == extractRegionKeyChrom(rkb)) && (extractRegionKeyStartPos(rka) < extractRegionKeyEndPos(rkb)) && (extractRegionKeyEndPos(rka) > extractRegionKeyStartPos(rkb)));
+}
+
+function areOverlappingVariantKeyRegionKey(vk, rk) {
+ return ((extractVariantKeyChrom(vk) == extractRegionKeyChrom(rk)) && (extractVariantKeyPos(vk) < extractRegionKeyEndPos(rk)) && (getVariantKeyEndPos(vk) > extractRegionKeyStartPos(rk)));
+}
+
+function variantKeyToRegionKey(vk) {
+ return {
+ "hi": vk.hi,
+ "lo": ((vk.lo & 0x80000000) | ((getVariantKeyEndPos(vk) << 3) >>> 0)) >>> 0
+ };
}
if (typeof(module) !== 'undefined') {
@@ -351,5 +437,22 @@ if (typeof(module) !== 'undefined') {
compareVariantKeyChromPos: compareVariantKeyChromPos,
variantKeyString: variantKeyString,
reverseVariantKey: reverseVariantKey,
+ encodeRegionStrand: encodeRegionStrand,
+ decodeRegionStrand: decodeRegionStrand,
+ encodeRegionKey: encodeRegionKey,
+ extractRegionKeyChrom: extractRegionKeyChrom,
+ extractRegionKeyStartPos: extractRegionKeyStartPos,
+ extractRegionKeyEndPos: extractRegionKeyEndPos,
+ extractRegionKeyStrand: extractRegionKeyStrand,
+ decodeRegionKey: decodeRegionKey,
+ reverseRegionKey: reverseRegionKey,
+ regionKey: regionKey,
+ regionKeyString: regionKeyString,
+ getVariantKeyEndPos: getVariantKeyEndPos,
+ areOverlappingRegions: areOverlappingRegions,
+ areOverlappingRegionRegionKey: areOverlappingRegionRegionKey,
+ areOverlappingRegionKeys: areOverlappingRegionKeys,
+ areOverlappingVariantKeyRegionKey: areOverlappingVariantKeyRegionKey,
+ variantKeyToRegionKey: variantKeyToRegionKey,
}
}
\ No newline at end of file
diff --git a/javascript/test/test_regionkey.js b/javascript/test/test_regionkey.js
new file mode 100644
index 0000000..ec5b9df
--- /dev/null
+++ b/javascript/test/test_regionkey.js
@@ -0,0 +1,376 @@
+/** VariantKey Javascript Library Test
+ *
+ * regionkey.js
+ *
+ * @category Tools
+ * @author Nicola Asuni
+ * @copyright 2017-2018 GENOMICS plc
+ * @license MIT (see LICENSE)
+ * @link https://github.com/genomicsplc/variantkey
+ */
+
+// LICENSE
+//
+// Copyright (c) 2017-2018 GENOMICS plc
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+const {
+ encodeRegionStrand,
+ decodeRegionStrand,
+ encodeRegionKey,
+ extractRegionKeyChrom,
+ extractRegionKeyStartPos,
+ extractRegionKeyEndPos,
+ extractRegionKeyStrand,
+ decodeRegionKey,
+ reverseRegionKey,
+ regionKey,
+ regionKeyString,
+ getVariantKeyEndPos,
+ areOverlappingRegions,
+ areOverlappingRegionRegionKey,
+ areOverlappingRegionKeys,
+ areOverlappingVariantKeyRegionKey,
+ variantKeyToRegionKey,
+} = require(process.argv[2]);
+
+var k_test_size = 10;
+// 0 1 2 3 4 5 6 7 8 9
+// chrom, startpos, endpos, strand, echrom, estrand, rk, rs, chrom_startpos, chrom_endpos
+var test_data = [
+ [ "1", 1000, 1100, 0, 1, 0, {"hi": 0x080001f4, "lo": 0x00002260}, "080001f400002260", {"hi": 0x00000000, "lo": 0x100003e8}, {"hi": 0x00000000, "lo": 0x1000044c}],
+ [ "2", 1001, 1201, 1, 2, 1, {"hi": 0x100001f4, "lo": 0x8000258a}, "100001f48000258a", {"hi": 0x00000000, "lo": 0x200003e9}, {"hi": 0x00000000, "lo": 0x200004b1}],
+ [ "3", 1002, 1302, -1, 3, 2, {"hi": 0x180001f5, "lo": 0x000028b4}, "180001f5000028b4", {"hi": 0x00000000, "lo": 0x300003ea}, {"hi": 0x00000000, "lo": 0x30000516}],
+ [ "4", 1003, 1403, 0, 4, 0, {"hi": 0x200001f5, "lo": 0x80002bd8}, "200001f580002bd8", {"hi": 0x00000000, "lo": 0x400003eb}, {"hi": 0x00000000, "lo": 0x4000057b}],
+ [ "5", 1004, 1504, 1, 5, 1, {"hi": 0x280001f6, "lo": 0x00002f02}, "280001f600002f02", {"hi": 0x00000000, "lo": 0x500003ec}, {"hi": 0x00000000, "lo": 0x500005e0}],
+ ["10", 1005, 1605, -1, 10, 2, {"hi": 0x500001f6, "lo": 0x8000322c}, "500001f68000322c", {"hi": 0x00000000, "lo": 0xa00003ed}, {"hi": 0x00000000, "lo": 0xa0000645}],
+ ["22", 1006, 1706, 0, 22, 0, {"hi": 0xb00001f7, "lo": 0x00003550}, "b00001f700003550", {"hi": 0x00000001, "lo": 0x600003ee}, {"hi": 0x00000001, "lo": 0x600006aa}],
+ [ "X", 1007, 1807, 1, 23, 1, {"hi": 0xb80001f7, "lo": 0x8000387a}, "b80001f78000387a", {"hi": 0x00000001, "lo": 0x700003ef}, {"hi": 0x00000001, "lo": 0x7000070f}],
+ [ "Y", 1008, 1908, -1, 24, 2, {"hi": 0xc00001f8, "lo": 0x00003ba4}, "c00001f800003ba4", {"hi": 0x00000001, "lo": 0x800003f0}, {"hi": 0x00000001, "lo": 0x80000774}],
+ ["MT", 1009, 2009, 0, 25, 0, {"hi": 0xc80001f8, "lo": 0x80003ec8}, "c80001f880003ec8", {"hi": 0x00000001, "lo": 0x900003f1}, {"hi": 0x00000001, "lo": 0x900007d9}],
+];
+
+var k_test_overlap_size = 12;
+// 0 1 2 3 4 5 6 7 8 9
+// a_chrom, a_startpos, a_endpos, a_rk, a_vk, b_chrom, b_startpos, b_endpos, b_rk, res;
+test_overlap = [
+ [ 1, 5, 7, {"hi": 0x08000002, "lo": 0x80000038}, {"hi": 0x08000002, "lo": 0x90920000}, 2, 5, 7, {"hi": 0x10000002, "lo": 0x80000038}, false], // different chromosome
+ [ 1, 0, 2, {"hi": 0x08000000, "lo": 0x00000010}, {"hi": 0x08000000, "lo": 0x10920000}, 1, 3, 7, {"hi": 0x08000001, "lo": 0x80000038}, false], // -[-]|---|----
+ [ 2, 1, 3, {"hi": 0x10000000, "lo": 0x80000018}, {"hi": 0x10000000, "lo": 0x90920000}, 2, 3, 7, {"hi": 0x10000001, "lo": 0x80000038}, false], // --[-]---|----
+ [ 3, 2, 4, {"hi": 0x18000001, "lo": 0x00000020}, {"hi": 0x18000001, "lo": 0x10920000}, 3, 3, 7, {"hi": 0x18000001, "lo": 0x80000038}, true], // ---[|]--|----
+ [ 4, 3, 5, {"hi": 0x20000001, "lo": 0x80000028}, {"hi": 0x20000001, "lo": 0x90920000}, 4, 3, 7, {"hi": 0x20000001, "lo": 0x80000038}, true], // ----[-]-|----
+ [ 5, 4, 6, {"hi": 0x28000002, "lo": 0x00000030}, {"hi": 0x28000002, "lo": 0x10920000}, 5, 3, 7, {"hi": 0x28000001, "lo": 0x80000038}, true], // ----|[-]|----
+ [ 6, 5, 7, {"hi": 0x30000002, "lo": 0x80000038}, {"hi": 0x30000002, "lo": 0x90920000}, 6, 3, 7, {"hi": 0x30000001, "lo": 0x80000038}, true], // ----|-[ ]----
+ [10, 6, 8, {"hi": 0x50000003, "lo": 0x00000040}, {"hi": 0x50000003, "lo": 0x10920000}, 10, 3, 7, {"hi": 0x50000001, "lo": 0x80000038}, true], // ----|--[|]---
+ [22, 7, 9, {"hi": 0xb0000003, "lo": 0x80000048}, {"hi": 0xb0000003, "lo": 0x90920000}, 22, 3, 7, {"hi": 0xb0000001, "lo": 0x80000038}, false], // ----|---[-]--
+ [23, 8, 10, {"hi": 0xb8000004, "lo": 0x00000050}, {"hi": 0xb8000004, "lo": 0x10920000}, 23, 3, 7, {"hi": 0xb8000001, "lo": 0x80000038}, false], // ----|---|[-]-
+ [24, 2, 8, {"hi": 0xc0000001, "lo": 0x00000040}, {"hi": 0xc0000001, "lo": 0x30911200}, 24, 3, 7, {"hi": 0xc0000001, "lo": 0x80000038}, true], // ---[|---|]---
+ [25, 3, 7, {"hi": 0xc8000001, "lo": 0x80000038}, {"hi": 0xc8000001, "lo": 0xa0912000}, 25, 3, 7, {"hi": 0xc8000001, "lo": 0x80000038}, true], // ----[---]----
+];
+
+function test_encodeRegionStrand() {
+ var errors = 0;
+ var i;
+ var rk;
+ for (i = 0; i < k_test_size; i++) {
+ estrand = encodeRegionStrand(test_data[i][3]);
+ if (estrand != test_data[i][5]) {
+ console.error("(", i, "): Unexpected encoded strand: expected ", test_data[i][5], ", got ", estrand);
+ ++errors;
+ }
+ }
+ return errors;
+}
+
+function test_decodeRegionStrand() {
+ var errors = 0;
+ var i;
+ var strand;
+ for (i = 0; i < k_test_size; i++) {
+ strand = decodeRegionStrand(test_data[i][5]);
+ if (strand != test_data[i][3]) {
+ console.error("(", i, "): Unexpected strand: expected ", test_data[i][3], ", got ", strand);
+ ++errors;
+ }
+ }
+ return errors;
+}
+
+function test_encodeRegionKey() {
+ var errors = 0;
+ var i;
+ var rk;
+ for (i = 0; i < k_test_size; i++) {
+ rk = encodeRegionKey(test_data[i][4], test_data[i][1], test_data[i][2], test_data[i][5]);
+ if ((rk.hi != test_data[i][6].hi) || (rk.lo != test_data[i][6].lo)) {
+ console.error("(", i, "): Unexpected regionkey: expected ", test_data[i][6], ", got ", rk);
+ ++errors;
+ }
+ }
+ return errors;
+}
+
+function test_extractRegionKeyChrom() {
+ var errors = 0;
+ var i;
+ var h;
+ for (i = 0; i < k_test_size; i++) {
+ h = extractRegionKeyChrom(test_data[i][6]);
+ if (h != test_data[i][4]) {
+ console.error("(", i, "): Unexpected chrom code: expected ", test_data[i][4], ", got ", h);
+ ++errors;
+ }
+ }
+ return errors;
+}
+
+function test_extractRegionKeyStartPos() {
+ var errors = 0;
+ var i;
+ var h;
+ for (i = 0; i < k_test_size; i++) {
+ h = extractRegionKeyStartPos(test_data[i][6]);
+ if (h != test_data[i][1]) {
+ console.error("(", i, "): Unexpected START POS: expected ", test_data[i][1], ", got ", h);
+ ++errors;
+ }
+ }
+ return errors;
+}
+
+function test_extractRegionKeyEndPos() {
+ var errors = 0;
+ var i;
+ var h;
+ for (i = 0; i < k_test_size; i++) {
+ h = extractRegionKeyEndPos(test_data[i][6]);
+ if (h != test_data[i][2]) {
+ console.error("(", i, "): Unexpected END POS: expected ", test_data[i][2], ", got ", h);
+ ++errors;
+ }
+ }
+ return errors;
+}
+
+function test_extractRegionKeyStrand() {
+ var errors = 0;
+ var i;
+ var h;
+ for (i = 0; i < k_test_size; i++) {
+ h = extractRegionKeyStrand(test_data[i][6]);
+ if (h != test_data[i][5]) {
+ console.error("(", i, "): Unexpected STRAND code: expected ", test_data[i][5], ", got ", h);
+ ++errors;
+ }
+ }
+ return errors;
+}
+
+
+function test_decodeRegionKey() {
+ var errors = 0;
+ var i;
+ var h;
+ for (i = 0; i < k_test_size; i++) {
+ h = decodeRegionKey(test_data[i][6]);
+ if (h.chrom != test_data[i][4]) {
+ console.error("(", i, "): Unexpected CHROM code: expected ", test_data[i][4], ", got ", h.chrom);
+ ++errors;
+ }
+ if (h.startpos != test_data[i][1]) {
+ console.error("(", i, "): Unexpected START POS: expected ", test_data[i][1], ", got ", h.startpos);
+ ++errors;
+ }
+ if (h.endpos != test_data[i][2]) {
+ console.error("(", i, "): Unexpected END POS: expected ", test_data[i][2], ", got ", h.endpos);
+ ++errors;
+ }
+ if (h.strand != test_data[i][5]) {
+ console.error("(", i, "): Unexpected STRAND code: expected ", test_data[i][5], ", got ", h.strand);
+ ++errors;
+ }
+ }
+ return errors;
+}
+
+function test_reverseRegionKey() {
+ var errors = 0;
+ var i;
+ var h;
+ for (i = 0; i < k_test_size; i++) {
+ h = reverseRegionKey(test_data[i][6]);
+ if (h.chrom != test_data[i][0]) {
+ console.error("(", i, "): Unexpected CHROM: expected ", test_data[i][0], ", got ", h.chrom);
+ ++errors;
+ }
+ if (h.startpos != test_data[i][1]) {
+ console.error("(", i, "): Unexpected START POS: expected ", test_data[i][1], ", got ", h.startpos);
+ ++errors;
+ }
+ if (h.endpos != test_data[i][2]) {
+ console.error("(", i, "): Unexpected END POS: expected ", test_data[i][2], ", got ", h.endpos);
+ ++errors;
+ }
+ if (h.strand != test_data[i][3]) {
+ console.error("(", i, "): Unexpected STRAND: expected ", test_data[i][3], ", got ", h.strand);
+ ++errors;
+ }
+ }
+ return errors;
+}
+
+function test_regionKey() {
+ var errors = 0;
+ var i;
+ var rk;
+ for (i = 0; i < k_test_size; i++) {
+ rk = regionKey(test_data[i][0], test_data[i][1], test_data[i][2], test_data[i][3]);
+ if ((rk.hi != test_data[i][6].hi) || (rk.lo != test_data[i][6].lo)) {
+ console.error("(", i, "): Unexpected regionkey: expected ", test_data[i][6], ", got ", rk);
+ ++errors;
+ }
+ }
+ return errors;
+}
+
+function test_regionKeyString() {
+ var errors = 0;
+ var rs = "";
+ var i;
+ for (i = 0; i < k_test_size; i++) {
+ rs = regionKeyString(test_data[i][6]);
+ if (rs !== test_data[i][7]) {
+ console.error("(", i, "): Unexpected regionkey: expected ", test_data[i][7], ", got ", rs);
+ ++errors;
+ }
+ }
+ return errors;
+}
+
+function test_getVariantKeyEndPos() {
+ var errors = 0;
+ var h;
+ var i;
+ for (i = 0; i < k_test_overlap_size; i++) {
+ h = getVariantKeyEndPos(test_overlap[i][4]);
+ if (h !== test_overlap[i][2]) {
+ console.error("(", i, "): Expected ", test_overlap[i][2], ", got ", h);
+ ++errors;
+ }
+ }
+ return errors;
+}
+
+function test_areOverlappingRegions() {
+ var errors = 0;
+ var h;
+ var i;
+ for (i = 0; i < k_test_overlap_size; i++) {
+ h = areOverlappingRegions(test_overlap[i][0], test_overlap[i][1], test_overlap[i][2], test_overlap[i][5], test_overlap[i][6], test_overlap[i][7]);
+ if (h !== test_overlap[i][9]) {
+ console.error("(", i, "): Expected ", test_overlap[i][9], ", got ", h);
+ ++errors;
+ }
+ }
+ return errors;
+}
+
+function test_areOverlappingRegionRegionKey() {
+ var errors = 0;
+ var h;
+ var i;
+ for (i = 0; i < k_test_overlap_size; i++) {
+ h = areOverlappingRegionRegionKey(test_overlap[i][0], test_overlap[i][1], test_overlap[i][2], test_overlap[i][8]);
+ if (h !== test_overlap[i][9]) {
+ console.error("(", i, "): Expected ", test_overlap[i][9], ", got ", h);
+ ++errors;
+ }
+ }
+ return errors;
+}
+
+function test_areOverlappingRegionKeys() {
+ var errors = 0;
+ var h;
+ var i;
+ for (i = 0; i < k_test_overlap_size; i++) {
+ h = areOverlappingRegionKeys(test_overlap[i][3], test_overlap[i][8]);
+ if (h !== test_overlap[i][9]) {
+ console.error("(", i, "): Expected ", test_overlap[i][9], ", got ", h);
+ ++errors;
+ }
+ }
+ return errors;
+}
+
+function test_areOverlappingVariantKeyRegionKey() {
+ var errors = 0;
+ var h;
+ var i;
+ for (i = 0; i < k_test_overlap_size; i++) {
+ h = areOverlappingVariantKeyRegionKey(test_overlap[i][4], test_overlap[i][8]);
+ if (h !== test_overlap[i][9]) {
+ console.error("(", i, "): Expected ", test_overlap[i][9], ", got ", h);
+ ++errors;
+ }
+ }
+ return errors;
+}
+
+function test_variantKeyToRegionKey() {
+ var errors = 0;
+ var rk;
+ var i;
+ for (i = 0; i < k_test_overlap_size; i++) {
+ rk = variantKeyToRegionKey(test_overlap[i][4]);
+ if ((rk.hi != test_overlap[i][3].hi) || (rk.lo != test_overlap[i][3].lo)) {
+ console.error("(", i, "): Unexpected regionkey: expected ", test_overlap[i][3], ", got ", rk);
+ ++errors;
+ }
+ }
+ return errors;
+}
+
+var errors = 0;
+
+errors += test_encodeRegionStrand();
+errors += test_decodeRegionStrand();
+errors += test_encodeRegionKey();
+errors += test_extractRegionKeyChrom();
+errors += test_extractRegionKeyStartPos();
+errors += test_extractRegionKeyEndPos();
+errors += test_extractRegionKeyStrand();
+errors += test_decodeRegionKey();
+errors += test_reverseRegionKey();
+errors += test_regionKey();
+errors += test_regionKeyString();
+errors += test_getVariantKeyEndPos();
+errors += test_areOverlappingRegions();
+errors += test_areOverlappingRegionRegionKey();
+errors += test_areOverlappingRegionKeys();
+errors += test_areOverlappingVariantKeyRegionKey();
+errors += test_variantKeyToRegionKey();
+
+if (errors > 0) {
+ console.log("FAILED: " + errors);
+ process.exit(1);
+} else {
+ console.log("OK");
+}
diff --git a/javascript/test/test_variantkey.js b/javascript/test/test_variantkey.js
index 3cd8644..cb2b1dd 100644
--- a/javascript/test/test_variantkey.js
+++ b/javascript/test/test_variantkey.js
@@ -32,10 +32,10 @@
// THE SOFTWARE.
const {
- parseHex,
- azToUpper,
encodeChrom,
decodeChrom,
+ parseHex,
+ azToUpper,
encodeRefAlt,
decodeRefAlt,
encodeVariantKey,
@@ -48,7 +48,7 @@ const {
compareVariantKeyChrom,
compareVariantKeyChromPos,
variantKeyString,
- reverseVariantKey
+ reverseVariantKey,
} = require(process.argv[2]);
var k_test_size = 566;
@@ -2510,7 +2510,7 @@ function test_extractVariantKeyChrom() {
for (i = 0; i < k_test_size; i++) {
h = extractVariantKeyChrom(test_data[i][4]);
if (h != test_data[i][6]) {
- console.error("(", i, "): Unexpected chrom code: expected ", test_data[i][6], ", got ", h.chrom);
+ console.error("(", i, "): Unexpected chrom code: expected ", test_data[i][6], ", got ", h);
++errors;
}
}
@@ -2524,7 +2524,7 @@ function test_extractVariantKeyPos() {
for (i = 0; i < k_test_size; i++) {
h = extractVariantKeyPos(test_data[i][4]);
if (h != test_data[i][7]) {
- console.error("(", i, "): Unexpected pos code: expected ", test_data[i][7], ", got ", h.pos);
+ console.error("(", i, "): Unexpected pos code: expected ", test_data[i][7], ", got ", h);
++errors;
}
}
@@ -2538,7 +2538,7 @@ function test_extractVariantKeyRefAlt() {
for (i = 0; i < k_test_size; i++) {
h = extractVariantKeyRefAlt(test_data[i][4]);
if (h != test_data[i][8]) {
- console.error("(", i, "): Unexpected ref+alt code: expected ", test_data[i][8], ", got ", h.refalt);
+ console.error("(", i, "): Unexpected ref+alt code: expected ", test_data[i][8], ", got ", h);
++errors;
}
}
@@ -2567,6 +2567,34 @@ function test_decodeVariantKey() {
return errors;
}
+function test_reverseVariantKey() {
+ var errors = 0;
+ var i;
+ var h;
+ for (i = 0; i < k_test_size; i++) {
+ h = reverseVariantKey(test_data[i][4]);
+ if (h.alt.length > 0) {
+ if (encodeChrom(h.chrom) != encodeChrom(test_data[i][0])) {
+ console.error("(", i, "): Unexpected chrom code: expected ", test_data[i][0], ", got ", h.chrom);
+ ++errors;
+ }
+ if (h.pos != test_data[i][1]) {
+ console.error("(", i, "): Unexpected pos code: expected ", test_data[i][1], ", got ", h.pos);
+ ++errors;
+ }
+ if (h.ref != test_data[i][2].toUpperCase()) {
+ console.error("(", i, "): Unexpected ref code: expected ", test_data[i][2].toUpperCase(), ", got ", h.ref);
+ ++errors;
+ }
+ if (h.alt != test_data[i][3].toUpperCase()) {
+ console.error("(", i, "): Unexpected alt code: expected ", test_data[i][3].toUpperCase(), ", got ", h.alt);
+ ++errors;
+ }
+ }
+ }
+ return errors;
+}
+
function test_variantKey() {
var errors = 0;
var i;
@@ -2901,38 +2929,6 @@ function test_parseHex() {
return errors;
}
-function test_reverseVariantKey() {
- var errors = 0;
- var i;
- var h;
- for (i = 0; i < k_test_size; i++) {
- h = reverseVariantKey({
- "chrom": test_data[i][6],
- "pos": test_data[i][7],
- "refalt": test_data[i][8]
- });
- if (h.alt.length > 0) {
- if (encodeChrom(h.chrom) != encodeChrom(test_data[i][0])) {
- console.error("(", i, "): Unexpected chrom code: expected ", test_data[i][0], ", got ", h.chrom);
- ++errors;
- }
- if (h.pos != test_data[i][1]) {
- console.error("(", i, "): Unexpected pos code: expected ", test_data[i][1], ", got ", h.pos);
- ++errors;
- }
- if (h.ref != test_data[i][2].toUpperCase()) {
- console.error("(", i, "): Unexpected ref code: expected ", test_data[i][2].toUpperCase(), ", got ", h.ref);
- ++errors;
- }
- if (h.alt != test_data[i][3].toUpperCase()) {
- console.error("(", i, "): Unexpected alt code: expected ", test_data[i][3].toUpperCase(), ", got ", h.alt);
- ++errors;
- }
- }
- }
- return errors;
-}
-
var errors = 0;
errors += test_azToUpper();
@@ -2944,13 +2940,13 @@ errors += test_extractVariantKeyChrom();
errors += test_extractVariantKeyPos();
errors += test_extractVariantKeyRefAlt();
errors += test_decodeVariantKey();
+errors += test_reverseVariantKey();
errors += test_variantKey();
errors += test_variantKeyRange();
errors += test_compareVariantKeyChrom();
errors += test_compareVariantKeyChromPos();
errors += test_variantKeyString();
errors += test_parseHex();
-errors += test_reverseVariantKey();
if (errors > 0) {
console.log("FAILED: " + errors);
diff --git a/python/setup.py b/python/setup.py
index c38d430..6a2a55a 100644
--- a/python/setup.py
+++ b/python/setup.py
@@ -30,7 +30,7 @@ def run(self):
setup(
name='variantkey',
- version='2.14.0',
+ version='2.15.0',
keywords=('variantkey variant key genetic genomics'),
description="VariantKey Bindings for Python",
long_description=read('../README.md'),
diff --git a/r/variantkey/DESCRIPTION b/r/variantkey/DESCRIPTION
index 037a03a..eb66f00 100644
--- a/r/variantkey/DESCRIPTION
+++ b/r/variantkey/DESCRIPTION
@@ -1,6 +1,6 @@
Package: variantkey
Title: Genetic VariantKey
-Version: 2.14.0.1
+Version: 2.15.0.1
Authors@R: person("Nicola", "Asuni", email = "info@genomicsplc.com", role = c("aut", "cre"))
Description: Tools to generate and process a 64 bit Unsigned Integer Keys for Human Genetic Variants.
The VariantKey is sortable for chromosome and position,